diff options
264 files changed, 5728 insertions, 2387 deletions
diff --git a/drivers/bcma/driver_chipcommon_sflash.c b/drivers/bcma/driver_chipcommon_sflash.c index 4d07cce9c5d9..7e11ef4cb7db 100644 --- a/drivers/bcma/driver_chipcommon_sflash.c +++ b/drivers/bcma/driver_chipcommon_sflash.c | |||
@@ -38,7 +38,7 @@ static const struct bcma_sflash_tbl_e bcma_sflash_st_tbl[] = { | |||
38 | { "M25P32", 0x15, 0x10000, 64, }, | 38 | { "M25P32", 0x15, 0x10000, 64, }, |
39 | { "M25P64", 0x16, 0x10000, 128, }, | 39 | { "M25P64", 0x16, 0x10000, 128, }, |
40 | { "M25FL128", 0x17, 0x10000, 256, }, | 40 | { "M25FL128", 0x17, 0x10000, 256, }, |
41 | { 0 }, | 41 | { NULL }, |
42 | }; | 42 | }; |
43 | 43 | ||
44 | static const struct bcma_sflash_tbl_e bcma_sflash_sst_tbl[] = { | 44 | static const struct bcma_sflash_tbl_e bcma_sflash_sst_tbl[] = { |
@@ -56,7 +56,7 @@ static const struct bcma_sflash_tbl_e bcma_sflash_sst_tbl[] = { | |||
56 | { "SST25VF016", 0x41, 0x1000, 512, }, | 56 | { "SST25VF016", 0x41, 0x1000, 512, }, |
57 | { "SST25VF032", 0x4a, 0x1000, 1024, }, | 57 | { "SST25VF032", 0x4a, 0x1000, 1024, }, |
58 | { "SST25VF064", 0x4b, 0x1000, 2048, }, | 58 | { "SST25VF064", 0x4b, 0x1000, 2048, }, |
59 | { 0 }, | 59 | { NULL }, |
60 | }; | 60 | }; |
61 | 61 | ||
62 | static const struct bcma_sflash_tbl_e bcma_sflash_at_tbl[] = { | 62 | static const struct bcma_sflash_tbl_e bcma_sflash_at_tbl[] = { |
@@ -67,7 +67,7 @@ static const struct bcma_sflash_tbl_e bcma_sflash_at_tbl[] = { | |||
67 | { "AT45DB161", 0x2c, 512, 4096, }, | 67 | { "AT45DB161", 0x2c, 512, 4096, }, |
68 | { "AT45DB321", 0x34, 512, 8192, }, | 68 | { "AT45DB321", 0x34, 512, 8192, }, |
69 | { "AT45DB642", 0x3c, 1024, 8192, }, | 69 | { "AT45DB642", 0x3c, 1024, 8192, }, |
70 | { 0 }, | 70 | { NULL }, |
71 | }; | 71 | }; |
72 | 72 | ||
73 | static void bcma_sflash_cmd(struct bcma_drv_cc *cc, u32 opcode) | 73 | static void bcma_sflash_cmd(struct bcma_drv_cc *cc, u32 opcode) |
diff --git a/drivers/bluetooth/btsdio.c b/drivers/bluetooth/btsdio.c index b61440aaee65..83f6437dd91d 100644 --- a/drivers/bluetooth/btsdio.c +++ b/drivers/bluetooth/btsdio.c | |||
@@ -73,6 +73,7 @@ struct btsdio_data { | |||
73 | #define REG_CL_INTRD 0x13 /* Interrupt Clear */ | 73 | #define REG_CL_INTRD 0x13 /* Interrupt Clear */ |
74 | #define REG_EN_INTRD 0x14 /* Interrupt Enable */ | 74 | #define REG_EN_INTRD 0x14 /* Interrupt Enable */ |
75 | #define REG_MD_STAT 0x20 /* Bluetooth Mode Status */ | 75 | #define REG_MD_STAT 0x20 /* Bluetooth Mode Status */ |
76 | #define REG_MD_SET 0x20 /* Bluetooth Mode Set */ | ||
76 | 77 | ||
77 | static int btsdio_tx_packet(struct btsdio_data *data, struct sk_buff *skb) | 78 | static int btsdio_tx_packet(struct btsdio_data *data, struct sk_buff *skb) |
78 | { | 79 | { |
@@ -212,7 +213,7 @@ static int btsdio_open(struct hci_dev *hdev) | |||
212 | } | 213 | } |
213 | 214 | ||
214 | if (data->func->class == SDIO_CLASS_BT_B) | 215 | if (data->func->class == SDIO_CLASS_BT_B) |
215 | sdio_writeb(data->func, 0x00, REG_MD_STAT, NULL); | 216 | sdio_writeb(data->func, 0x00, REG_MD_SET, NULL); |
216 | 217 | ||
217 | sdio_writeb(data->func, 0x01, REG_EN_INTRD, NULL); | 218 | sdio_writeb(data->func, 0x01, REG_EN_INTRD, NULL); |
218 | 219 | ||
@@ -333,6 +334,9 @@ static int btsdio_probe(struct sdio_func *func, | |||
333 | hdev->flush = btsdio_flush; | 334 | hdev->flush = btsdio_flush; |
334 | hdev->send = btsdio_send_frame; | 335 | hdev->send = btsdio_send_frame; |
335 | 336 | ||
337 | if (func->vendor == 0x0104 && func->device == 0x00c5) | ||
338 | set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks); | ||
339 | |||
336 | err = hci_register_dev(hdev); | 340 | err = hci_register_dev(hdev); |
337 | if (err < 0) { | 341 | if (err < 0) { |
338 | hci_free_dev(hdev); | 342 | hci_free_dev(hdev); |
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 9f7e539de510..baeaaed299e4 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c | |||
@@ -965,6 +965,45 @@ static int btusb_setup_bcm92035(struct hci_dev *hdev) | |||
965 | return 0; | 965 | return 0; |
966 | } | 966 | } |
967 | 967 | ||
968 | static int btusb_setup_csr(struct hci_dev *hdev) | ||
969 | { | ||
970 | struct hci_rp_read_local_version *rp; | ||
971 | struct sk_buff *skb; | ||
972 | int ret; | ||
973 | |||
974 | BT_DBG("%s", hdev->name); | ||
975 | |||
976 | skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL, | ||
977 | HCI_INIT_TIMEOUT); | ||
978 | if (IS_ERR(skb)) { | ||
979 | BT_ERR("Reading local version failed (%ld)", -PTR_ERR(skb)); | ||
980 | return -PTR_ERR(skb); | ||
981 | } | ||
982 | |||
983 | rp = (struct hci_rp_read_local_version *) skb->data; | ||
984 | |||
985 | if (!rp->status) { | ||
986 | if (le16_to_cpu(rp->manufacturer) != 10) { | ||
987 | /* Clear the reset quirk since this is not an actual | ||
988 | * early Bluetooth 1.1 device from CSR. | ||
989 | */ | ||
990 | clear_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks); | ||
991 | |||
992 | /* These fake CSR controllers have all a broken | ||
993 | * stored link key handling and so just disable it. | ||
994 | */ | ||
995 | set_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, | ||
996 | &hdev->quirks); | ||
997 | } | ||
998 | } | ||
999 | |||
1000 | ret = -bt_to_errno(rp->status); | ||
1001 | |||
1002 | kfree_skb(skb); | ||
1003 | |||
1004 | return ret; | ||
1005 | } | ||
1006 | |||
968 | struct intel_version { | 1007 | struct intel_version { |
969 | u8 status; | 1008 | u8 status; |
970 | u8 hw_platform; | 1009 | u8 hw_platform; |
@@ -1465,10 +1504,15 @@ static int btusb_probe(struct usb_interface *intf, | |||
1465 | 1504 | ||
1466 | if (id->driver_info & BTUSB_CSR) { | 1505 | if (id->driver_info & BTUSB_CSR) { |
1467 | struct usb_device *udev = data->udev; | 1506 | struct usb_device *udev = data->udev; |
1507 | u16 bcdDevice = le16_to_cpu(udev->descriptor.bcdDevice); | ||
1468 | 1508 | ||
1469 | /* Old firmware would otherwise execute USB reset */ | 1509 | /* Old firmware would otherwise execute USB reset */ |
1470 | if (le16_to_cpu(udev->descriptor.bcdDevice) < 0x117) | 1510 | if (bcdDevice < 0x117) |
1471 | set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks); | 1511 | set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks); |
1512 | |||
1513 | /* Fake CSR devices with broken commands */ | ||
1514 | if (bcdDevice <= 0x100) | ||
1515 | hdev->setup = btusb_setup_csr; | ||
1472 | } | 1516 | } |
1473 | 1517 | ||
1474 | if (id->driver_info & BTUSB_SNIFFER) { | 1518 | if (id->driver_info & BTUSB_SNIFFER) { |
diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c index 7b167385a1c4..1ef6990a5c7e 100644 --- a/drivers/bluetooth/hci_vhci.c +++ b/drivers/bluetooth/hci_vhci.c | |||
@@ -141,22 +141,28 @@ static int vhci_create_device(struct vhci_data *data, __u8 dev_type) | |||
141 | } | 141 | } |
142 | 142 | ||
143 | static inline ssize_t vhci_get_user(struct vhci_data *data, | 143 | static inline ssize_t vhci_get_user(struct vhci_data *data, |
144 | const char __user *buf, size_t count) | 144 | const struct iovec *iov, |
145 | unsigned long count) | ||
145 | { | 146 | { |
147 | size_t len = iov_length(iov, count); | ||
146 | struct sk_buff *skb; | 148 | struct sk_buff *skb; |
147 | __u8 pkt_type, dev_type; | 149 | __u8 pkt_type, dev_type; |
150 | unsigned long i; | ||
148 | int ret; | 151 | int ret; |
149 | 152 | ||
150 | if (count < 2 || count > HCI_MAX_FRAME_SIZE) | 153 | if (len < 2 || len > HCI_MAX_FRAME_SIZE) |
151 | return -EINVAL; | 154 | return -EINVAL; |
152 | 155 | ||
153 | skb = bt_skb_alloc(count, GFP_KERNEL); | 156 | skb = bt_skb_alloc(len, GFP_KERNEL); |
154 | if (!skb) | 157 | if (!skb) |
155 | return -ENOMEM; | 158 | return -ENOMEM; |
156 | 159 | ||
157 | if (copy_from_user(skb_put(skb, count), buf, count)) { | 160 | for (i = 0; i < count; i++) { |
158 | kfree_skb(skb); | 161 | if (copy_from_user(skb_put(skb, iov[i].iov_len), |
159 | return -EFAULT; | 162 | iov[i].iov_base, iov[i].iov_len)) { |
163 | kfree_skb(skb); | ||
164 | return -EFAULT; | ||
165 | } | ||
160 | } | 166 | } |
161 | 167 | ||
162 | pkt_type = *((__u8 *) skb->data); | 168 | pkt_type = *((__u8 *) skb->data); |
@@ -205,7 +211,7 @@ static inline ssize_t vhci_get_user(struct vhci_data *data, | |||
205 | return -EINVAL; | 211 | return -EINVAL; |
206 | } | 212 | } |
207 | 213 | ||
208 | return (ret < 0) ? ret : count; | 214 | return (ret < 0) ? ret : len; |
209 | } | 215 | } |
210 | 216 | ||
211 | static inline ssize_t vhci_put_user(struct vhci_data *data, | 217 | static inline ssize_t vhci_put_user(struct vhci_data *data, |
@@ -272,12 +278,13 @@ static ssize_t vhci_read(struct file *file, | |||
272 | return ret; | 278 | return ret; |
273 | } | 279 | } |
274 | 280 | ||
275 | static ssize_t vhci_write(struct file *file, | 281 | static ssize_t vhci_write(struct kiocb *iocb, const struct iovec *iov, |
276 | const char __user *buf, size_t count, loff_t *pos) | 282 | unsigned long count, loff_t pos) |
277 | { | 283 | { |
284 | struct file *file = iocb->ki_filp; | ||
278 | struct vhci_data *data = file->private_data; | 285 | struct vhci_data *data = file->private_data; |
279 | 286 | ||
280 | return vhci_get_user(data, buf, count); | 287 | return vhci_get_user(data, iov, count); |
281 | } | 288 | } |
282 | 289 | ||
283 | static unsigned int vhci_poll(struct file *file, poll_table *wait) | 290 | static unsigned int vhci_poll(struct file *file, poll_table *wait) |
@@ -342,7 +349,7 @@ static int vhci_release(struct inode *inode, struct file *file) | |||
342 | static const struct file_operations vhci_fops = { | 349 | static const struct file_operations vhci_fops = { |
343 | .owner = THIS_MODULE, | 350 | .owner = THIS_MODULE, |
344 | .read = vhci_read, | 351 | .read = vhci_read, |
345 | .write = vhci_write, | 352 | .aio_write = vhci_write, |
346 | .poll = vhci_poll, | 353 | .poll = vhci_poll, |
347 | .open = vhci_open, | 354 | .open = vhci_open, |
348 | .release = vhci_release, | 355 | .release = vhci_release, |
diff --git a/drivers/net/wireless/adm8211.c b/drivers/net/wireless/adm8211.c index 1d40c69cc4a9..55eda7afc041 100644 --- a/drivers/net/wireless/adm8211.c +++ b/drivers/net/wireless/adm8211.c | |||
@@ -15,7 +15,6 @@ | |||
15 | * more details. | 15 | * more details. |
16 | */ | 16 | */ |
17 | 17 | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/interrupt.h> | 18 | #include <linux/interrupt.h> |
20 | #include <linux/if.h> | 19 | #include <linux/if.h> |
21 | #include <linux/skbuff.h> | 20 | #include <linux/skbuff.h> |
diff --git a/drivers/net/wireless/airo_cs.c b/drivers/net/wireless/airo_cs.c index 14128fd265ac..7e9ede6c5798 100644 --- a/drivers/net/wireless/airo_cs.c +++ b/drivers/net/wireless/airo_cs.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #ifdef __IN_PCMCIA_PACKAGE__ | 23 | #ifdef __IN_PCMCIA_PACKAGE__ |
24 | #include <pcmcia/k_compat.h> | 24 | #include <pcmcia/k_compat.h> |
25 | #endif | 25 | #endif |
26 | #include <linux/init.h> | ||
27 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
28 | #include <linux/module.h> | 27 | #include <linux/module.h> |
29 | #include <linux/ptrace.h> | 28 | #include <linux/ptrace.h> |
diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c index 34c8a33cac06..031d4ec64779 100644 --- a/drivers/net/wireless/at76c50x-usb.c +++ b/drivers/net/wireless/at76c50x-usb.c | |||
@@ -1721,7 +1721,7 @@ static void at76_mac80211_tx(struct ieee80211_hw *hw, | |||
1721 | * following workaround is necessary. If the TX frame is an | 1721 | * following workaround is necessary. If the TX frame is an |
1722 | * authentication frame extract the bssid and send the CMD_JOIN. */ | 1722 | * authentication frame extract the bssid and send the CMD_JOIN. */ |
1723 | if (mgmt->frame_control & cpu_to_le16(IEEE80211_STYPE_AUTH)) { | 1723 | if (mgmt->frame_control & cpu_to_le16(IEEE80211_STYPE_AUTH)) { |
1724 | if (!ether_addr_equal(priv->bssid, mgmt->bssid)) { | 1724 | if (!ether_addr_equal_64bits(priv->bssid, mgmt->bssid)) { |
1725 | memcpy(priv->bssid, mgmt->bssid, ETH_ALEN); | 1725 | memcpy(priv->bssid, mgmt->bssid, ETH_ALEN); |
1726 | ieee80211_queue_work(hw, &priv->work_join_bssid); | 1726 | ieee80211_queue_work(hw, &priv->work_join_bssid); |
1727 | dev_kfree_skb_any(skb); | 1727 | dev_kfree_skb_any(skb); |
diff --git a/drivers/net/wireless/ath/ar5523/ar5523.c b/drivers/net/wireless/ath/ar5523/ar5523.c index 280fc3d53a36..8aa20df55e50 100644 --- a/drivers/net/wireless/ath/ar5523/ar5523.c +++ b/drivers/net/wireless/ath/ar5523/ar5523.c | |||
@@ -25,7 +25,6 @@ | |||
25 | * that and only has minimal functionality. | 25 | * that and only has minimal functionality. |
26 | */ | 26 | */ |
27 | #include <linux/compiler.h> | 27 | #include <linux/compiler.h> |
28 | #include <linux/init.h> | ||
29 | #include <linux/kernel.h> | 28 | #include <linux/kernel.h> |
30 | #include <linux/module.h> | 29 | #include <linux/module.h> |
31 | #include <linux/list.h> | 30 | #include <linux/list.h> |
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 69f58b073e85..6396ad4bce67 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c | |||
@@ -1245,7 +1245,7 @@ ath5k_check_ibss_tsf(struct ath5k_hw *ah, struct sk_buff *skb, | |||
1245 | 1245 | ||
1246 | if (ieee80211_is_beacon(mgmt->frame_control) && | 1246 | if (ieee80211_is_beacon(mgmt->frame_control) && |
1247 | le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS && | 1247 | le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS && |
1248 | ether_addr_equal(mgmt->bssid, common->curbssid)) { | 1248 | ether_addr_equal_64bits(mgmt->bssid, common->curbssid)) { |
1249 | /* | 1249 | /* |
1250 | * Received an IBSS beacon with the same BSSID. Hardware *must* | 1250 | * Received an IBSS beacon with the same BSSID. Hardware *must* |
1251 | * have updated the local TSF. We have to work around various | 1251 | * have updated the local TSF. We have to work around various |
@@ -1309,7 +1309,7 @@ ath5k_update_beacon_rssi(struct ath5k_hw *ah, struct sk_buff *skb, int rssi) | |||
1309 | 1309 | ||
1310 | /* only beacons from our BSSID */ | 1310 | /* only beacons from our BSSID */ |
1311 | if (!ieee80211_is_beacon(mgmt->frame_control) || | 1311 | if (!ieee80211_is_beacon(mgmt->frame_control) || |
1312 | !ether_addr_equal(mgmt->bssid, common->curbssid)) | 1312 | !ether_addr_equal_64bits(mgmt->bssid, common->curbssid)) |
1313 | return; | 1313 | return; |
1314 | 1314 | ||
1315 | ewma_add(&ah->ah_beacon_rssi_avg, rssi); | 1315 | ewma_add(&ah->ah_beacon_rssi_avg, rssi); |
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c index 149aba3c7298..d480d2f3e185 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c | |||
@@ -383,6 +383,20 @@ void ar9002_hw_enable_async_fifo(struct ath_hw *ah) | |||
383 | } | 383 | } |
384 | } | 384 | } |
385 | 385 | ||
386 | static void ar9002_hw_init_hang_checks(struct ath_hw *ah) | ||
387 | { | ||
388 | if (AR_SREV_9100(ah) || AR_SREV_9160(ah)) { | ||
389 | ah->config.hw_hang_checks |= HW_BB_RIFS_HANG; | ||
390 | ah->config.hw_hang_checks |= HW_BB_DFS_HANG; | ||
391 | } | ||
392 | |||
393 | if (AR_SREV_9280(ah)) | ||
394 | ah->config.hw_hang_checks |= HW_BB_RX_CLEAR_STUCK_HANG; | ||
395 | |||
396 | if (AR_SREV_5416(ah) || AR_SREV_9100(ah) || AR_SREV_9160(ah)) | ||
397 | ah->config.hw_hang_checks |= HW_MAC_HANG; | ||
398 | } | ||
399 | |||
386 | /* Sets up the AR5008/AR9001/AR9002 hardware familiy callbacks */ | 400 | /* Sets up the AR5008/AR9001/AR9002 hardware familiy callbacks */ |
387 | int ar9002_hw_attach_ops(struct ath_hw *ah) | 401 | int ar9002_hw_attach_ops(struct ath_hw *ah) |
388 | { | 402 | { |
@@ -395,6 +409,7 @@ int ar9002_hw_attach_ops(struct ath_hw *ah) | |||
395 | return ret; | 409 | return ret; |
396 | 410 | ||
397 | priv_ops->init_mode_gain_regs = ar9002_hw_init_mode_gain_regs; | 411 | priv_ops->init_mode_gain_regs = ar9002_hw_init_mode_gain_regs; |
412 | priv_ops->init_hang_checks = ar9002_hw_init_hang_checks; | ||
398 | 413 | ||
399 | ops->config_pci_powersave = ar9002_hw_configpcipowersave; | 414 | ops->config_pci_powersave = ar9002_hw_configpcipowersave; |
400 | 415 | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c index 97e09d5f3a42..8c145cd98c1c 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c | |||
@@ -326,6 +326,224 @@ static void ar9003_hw_init_cal_settings(struct ath_hw *ah) | |||
326 | ah->supp_cals = IQ_MISMATCH_CAL; | 326 | ah->supp_cals = IQ_MISMATCH_CAL; |
327 | } | 327 | } |
328 | 328 | ||
329 | #define OFF_UPPER_LT 24 | ||
330 | #define OFF_LOWER_LT 7 | ||
331 | |||
332 | static bool ar9003_hw_dynamic_osdac_selection(struct ath_hw *ah, | ||
333 | bool txiqcal_done) | ||
334 | { | ||
335 | struct ath_common *common = ath9k_hw_common(ah); | ||
336 | int ch0_done, osdac_ch0, dc_off_ch0_i1, dc_off_ch0_q1, dc_off_ch0_i2, | ||
337 | dc_off_ch0_q2, dc_off_ch0_i3, dc_off_ch0_q3; | ||
338 | int ch1_done, osdac_ch1, dc_off_ch1_i1, dc_off_ch1_q1, dc_off_ch1_i2, | ||
339 | dc_off_ch1_q2, dc_off_ch1_i3, dc_off_ch1_q3; | ||
340 | int ch2_done, osdac_ch2, dc_off_ch2_i1, dc_off_ch2_q1, dc_off_ch2_i2, | ||
341 | dc_off_ch2_q2, dc_off_ch2_i3, dc_off_ch2_q3; | ||
342 | bool status; | ||
343 | u32 temp, val; | ||
344 | |||
345 | /* | ||
346 | * Clear offset and IQ calibration, run AGC cal. | ||
347 | */ | ||
348 | REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, | ||
349 | AR_PHY_AGC_CONTROL_OFFSET_CAL); | ||
350 | REG_CLR_BIT(ah, AR_PHY_TX_IQCAL_CONTROL_0, | ||
351 | AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL); | ||
352 | REG_WRITE(ah, AR_PHY_AGC_CONTROL, | ||
353 | REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_CAL); | ||
354 | |||
355 | status = ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, | ||
356 | AR_PHY_AGC_CONTROL_CAL, | ||
357 | 0, AH_WAIT_TIMEOUT); | ||
358 | if (!status) { | ||
359 | ath_dbg(common, CALIBRATE, | ||
360 | "AGC cal without offset cal failed to complete in 1ms"); | ||
361 | return false; | ||
362 | } | ||
363 | |||
364 | /* | ||
365 | * Allow only offset calibration and disable the others | ||
366 | * (Carrier Leak calibration, TX Filter calibration and | ||
367 | * Peak Detector offset calibration). | ||
368 | */ | ||
369 | REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, | ||
370 | AR_PHY_AGC_CONTROL_OFFSET_CAL); | ||
371 | REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, | ||
372 | AR_PHY_CL_CAL_ENABLE); | ||
373 | REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, | ||
374 | AR_PHY_AGC_CONTROL_FLTR_CAL); | ||
375 | REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, | ||
376 | AR_PHY_AGC_CONTROL_PKDET_CAL); | ||
377 | |||
378 | ch0_done = 0; | ||
379 | ch1_done = 0; | ||
380 | ch2_done = 0; | ||
381 | |||
382 | while ((ch0_done == 0) || (ch1_done == 0) || (ch2_done == 0)) { | ||
383 | osdac_ch0 = (REG_READ(ah, AR_PHY_65NM_CH0_BB1) >> 30) & 0x3; | ||
384 | osdac_ch1 = (REG_READ(ah, AR_PHY_65NM_CH1_BB1) >> 30) & 0x3; | ||
385 | osdac_ch2 = (REG_READ(ah, AR_PHY_65NM_CH2_BB1) >> 30) & 0x3; | ||
386 | |||
387 | REG_SET_BIT(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); | ||
388 | |||
389 | REG_WRITE(ah, AR_PHY_AGC_CONTROL, | ||
390 | REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_CAL); | ||
391 | |||
392 | status = ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, | ||
393 | AR_PHY_AGC_CONTROL_CAL, | ||
394 | 0, AH_WAIT_TIMEOUT); | ||
395 | if (!status) { | ||
396 | ath_dbg(common, CALIBRATE, | ||
397 | "DC offset cal failed to complete in 1ms"); | ||
398 | return false; | ||
399 | } | ||
400 | |||
401 | REG_CLR_BIT(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); | ||
402 | |||
403 | /* | ||
404 | * High gain. | ||
405 | */ | ||
406 | REG_WRITE(ah, AR_PHY_65NM_CH0_BB3, | ||
407 | ((REG_READ(ah, AR_PHY_65NM_CH0_BB3) & 0xfffffcff) | (1 << 8))); | ||
408 | REG_WRITE(ah, AR_PHY_65NM_CH1_BB3, | ||
409 | ((REG_READ(ah, AR_PHY_65NM_CH1_BB3) & 0xfffffcff) | (1 << 8))); | ||
410 | REG_WRITE(ah, AR_PHY_65NM_CH2_BB3, | ||
411 | ((REG_READ(ah, AR_PHY_65NM_CH2_BB3) & 0xfffffcff) | (1 << 8))); | ||
412 | |||
413 | temp = REG_READ(ah, AR_PHY_65NM_CH0_BB3); | ||
414 | dc_off_ch0_i1 = (temp >> 26) & 0x1f; | ||
415 | dc_off_ch0_q1 = (temp >> 21) & 0x1f; | ||
416 | |||
417 | temp = REG_READ(ah, AR_PHY_65NM_CH1_BB3); | ||
418 | dc_off_ch1_i1 = (temp >> 26) & 0x1f; | ||
419 | dc_off_ch1_q1 = (temp >> 21) & 0x1f; | ||
420 | |||
421 | temp = REG_READ(ah, AR_PHY_65NM_CH2_BB3); | ||
422 | dc_off_ch2_i1 = (temp >> 26) & 0x1f; | ||
423 | dc_off_ch2_q1 = (temp >> 21) & 0x1f; | ||
424 | |||
425 | /* | ||
426 | * Low gain. | ||
427 | */ | ||
428 | REG_WRITE(ah, AR_PHY_65NM_CH0_BB3, | ||
429 | ((REG_READ(ah, AR_PHY_65NM_CH0_BB3) & 0xfffffcff) | (2 << 8))); | ||
430 | REG_WRITE(ah, AR_PHY_65NM_CH1_BB3, | ||
431 | ((REG_READ(ah, AR_PHY_65NM_CH1_BB3) & 0xfffffcff) | (2 << 8))); | ||
432 | REG_WRITE(ah, AR_PHY_65NM_CH2_BB3, | ||
433 | ((REG_READ(ah, AR_PHY_65NM_CH2_BB3) & 0xfffffcff) | (2 << 8))); | ||
434 | |||
435 | temp = REG_READ(ah, AR_PHY_65NM_CH0_BB3); | ||
436 | dc_off_ch0_i2 = (temp >> 26) & 0x1f; | ||
437 | dc_off_ch0_q2 = (temp >> 21) & 0x1f; | ||
438 | |||
439 | temp = REG_READ(ah, AR_PHY_65NM_CH1_BB3); | ||
440 | dc_off_ch1_i2 = (temp >> 26) & 0x1f; | ||
441 | dc_off_ch1_q2 = (temp >> 21) & 0x1f; | ||
442 | |||
443 | temp = REG_READ(ah, AR_PHY_65NM_CH2_BB3); | ||
444 | dc_off_ch2_i2 = (temp >> 26) & 0x1f; | ||
445 | dc_off_ch2_q2 = (temp >> 21) & 0x1f; | ||
446 | |||
447 | /* | ||
448 | * Loopback. | ||
449 | */ | ||
450 | REG_WRITE(ah, AR_PHY_65NM_CH0_BB3, | ||
451 | ((REG_READ(ah, AR_PHY_65NM_CH0_BB3) & 0xfffffcff) | (3 << 8))); | ||
452 | REG_WRITE(ah, AR_PHY_65NM_CH1_BB3, | ||
453 | ((REG_READ(ah, AR_PHY_65NM_CH1_BB3) & 0xfffffcff) | (3 << 8))); | ||
454 | REG_WRITE(ah, AR_PHY_65NM_CH2_BB3, | ||
455 | ((REG_READ(ah, AR_PHY_65NM_CH2_BB3) & 0xfffffcff) | (3 << 8))); | ||
456 | |||
457 | temp = REG_READ(ah, AR_PHY_65NM_CH0_BB3); | ||
458 | dc_off_ch0_i3 = (temp >> 26) & 0x1f; | ||
459 | dc_off_ch0_q3 = (temp >> 21) & 0x1f; | ||
460 | |||
461 | temp = REG_READ(ah, AR_PHY_65NM_CH1_BB3); | ||
462 | dc_off_ch1_i3 = (temp >> 26) & 0x1f; | ||
463 | dc_off_ch1_q3 = (temp >> 21) & 0x1f; | ||
464 | |||
465 | temp = REG_READ(ah, AR_PHY_65NM_CH2_BB3); | ||
466 | dc_off_ch2_i3 = (temp >> 26) & 0x1f; | ||
467 | dc_off_ch2_q3 = (temp >> 21) & 0x1f; | ||
468 | |||
469 | if ((dc_off_ch0_i1 > OFF_UPPER_LT) || (dc_off_ch0_i1 < OFF_LOWER_LT) || | ||
470 | (dc_off_ch0_i2 > OFF_UPPER_LT) || (dc_off_ch0_i2 < OFF_LOWER_LT) || | ||
471 | (dc_off_ch0_i3 > OFF_UPPER_LT) || (dc_off_ch0_i3 < OFF_LOWER_LT) || | ||
472 | (dc_off_ch0_q1 > OFF_UPPER_LT) || (dc_off_ch0_q1 < OFF_LOWER_LT) || | ||
473 | (dc_off_ch0_q2 > OFF_UPPER_LT) || (dc_off_ch0_q2 < OFF_LOWER_LT) || | ||
474 | (dc_off_ch0_q3 > OFF_UPPER_LT) || (dc_off_ch0_q3 < OFF_LOWER_LT)) { | ||
475 | if (osdac_ch0 == 3) { | ||
476 | ch0_done = 1; | ||
477 | } else { | ||
478 | osdac_ch0++; | ||
479 | |||
480 | val = REG_READ(ah, AR_PHY_65NM_CH0_BB1) & 0x3fffffff; | ||
481 | val |= (osdac_ch0 << 30); | ||
482 | REG_WRITE(ah, AR_PHY_65NM_CH0_BB1, val); | ||
483 | |||
484 | ch0_done = 0; | ||
485 | } | ||
486 | } else { | ||
487 | ch0_done = 1; | ||
488 | } | ||
489 | |||
490 | if ((dc_off_ch1_i1 > OFF_UPPER_LT) || (dc_off_ch1_i1 < OFF_LOWER_LT) || | ||
491 | (dc_off_ch1_i2 > OFF_UPPER_LT) || (dc_off_ch1_i2 < OFF_LOWER_LT) || | ||
492 | (dc_off_ch1_i3 > OFF_UPPER_LT) || (dc_off_ch1_i3 < OFF_LOWER_LT) || | ||
493 | (dc_off_ch1_q1 > OFF_UPPER_LT) || (dc_off_ch1_q1 < OFF_LOWER_LT) || | ||
494 | (dc_off_ch1_q2 > OFF_UPPER_LT) || (dc_off_ch1_q2 < OFF_LOWER_LT) || | ||
495 | (dc_off_ch1_q3 > OFF_UPPER_LT) || (dc_off_ch1_q3 < OFF_LOWER_LT)) { | ||
496 | if (osdac_ch1 == 3) { | ||
497 | ch1_done = 1; | ||
498 | } else { | ||
499 | osdac_ch1++; | ||
500 | |||
501 | val = REG_READ(ah, AR_PHY_65NM_CH1_BB1) & 0x3fffffff; | ||
502 | val |= (osdac_ch1 << 30); | ||
503 | REG_WRITE(ah, AR_PHY_65NM_CH1_BB1, val); | ||
504 | |||
505 | ch1_done = 0; | ||
506 | } | ||
507 | } else { | ||
508 | ch1_done = 1; | ||
509 | } | ||
510 | |||
511 | if ((dc_off_ch2_i1 > OFF_UPPER_LT) || (dc_off_ch2_i1 < OFF_LOWER_LT) || | ||
512 | (dc_off_ch2_i2 > OFF_UPPER_LT) || (dc_off_ch2_i2 < OFF_LOWER_LT) || | ||
513 | (dc_off_ch2_i3 > OFF_UPPER_LT) || (dc_off_ch2_i3 < OFF_LOWER_LT) || | ||
514 | (dc_off_ch2_q1 > OFF_UPPER_LT) || (dc_off_ch2_q1 < OFF_LOWER_LT) || | ||
515 | (dc_off_ch2_q2 > OFF_UPPER_LT) || (dc_off_ch2_q2 < OFF_LOWER_LT) || | ||
516 | (dc_off_ch2_q3 > OFF_UPPER_LT) || (dc_off_ch2_q3 < OFF_LOWER_LT)) { | ||
517 | if (osdac_ch2 == 3) { | ||
518 | ch2_done = 1; | ||
519 | } else { | ||
520 | osdac_ch2++; | ||
521 | |||
522 | val = REG_READ(ah, AR_PHY_65NM_CH2_BB1) & 0x3fffffff; | ||
523 | val |= (osdac_ch2 << 30); | ||
524 | REG_WRITE(ah, AR_PHY_65NM_CH2_BB1, val); | ||
525 | |||
526 | ch2_done = 0; | ||
527 | } | ||
528 | } else { | ||
529 | ch2_done = 1; | ||
530 | } | ||
531 | } | ||
532 | |||
533 | REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, | ||
534 | AR_PHY_AGC_CONTROL_OFFSET_CAL); | ||
535 | REG_SET_BIT(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); | ||
536 | |||
537 | /* | ||
538 | * We don't need to check txiqcal_done here since it is always | ||
539 | * set for AR9550. | ||
540 | */ | ||
541 | REG_SET_BIT(ah, AR_PHY_TX_IQCAL_CONTROL_0, | ||
542 | AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL); | ||
543 | |||
544 | return true; | ||
545 | } | ||
546 | |||
329 | /* | 547 | /* |
330 | * solve 4x4 linear equation used in loopback iq cal. | 548 | * solve 4x4 linear equation used in loopback iq cal. |
331 | */ | 549 | */ |
@@ -1271,6 +1489,11 @@ static bool ar9003_hw_init_cal_soc(struct ath_hw *ah, | |||
1271 | REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); | 1489 | REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); |
1272 | } | 1490 | } |
1273 | 1491 | ||
1492 | if (AR_SREV_9550(ah) && IS_CHAN_2GHZ(chan)) { | ||
1493 | if (!ar9003_hw_dynamic_osdac_selection(ah, txiqcal_done)) | ||
1494 | return false; | ||
1495 | } | ||
1496 | |||
1274 | skip_tx_iqcal: | 1497 | skip_tx_iqcal: |
1275 | if (run_agc_cal || !(ah->ah_flags & AH_FASTCC)) { | 1498 | if (run_agc_cal || !(ah->ah_flags & AH_FASTCC)) { |
1276 | if (AR_SREV_9330_11(ah)) | 1499 | if (AR_SREV_9330_11(ah)) |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index c8d22eccfef8..25243cbc07f0 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | |||
@@ -3598,7 +3598,7 @@ static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz) | |||
3598 | if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) { | 3598 | if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) { |
3599 | REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM, | 3599 | REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM, |
3600 | AR_SWITCH_TABLE_COM_AR9462_ALL, value); | 3600 | AR_SWITCH_TABLE_COM_AR9462_ALL, value); |
3601 | } else if (AR_SREV_9550(ah)) { | 3601 | } else if (AR_SREV_9550(ah) || AR_SREV_9531(ah)) { |
3602 | REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM, | 3602 | REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM, |
3603 | AR_SWITCH_TABLE_COM_AR9550_ALL, value); | 3603 | AR_SWITCH_TABLE_COM_AR9550_ALL, value); |
3604 | } else | 3604 | } else |
@@ -3975,7 +3975,7 @@ static void ar9003_hw_apply_tuning_caps(struct ath_hw *ah) | |||
3975 | struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; | 3975 | struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; |
3976 | u8 tuning_caps_param = eep->baseEepHeader.params_for_tuning_caps[0]; | 3976 | u8 tuning_caps_param = eep->baseEepHeader.params_for_tuning_caps[0]; |
3977 | 3977 | ||
3978 | if (AR_SREV_9340(ah)) | 3978 | if (AR_SREV_9340(ah) || AR_SREV_9531(ah)) |
3979 | return; | 3979 | return; |
3980 | 3980 | ||
3981 | if (eep->baseEepHeader.featureEnable & 0x40) { | 3981 | if (eep->baseEepHeader.featureEnable & 0x40) { |
@@ -4030,7 +4030,10 @@ static void ar9003_hw_xpa_timing_control_apply(struct ath_hw *ah, bool is2ghz) | |||
4030 | if (!(eep->baseEepHeader.featureEnable & 0x80)) | 4030 | if (!(eep->baseEepHeader.featureEnable & 0x80)) |
4031 | return; | 4031 | return; |
4032 | 4032 | ||
4033 | if (!AR_SREV_9300(ah) && !AR_SREV_9340(ah) && !AR_SREV_9580(ah)) | 4033 | if (!AR_SREV_9300(ah) && |
4034 | !AR_SREV_9340(ah) && | ||
4035 | !AR_SREV_9580(ah) && | ||
4036 | !AR_SREV_9531(ah)) | ||
4034 | return; | 4037 | return; |
4035 | 4038 | ||
4036 | xpa_ctl = ar9003_modal_header(ah, is2ghz)->txFrameToXpaOn; | 4039 | xpa_ctl = ar9003_modal_header(ah, is2ghz)->txFrameToXpaOn; |
@@ -4163,7 +4166,7 @@ static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah, | |||
4163 | ar9003_hw_xlna_bias_strength_apply(ah, is2ghz); | 4166 | ar9003_hw_xlna_bias_strength_apply(ah, is2ghz); |
4164 | ar9003_hw_atten_apply(ah, chan); | 4167 | ar9003_hw_atten_apply(ah, chan); |
4165 | ar9003_hw_quick_drop_apply(ah, chan->channel); | 4168 | ar9003_hw_quick_drop_apply(ah, chan->channel); |
4166 | if (!AR_SREV_9330(ah) && !AR_SREV_9340(ah)) | 4169 | if (!AR_SREV_9330(ah) && !AR_SREV_9340(ah) && !AR_SREV_9531(ah)) |
4167 | ar9003_hw_internal_regulator_apply(ah); | 4170 | ar9003_hw_internal_regulator_apply(ah); |
4168 | ar9003_hw_apply_tuning_caps(ah); | 4171 | ar9003_hw_apply_tuning_caps(ah); |
4169 | ar9003_hw_apply_minccapwr_thresh(ah, chan); | 4172 | ar9003_hw_apply_minccapwr_thresh(ah, chan); |
@@ -4788,7 +4791,7 @@ static void ar9003_hw_power_control_override(struct ath_hw *ah, | |||
4788 | } | 4791 | } |
4789 | 4792 | ||
4790 | tempslope: | 4793 | tempslope: |
4791 | if (AR_SREV_9550(ah)) { | 4794 | if (AR_SREV_9550(ah) || AR_SREV_9531(ah)) { |
4792 | /* | 4795 | /* |
4793 | * AR955x has tempSlope register for each chain. | 4796 | * AR955x has tempSlope register for each chain. |
4794 | * Check whether temp_compensation feature is enabled or not. | 4797 | * Check whether temp_compensation feature is enabled or not. |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c index 29613ebbc5d7..ec1da0cc25f5 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include "ar9462_2p1_initvals.h" | 28 | #include "ar9462_2p1_initvals.h" |
29 | #include "ar9565_1p0_initvals.h" | 29 | #include "ar9565_1p0_initvals.h" |
30 | #include "ar9565_1p1_initvals.h" | 30 | #include "ar9565_1p1_initvals.h" |
31 | #include "ar953x_initvals.h" | ||
31 | 32 | ||
32 | /* General hardware code for the AR9003 hadware family */ | 33 | /* General hardware code for the AR9003 hadware family */ |
33 | 34 | ||
@@ -308,6 +309,31 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) | |||
308 | /* Fast clock modal settings */ | 309 | /* Fast clock modal settings */ |
309 | INIT_INI_ARRAY(&ah->iniModesFastClock, | 310 | INIT_INI_ARRAY(&ah->iniModesFastClock, |
310 | ar955x_1p0_modes_fast_clock); | 311 | ar955x_1p0_modes_fast_clock); |
312 | } else if (AR_SREV_9531(ah)) { | ||
313 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], | ||
314 | qca953x_1p0_mac_core); | ||
315 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST], | ||
316 | qca953x_1p0_mac_postamble); | ||
317 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE], | ||
318 | qca953x_1p0_baseband_core); | ||
319 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST], | ||
320 | qca953x_1p0_baseband_postamble); | ||
321 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE], | ||
322 | qca953x_1p0_radio_core); | ||
323 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST], | ||
324 | qca953x_1p0_radio_postamble); | ||
325 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE], | ||
326 | qca953x_1p0_soc_preamble); | ||
327 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], | ||
328 | qca953x_1p0_soc_postamble); | ||
329 | INIT_INI_ARRAY(&ah->iniModesRxGain, | ||
330 | qca953x_1p0_common_wo_xlna_rx_gain_table); | ||
331 | INIT_INI_ARRAY(&ah->ini_modes_rx_gain_bounds, | ||
332 | qca953x_1p0_common_wo_xlna_rx_gain_bounds); | ||
333 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
334 | qca953x_1p0_modes_no_xpa_tx_gain_table); | ||
335 | INIT_INI_ARRAY(&ah->iniModesFastClock, | ||
336 | qca953x_1p0_modes_fast_clock); | ||
311 | } else if (AR_SREV_9580(ah)) { | 337 | } else if (AR_SREV_9580(ah)) { |
312 | /* mac */ | 338 | /* mac */ |
313 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], | 339 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], |
@@ -485,6 +511,9 @@ static void ar9003_tx_gain_table_mode0(struct ath_hw *ah) | |||
485 | else if (AR_SREV_9550(ah)) | 511 | else if (AR_SREV_9550(ah)) |
486 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 512 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
487 | ar955x_1p0_modes_xpa_tx_gain_table); | 513 | ar955x_1p0_modes_xpa_tx_gain_table); |
514 | else if (AR_SREV_9531(ah)) | ||
515 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
516 | qca953x_1p0_modes_xpa_tx_gain_table); | ||
488 | else if (AR_SREV_9580(ah)) | 517 | else if (AR_SREV_9580(ah)) |
489 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 518 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
490 | ar9580_1p0_lowest_ob_db_tx_gain_table); | 519 | ar9580_1p0_lowest_ob_db_tx_gain_table); |
@@ -525,7 +554,14 @@ static void ar9003_tx_gain_table_mode1(struct ath_hw *ah) | |||
525 | else if (AR_SREV_9550(ah)) | 554 | else if (AR_SREV_9550(ah)) |
526 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 555 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
527 | ar955x_1p0_modes_no_xpa_tx_gain_table); | 556 | ar955x_1p0_modes_no_xpa_tx_gain_table); |
528 | else if (AR_SREV_9462_21(ah)) | 557 | else if (AR_SREV_9531(ah)) { |
558 | if (AR_SREV_9531_11(ah)) | ||
559 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
560 | qca953x_1p1_modes_no_xpa_tx_gain_table); | ||
561 | else | ||
562 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
563 | qca953x_1p0_modes_no_xpa_tx_gain_table); | ||
564 | } else if (AR_SREV_9462_21(ah)) | ||
529 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 565 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
530 | ar9462_2p1_modes_high_ob_db_tx_gain); | 566 | ar9462_2p1_modes_high_ob_db_tx_gain); |
531 | else if (AR_SREV_9462_20(ah)) | 567 | else if (AR_SREV_9462_20(ah)) |
@@ -699,6 +735,11 @@ static void ar9003_rx_gain_table_mode0(struct ath_hw *ah) | |||
699 | ar955x_1p0_common_rx_gain_table); | 735 | ar955x_1p0_common_rx_gain_table); |
700 | INIT_INI_ARRAY(&ah->ini_modes_rx_gain_bounds, | 736 | INIT_INI_ARRAY(&ah->ini_modes_rx_gain_bounds, |
701 | ar955x_1p0_common_rx_gain_bounds); | 737 | ar955x_1p0_common_rx_gain_bounds); |
738 | } else if (AR_SREV_9531(ah)) { | ||
739 | INIT_INI_ARRAY(&ah->iniModesRxGain, | ||
740 | qca953x_1p0_common_rx_gain_table); | ||
741 | INIT_INI_ARRAY(&ah->ini_modes_rx_gain_bounds, | ||
742 | qca953x_1p0_common_rx_gain_bounds); | ||
702 | } else if (AR_SREV_9580(ah)) | 743 | } else if (AR_SREV_9580(ah)) |
703 | INIT_INI_ARRAY(&ah->iniModesRxGain, | 744 | INIT_INI_ARRAY(&ah->iniModesRxGain, |
704 | ar9580_1p0_rx_gain_table); | 745 | ar9580_1p0_rx_gain_table); |
@@ -744,6 +785,11 @@ static void ar9003_rx_gain_table_mode1(struct ath_hw *ah) | |||
744 | ar955x_1p0_common_wo_xlna_rx_gain_table); | 785 | ar955x_1p0_common_wo_xlna_rx_gain_table); |
745 | INIT_INI_ARRAY(&ah->ini_modes_rx_gain_bounds, | 786 | INIT_INI_ARRAY(&ah->ini_modes_rx_gain_bounds, |
746 | ar955x_1p0_common_wo_xlna_rx_gain_bounds); | 787 | ar955x_1p0_common_wo_xlna_rx_gain_bounds); |
788 | } else if (AR_SREV_9531(ah)) { | ||
789 | INIT_INI_ARRAY(&ah->iniModesRxGain, | ||
790 | qca953x_1p0_common_wo_xlna_rx_gain_table); | ||
791 | INIT_INI_ARRAY(&ah->ini_modes_rx_gain_bounds, | ||
792 | qca953x_1p0_common_wo_xlna_rx_gain_bounds); | ||
747 | } else if (AR_SREV_9580(ah)) | 793 | } else if (AR_SREV_9580(ah)) |
748 | INIT_INI_ARRAY(&ah->iniModesRxGain, | 794 | INIT_INI_ARRAY(&ah->iniModesRxGain, |
749 | ar9580_1p0_wo_xlna_rx_gain_table); | 795 | ar9580_1p0_wo_xlna_rx_gain_table); |
@@ -872,6 +918,117 @@ static void ar9003_hw_configpcipowersave(struct ath_hw *ah, | |||
872 | } | 918 | } |
873 | } | 919 | } |
874 | 920 | ||
921 | static void ar9003_hw_init_hang_checks(struct ath_hw *ah) | ||
922 | { | ||
923 | /* | ||
924 | * All chips support detection of BB/MAC hangs. | ||
925 | */ | ||
926 | ah->config.hw_hang_checks |= HW_BB_WATCHDOG; | ||
927 | ah->config.hw_hang_checks |= HW_MAC_HANG; | ||
928 | |||
929 | /* | ||
930 | * This is not required for AR9580 1.0 | ||
931 | */ | ||
932 | if (AR_SREV_9300_22(ah)) | ||
933 | ah->config.hw_hang_checks |= HW_PHYRESTART_CLC_WAR; | ||
934 | |||
935 | if (AR_SREV_9330(ah)) | ||
936 | ah->bb_watchdog_timeout_ms = 85; | ||
937 | else | ||
938 | ah->bb_watchdog_timeout_ms = 25; | ||
939 | } | ||
940 | |||
941 | /* | ||
942 | * MAC HW hang check | ||
943 | * ================= | ||
944 | * | ||
945 | * Signature: dcu_chain_state is 0x6 and dcu_complete_state is 0x1. | ||
946 | * | ||
947 | * The state of each DCU chain (mapped to TX queues) is available from these | ||
948 | * DMA debug registers: | ||
949 | * | ||
950 | * Chain 0 state : Bits 4:0 of AR_DMADBG_4 | ||
951 | * Chain 1 state : Bits 9:5 of AR_DMADBG_4 | ||
952 | * Chain 2 state : Bits 14:10 of AR_DMADBG_4 | ||
953 | * Chain 3 state : Bits 19:15 of AR_DMADBG_4 | ||
954 | * Chain 4 state : Bits 24:20 of AR_DMADBG_4 | ||
955 | * Chain 5 state : Bits 29:25 of AR_DMADBG_4 | ||
956 | * Chain 6 state : Bits 4:0 of AR_DMADBG_5 | ||
957 | * Chain 7 state : Bits 9:5 of AR_DMADBG_5 | ||
958 | * Chain 8 state : Bits 14:10 of AR_DMADBG_5 | ||
959 | * Chain 9 state : Bits 19:15 of AR_DMADBG_5 | ||
960 | * | ||
961 | * The DCU chain state "0x6" means "WAIT_FRDONE" - wait for TX frame to be done. | ||
962 | */ | ||
963 | |||
964 | #define NUM_STATUS_READS 50 | ||
965 | |||
966 | static bool ath9k_hw_verify_hang(struct ath_hw *ah, unsigned int queue) | ||
967 | { | ||
968 | u32 dma_dbg_chain, dma_dbg_complete; | ||
969 | u8 dcu_chain_state, dcu_complete_state; | ||
970 | int i; | ||
971 | |||
972 | for (i = 0; i < NUM_STATUS_READS; i++) { | ||
973 | if (queue < 6) | ||
974 | dma_dbg_chain = REG_READ(ah, AR_DMADBG_4); | ||
975 | else | ||
976 | dma_dbg_chain = REG_READ(ah, AR_DMADBG_5); | ||
977 | |||
978 | dma_dbg_complete = REG_READ(ah, AR_DMADBG_6); | ||
979 | |||
980 | dcu_chain_state = (dma_dbg_chain >> (5 * queue)) & 0x1f; | ||
981 | dcu_complete_state = dma_dbg_complete & 0x3; | ||
982 | |||
983 | if ((dcu_chain_state != 0x6) || (dcu_complete_state != 0x1)) | ||
984 | return false; | ||
985 | } | ||
986 | |||
987 | ath_dbg(ath9k_hw_common(ah), RESET, | ||
988 | "MAC Hang signature found for queue: %d\n", queue); | ||
989 | |||
990 | return true; | ||
991 | } | ||
992 | |||
993 | static bool ar9003_hw_detect_mac_hang(struct ath_hw *ah) | ||
994 | { | ||
995 | u32 dma_dbg_4, dma_dbg_5, dma_dbg_6, chk_dbg; | ||
996 | u8 dcu_chain_state, dcu_complete_state; | ||
997 | bool dcu_wait_frdone = false; | ||
998 | unsigned long chk_dcu = 0; | ||
999 | unsigned int i = 0; | ||
1000 | |||
1001 | dma_dbg_4 = REG_READ(ah, AR_DMADBG_4); | ||
1002 | dma_dbg_5 = REG_READ(ah, AR_DMADBG_5); | ||
1003 | dma_dbg_6 = REG_READ(ah, AR_DMADBG_6); | ||
1004 | |||
1005 | dcu_complete_state = dma_dbg_6 & 0x3; | ||
1006 | if (dcu_complete_state != 0x1) | ||
1007 | goto exit; | ||
1008 | |||
1009 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { | ||
1010 | if (i < 6) | ||
1011 | chk_dbg = dma_dbg_4; | ||
1012 | else | ||
1013 | chk_dbg = dma_dbg_5; | ||
1014 | |||
1015 | dcu_chain_state = (chk_dbg >> (5 * i)) & 0x1f; | ||
1016 | if (dcu_chain_state == 0x6) { | ||
1017 | dcu_wait_frdone = true; | ||
1018 | chk_dcu |= BIT(i); | ||
1019 | } | ||
1020 | } | ||
1021 | |||
1022 | if ((dcu_complete_state == 0x1) && dcu_wait_frdone) { | ||
1023 | for_each_set_bit(i, &chk_dcu, ATH9K_NUM_TX_QUEUES) { | ||
1024 | if (ath9k_hw_verify_hang(ah, i)) | ||
1025 | return true; | ||
1026 | } | ||
1027 | } | ||
1028 | exit: | ||
1029 | return false; | ||
1030 | } | ||
1031 | |||
875 | /* Sets up the AR9003 hardware familiy callbacks */ | 1032 | /* Sets up the AR9003 hardware familiy callbacks */ |
876 | void ar9003_hw_attach_ops(struct ath_hw *ah) | 1033 | void ar9003_hw_attach_ops(struct ath_hw *ah) |
877 | { | 1034 | { |
@@ -880,6 +1037,8 @@ void ar9003_hw_attach_ops(struct ath_hw *ah) | |||
880 | 1037 | ||
881 | ar9003_hw_init_mode_regs(ah); | 1038 | ar9003_hw_init_mode_regs(ah); |
882 | priv_ops->init_mode_gain_regs = ar9003_hw_init_mode_gain_regs; | 1039 | priv_ops->init_mode_gain_regs = ar9003_hw_init_mode_gain_regs; |
1040 | priv_ops->init_hang_checks = ar9003_hw_init_hang_checks; | ||
1041 | priv_ops->detect_mac_hang = ar9003_hw_detect_mac_hang; | ||
883 | 1042 | ||
884 | ops->config_pci_powersave = ar9003_hw_configpcipowersave; | 1043 | ops->config_pci_powersave = ar9003_hw_configpcipowersave; |
885 | 1044 | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index 9f051a08e143..09facba1dc6d 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c | |||
@@ -103,7 +103,7 @@ static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan) | |||
103 | } else { | 103 | } else { |
104 | channelSel = CHANSEL_2G(freq) >> 1; | 104 | channelSel = CHANSEL_2G(freq) >> 1; |
105 | } | 105 | } |
106 | } else if (AR_SREV_9550(ah)) { | 106 | } else if (AR_SREV_9550(ah) || AR_SREV_9531(ah)) { |
107 | if (ah->is_clk_25mhz) | 107 | if (ah->is_clk_25mhz) |
108 | div = 75; | 108 | div = 75; |
109 | else | 109 | else |
@@ -118,7 +118,7 @@ static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan) | |||
118 | /* Set to 2G mode */ | 118 | /* Set to 2G mode */ |
119 | bMode = 1; | 119 | bMode = 1; |
120 | } else { | 120 | } else { |
121 | if ((AR_SREV_9340(ah) || AR_SREV_9550(ah)) && | 121 | if ((AR_SREV_9340(ah) || AR_SREV_9550(ah) || AR_SREV_9531(ah)) && |
122 | ah->is_clk_25mhz) { | 122 | ah->is_clk_25mhz) { |
123 | channelSel = freq / 75; | 123 | channelSel = freq / 75; |
124 | chan_frac = ((freq % 75) * 0x20000) / 75; | 124 | chan_frac = ((freq % 75) * 0x20000) / 75; |
@@ -810,10 +810,12 @@ static int ar9003_hw_process_ini(struct ath_hw *ah, | |||
810 | /* | 810 | /* |
811 | * TXGAIN initvals. | 811 | * TXGAIN initvals. |
812 | */ | 812 | */ |
813 | if (AR_SREV_9550(ah)) { | 813 | if (AR_SREV_9550(ah) || AR_SREV_9531(ah)) { |
814 | int modes_txgain_index; | 814 | int modes_txgain_index = 1; |
815 | |||
816 | if (AR_SREV_9550(ah)) | ||
817 | modes_txgain_index = ar9550_hw_get_modes_txgain_index(ah, chan); | ||
815 | 818 | ||
816 | modes_txgain_index = ar9550_hw_get_modes_txgain_index(ah, chan); | ||
817 | if (modes_txgain_index < 0) | 819 | if (modes_txgain_index < 0) |
818 | return -EINVAL; | 820 | return -EINVAL; |
819 | 821 | ||
@@ -1814,6 +1816,68 @@ void ar9003_hw_attach_phy_ops(struct ath_hw *ah) | |||
1814 | memcpy(ah->nf_regs, ar9300_cca_regs, sizeof(ah->nf_regs)); | 1816 | memcpy(ah->nf_regs, ar9300_cca_regs, sizeof(ah->nf_regs)); |
1815 | } | 1817 | } |
1816 | 1818 | ||
1819 | /* | ||
1820 | * Baseband Watchdog signatures: | ||
1821 | * | ||
1822 | * 0x04000539: BB hang when operating in HT40 DFS Channel. | ||
1823 | * Full chip reset is not required, but a recovery | ||
1824 | * mechanism is needed. | ||
1825 | * | ||
1826 | * 0x1300000a: Related to CAC deafness. | ||
1827 | * Chip reset is not required. | ||
1828 | * | ||
1829 | * 0x0400000a: Related to CAC deafness. | ||
1830 | * Full chip reset is required. | ||
1831 | * | ||
1832 | * 0x04000b09: RX state machine gets into an illegal state | ||
1833 | * when a packet with unsupported rate is received. | ||
1834 | * Full chip reset is required and PHY_RESTART has | ||
1835 | * to be disabled. | ||
1836 | * | ||
1837 | * 0x04000409: Packet stuck on receive. | ||
1838 | * Full chip reset is required for all chips except AR9340. | ||
1839 | */ | ||
1840 | |||
1841 | /* | ||
1842 | * ar9003_hw_bb_watchdog_check(): Returns true if a chip reset is required. | ||
1843 | */ | ||
1844 | bool ar9003_hw_bb_watchdog_check(struct ath_hw *ah) | ||
1845 | { | ||
1846 | u32 val; | ||
1847 | |||
1848 | switch(ah->bb_watchdog_last_status) { | ||
1849 | case 0x04000539: | ||
1850 | val = REG_READ(ah, AR_PHY_RADAR_0); | ||
1851 | val &= (~AR_PHY_RADAR_0_FIRPWR); | ||
1852 | val |= SM(0x7f, AR_PHY_RADAR_0_FIRPWR); | ||
1853 | REG_WRITE(ah, AR_PHY_RADAR_0, val); | ||
1854 | udelay(1); | ||
1855 | val = REG_READ(ah, AR_PHY_RADAR_0); | ||
1856 | val &= ~AR_PHY_RADAR_0_FIRPWR; | ||
1857 | val |= SM(AR9300_DFS_FIRPWR, AR_PHY_RADAR_0_FIRPWR); | ||
1858 | REG_WRITE(ah, AR_PHY_RADAR_0, val); | ||
1859 | |||
1860 | return false; | ||
1861 | case 0x1300000a: | ||
1862 | return false; | ||
1863 | case 0x0400000a: | ||
1864 | case 0x04000b09: | ||
1865 | return true; | ||
1866 | case 0x04000409: | ||
1867 | if (AR_SREV_9340(ah) || AR_SREV_9531(ah)) | ||
1868 | return false; | ||
1869 | else | ||
1870 | return true; | ||
1871 | default: | ||
1872 | /* | ||
1873 | * For any other unknown signatures, do a | ||
1874 | * full chip reset. | ||
1875 | */ | ||
1876 | return true; | ||
1877 | } | ||
1878 | } | ||
1879 | EXPORT_SYMBOL(ar9003_hw_bb_watchdog_check); | ||
1880 | |||
1817 | void ar9003_hw_bb_watchdog_config(struct ath_hw *ah) | 1881 | void ar9003_hw_bb_watchdog_config(struct ath_hw *ah) |
1818 | { | 1882 | { |
1819 | struct ath_common *common = ath9k_hw_common(ah); | 1883 | struct ath_common *common = ath9k_hw_common(ah); |
@@ -1930,6 +1994,7 @@ EXPORT_SYMBOL(ar9003_hw_bb_watchdog_dbg_info); | |||
1930 | 1994 | ||
1931 | void ar9003_hw_disable_phy_restart(struct ath_hw *ah) | 1995 | void ar9003_hw_disable_phy_restart(struct ath_hw *ah) |
1932 | { | 1996 | { |
1997 | u8 result; | ||
1933 | u32 val; | 1998 | u32 val; |
1934 | 1999 | ||
1935 | /* While receiving unsupported rate frame rx state machine | 2000 | /* While receiving unsupported rate frame rx state machine |
@@ -1937,15 +2002,13 @@ void ar9003_hw_disable_phy_restart(struct ath_hw *ah) | |||
1937 | * state, BB would go hang. If RXSM is in 0xb state after | 2002 | * state, BB would go hang. If RXSM is in 0xb state after |
1938 | * first bb panic, ensure to disable the phy_restart. | 2003 | * first bb panic, ensure to disable the phy_restart. |
1939 | */ | 2004 | */ |
1940 | if (!((MS(ah->bb_watchdog_last_status, | 2005 | result = MS(ah->bb_watchdog_last_status, AR_PHY_WATCHDOG_RX_OFDM_SM); |
1941 | AR_PHY_WATCHDOG_RX_OFDM_SM) == 0xb) || | ||
1942 | ah->bb_hang_rx_ofdm)) | ||
1943 | return; | ||
1944 | |||
1945 | ah->bb_hang_rx_ofdm = true; | ||
1946 | val = REG_READ(ah, AR_PHY_RESTART); | ||
1947 | val &= ~AR_PHY_RESTART_ENA; | ||
1948 | 2006 | ||
1949 | REG_WRITE(ah, AR_PHY_RESTART, val); | 2007 | if ((result == 0xb) || ah->bb_hang_rx_ofdm) { |
2008 | ah->bb_hang_rx_ofdm = true; | ||
2009 | val = REG_READ(ah, AR_PHY_RESTART); | ||
2010 | val &= ~AR_PHY_RESTART_ENA; | ||
2011 | REG_WRITE(ah, AR_PHY_RESTART, val); | ||
2012 | } | ||
1950 | } | 2013 | } |
1951 | EXPORT_SYMBOL(ar9003_hw_disable_phy_restart); | 2014 | EXPORT_SYMBOL(ar9003_hw_disable_phy_restart); |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h index 1b441715ba39..fd090b1f2d0f 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h | |||
@@ -338,9 +338,8 @@ | |||
338 | #define AR_PHY_CCA_NOM_VAL_9300_5GHZ -115 | 338 | #define AR_PHY_CCA_NOM_VAL_9300_5GHZ -115 |
339 | #define AR_PHY_CCA_MIN_GOOD_VAL_9300_2GHZ -125 | 339 | #define AR_PHY_CCA_MIN_GOOD_VAL_9300_2GHZ -125 |
340 | #define AR_PHY_CCA_MIN_GOOD_VAL_9300_5GHZ -125 | 340 | #define AR_PHY_CCA_MIN_GOOD_VAL_9300_5GHZ -125 |
341 | #define AR_PHY_CCA_MAX_GOOD_VAL_9300_2GHZ -95 | 341 | #define AR_PHY_CCA_MAX_GOOD_VAL_9300_2GHZ -60 |
342 | #define AR_PHY_CCA_MAX_GOOD_VAL_9300_5GHZ -100 | 342 | #define AR_PHY_CCA_MAX_GOOD_VAL_9300_5GHZ -60 |
343 | |||
344 | #define AR_PHY_CCA_MAX_GOOD_VAL_9300_FCC_2GHZ -95 | 343 | #define AR_PHY_CCA_MAX_GOOD_VAL_9300_FCC_2GHZ -95 |
345 | #define AR_PHY_CCA_MAX_GOOD_VAL_9300_FCC_5GHZ -100 | 344 | #define AR_PHY_CCA_MAX_GOOD_VAL_9300_FCC_5GHZ -100 |
346 | 345 | ||
@@ -670,6 +669,16 @@ | |||
670 | #define AR_PHY_65NM_CH1_RXTX4 0x1650c | 669 | #define AR_PHY_65NM_CH1_RXTX4 0x1650c |
671 | #define AR_PHY_65NM_CH2_RXTX4 0x1690c | 670 | #define AR_PHY_65NM_CH2_RXTX4 0x1690c |
672 | 671 | ||
672 | #define AR_PHY_65NM_CH0_BB1 0x16140 | ||
673 | #define AR_PHY_65NM_CH0_BB2 0x16144 | ||
674 | #define AR_PHY_65NM_CH0_BB3 0x16148 | ||
675 | #define AR_PHY_65NM_CH1_BB1 0x16540 | ||
676 | #define AR_PHY_65NM_CH1_BB2 0x16544 | ||
677 | #define AR_PHY_65NM_CH1_BB3 0x16548 | ||
678 | #define AR_PHY_65NM_CH2_BB1 0x16940 | ||
679 | #define AR_PHY_65NM_CH2_BB2 0x16944 | ||
680 | #define AR_PHY_65NM_CH2_BB3 0x16948 | ||
681 | |||
673 | #define AR_PHY_65NM_CH0_SYNTH12_VREFMUL3 0x00780000 | 682 | #define AR_PHY_65NM_CH0_SYNTH12_VREFMUL3 0x00780000 |
674 | #define AR_PHY_65NM_CH0_SYNTH12_VREFMUL3_S 19 | 683 | #define AR_PHY_65NM_CH0_SYNTH12_VREFMUL3_S 19 |
675 | #define AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK 0x00000004 | 684 | #define AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK 0x00000004 |
@@ -1334,4 +1343,6 @@ | |||
1334 | #define AR_PHY_65NM_RXRF_AGC_AGC_OUT 0x00000004 | 1343 | #define AR_PHY_65NM_RXRF_AGC_AGC_OUT 0x00000004 |
1335 | #define AR_PHY_65NM_RXRF_AGC_AGC_OUT_S 2 | 1344 | #define AR_PHY_65NM_RXRF_AGC_AGC_OUT_S 2 |
1336 | 1345 | ||
1346 | #define AR9300_DFS_FIRPWR -28 | ||
1347 | |||
1337 | #endif /* AR9003_PHY_H */ | 1348 | #endif /* AR9003_PHY_H */ |
diff --git a/drivers/net/wireless/ath/ath9k/ar953x_initvals.h b/drivers/net/wireless/ath/ath9k/ar953x_initvals.h new file mode 100644 index 000000000000..3c9113d9b1bc --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/ar953x_initvals.h | |||
@@ -0,0 +1,718 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2010-2011 Atheros Communications Inc. | ||
3 | * Copyright (c) 2011-2012 Qualcomm Atheros Inc. | ||
4 | * | ||
5 | * Permission to use, copy, modify, and/or distribute this software for any | ||
6 | * purpose with or without fee is hereby granted, provided that the above | ||
7 | * copyright notice and this permission notice appear in all copies. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
12 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
13 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
16 | */ | ||
17 | |||
18 | #ifndef INITVALS_953X_H | ||
19 | #define INITVALS_953X_H | ||
20 | |||
21 | #define qca953x_1p0_mac_postamble ar9300_2p2_mac_postamble | ||
22 | |||
23 | #define qca953x_1p0_soc_postamble ar9300_2p2_soc_postamble | ||
24 | |||
25 | #define qca953x_1p0_common_rx_gain_table ar9300Common_rx_gain_table_2p2 | ||
26 | |||
27 | #define qca953x_1p0_common_wo_xlna_rx_gain_table ar9300Common_wo_xlna_rx_gain_table_2p2 | ||
28 | |||
29 | #define qca953x_1p0_modes_fast_clock ar9300Modes_fast_clock_2p2 | ||
30 | |||
31 | static const u32 qca953x_1p0_mac_core[][2] = { | ||
32 | /* Addr allmodes */ | ||
33 | {0x00000008, 0x00000000}, | ||
34 | {0x00000030, 0x00020085}, | ||
35 | {0x00000034, 0x00000005}, | ||
36 | {0x00000040, 0x00000000}, | ||
37 | {0x00000044, 0x00000000}, | ||
38 | {0x00000048, 0x00000008}, | ||
39 | {0x0000004c, 0x00000010}, | ||
40 | {0x00000050, 0x00000000}, | ||
41 | {0x00001040, 0x002ffc0f}, | ||
42 | {0x00001044, 0x002ffc0f}, | ||
43 | {0x00001048, 0x002ffc0f}, | ||
44 | {0x0000104c, 0x002ffc0f}, | ||
45 | {0x00001050, 0x002ffc0f}, | ||
46 | {0x00001054, 0x002ffc0f}, | ||
47 | {0x00001058, 0x002ffc0f}, | ||
48 | {0x0000105c, 0x002ffc0f}, | ||
49 | {0x00001060, 0x002ffc0f}, | ||
50 | {0x00001064, 0x002ffc0f}, | ||
51 | {0x000010f0, 0x00000100}, | ||
52 | {0x00001270, 0x00000000}, | ||
53 | {0x000012b0, 0x00000000}, | ||
54 | {0x000012f0, 0x00000000}, | ||
55 | {0x0000143c, 0x00000000}, | ||
56 | {0x0000147c, 0x00000000}, | ||
57 | {0x00008000, 0x00000000}, | ||
58 | {0x00008004, 0x00000000}, | ||
59 | {0x00008008, 0x00000000}, | ||
60 | {0x0000800c, 0x00000000}, | ||
61 | {0x00008018, 0x00000000}, | ||
62 | {0x00008020, 0x00000000}, | ||
63 | {0x00008038, 0x00000000}, | ||
64 | {0x0000803c, 0x00000000}, | ||
65 | {0x00008040, 0x00000000}, | ||
66 | {0x00008044, 0x00000000}, | ||
67 | {0x00008048, 0x00000000}, | ||
68 | {0x0000804c, 0xffffffff}, | ||
69 | {0x00008054, 0x00000000}, | ||
70 | {0x00008058, 0x00000000}, | ||
71 | {0x0000805c, 0x000fc78f}, | ||
72 | {0x00008060, 0x0000000f}, | ||
73 | {0x00008064, 0x00000000}, | ||
74 | {0x00008070, 0x00000310}, | ||
75 | {0x00008074, 0x00000020}, | ||
76 | {0x00008078, 0x00000000}, | ||
77 | {0x0000809c, 0x0000000f}, | ||
78 | {0x000080a0, 0x00000000}, | ||
79 | {0x000080a4, 0x02ff0000}, | ||
80 | {0x000080a8, 0x0e070605}, | ||
81 | {0x000080ac, 0x0000000d}, | ||
82 | {0x000080b0, 0x00000000}, | ||
83 | {0x000080b4, 0x00000000}, | ||
84 | {0x000080b8, 0x00000000}, | ||
85 | {0x000080bc, 0x00000000}, | ||
86 | {0x000080c0, 0x2a800000}, | ||
87 | {0x000080c4, 0x06900168}, | ||
88 | {0x000080c8, 0x13881c22}, | ||
89 | {0x000080cc, 0x01f40000}, | ||
90 | {0x000080d0, 0x00252500}, | ||
91 | {0x000080d4, 0x00a00000}, | ||
92 | {0x000080d8, 0x00400000}, | ||
93 | {0x000080dc, 0x00000000}, | ||
94 | {0x000080e0, 0xffffffff}, | ||
95 | {0x000080e4, 0x0000ffff}, | ||
96 | {0x000080e8, 0x3f3f3f3f}, | ||
97 | {0x000080ec, 0x00000000}, | ||
98 | {0x000080f0, 0x00000000}, | ||
99 | {0x000080f4, 0x00000000}, | ||
100 | {0x000080fc, 0x00020000}, | ||
101 | {0x00008100, 0x00000000}, | ||
102 | {0x00008108, 0x00000052}, | ||
103 | {0x0000810c, 0x00000000}, | ||
104 | {0x00008110, 0x00000000}, | ||
105 | {0x00008114, 0x000007ff}, | ||
106 | {0x00008118, 0x000000aa}, | ||
107 | {0x0000811c, 0x00003210}, | ||
108 | {0x00008124, 0x00000000}, | ||
109 | {0x00008128, 0x00000000}, | ||
110 | {0x0000812c, 0x00000000}, | ||
111 | {0x00008130, 0x00000000}, | ||
112 | {0x00008134, 0x00000000}, | ||
113 | {0x00008138, 0x00000000}, | ||
114 | {0x0000813c, 0x0000ffff}, | ||
115 | {0x00008140, 0x000000fe}, | ||
116 | {0x00008144, 0xffffffff}, | ||
117 | {0x00008168, 0x00000000}, | ||
118 | {0x0000816c, 0x00000000}, | ||
119 | {0x000081c0, 0x00000000}, | ||
120 | {0x000081c4, 0x33332210}, | ||
121 | {0x000081ec, 0x00000000}, | ||
122 | {0x000081f0, 0x00000000}, | ||
123 | {0x000081f4, 0x00000000}, | ||
124 | {0x000081f8, 0x00000000}, | ||
125 | {0x000081fc, 0x00000000}, | ||
126 | {0x00008240, 0x00100000}, | ||
127 | {0x00008244, 0x0010f3d7}, | ||
128 | {0x00008248, 0x00000852}, | ||
129 | {0x0000824c, 0x0001e7ae}, | ||
130 | {0x00008250, 0x00000000}, | ||
131 | {0x00008254, 0x00000000}, | ||
132 | {0x00008258, 0x00000000}, | ||
133 | {0x0000825c, 0x40000000}, | ||
134 | {0x00008260, 0x00080922}, | ||
135 | {0x00008264, 0x9d400010}, | ||
136 | {0x00008268, 0xffffffff}, | ||
137 | {0x0000826c, 0x0000ffff}, | ||
138 | {0x00008270, 0x00000000}, | ||
139 | {0x00008274, 0x40000000}, | ||
140 | {0x00008278, 0x003e4180}, | ||
141 | {0x0000827c, 0x00000004}, | ||
142 | {0x00008284, 0x0000002c}, | ||
143 | {0x00008288, 0x0000002c}, | ||
144 | {0x0000828c, 0x000000ff}, | ||
145 | {0x00008294, 0x00000000}, | ||
146 | {0x00008298, 0x00000000}, | ||
147 | {0x0000829c, 0x00000000}, | ||
148 | {0x00008300, 0x00001d40}, | ||
149 | {0x00008314, 0x00000000}, | ||
150 | {0x0000831c, 0x0000010d}, | ||
151 | {0x00008328, 0x00000000}, | ||
152 | {0x0000832c, 0x0000001f}, | ||
153 | {0x00008330, 0x00000302}, | ||
154 | {0x00008334, 0x00000700}, | ||
155 | {0x00008338, 0xffff0000}, | ||
156 | {0x0000833c, 0x02400000}, | ||
157 | {0x00008340, 0x000107ff}, | ||
158 | {0x00008344, 0xaa48107b}, | ||
159 | {0x00008348, 0x008f0000}, | ||
160 | {0x0000835c, 0x00000000}, | ||
161 | {0x00008360, 0xffffffff}, | ||
162 | {0x00008364, 0xffffffff}, | ||
163 | {0x00008368, 0x00000000}, | ||
164 | {0x00008370, 0x00000000}, | ||
165 | {0x00008374, 0x000000ff}, | ||
166 | {0x00008378, 0x00000000}, | ||
167 | {0x0000837c, 0x00000000}, | ||
168 | {0x00008380, 0xffffffff}, | ||
169 | {0x00008384, 0xffffffff}, | ||
170 | {0x00008390, 0xffffffff}, | ||
171 | {0x00008394, 0xffffffff}, | ||
172 | {0x00008398, 0x00000000}, | ||
173 | {0x0000839c, 0x00000000}, | ||
174 | {0x000083a0, 0x00000000}, | ||
175 | {0x000083a4, 0x0000fa14}, | ||
176 | {0x000083a8, 0x000f0c00}, | ||
177 | {0x000083ac, 0x33332210}, | ||
178 | {0x000083b0, 0x33332210}, | ||
179 | {0x000083b4, 0x33332210}, | ||
180 | {0x000083b8, 0x33332210}, | ||
181 | {0x000083bc, 0x00000000}, | ||
182 | {0x000083c0, 0x00000000}, | ||
183 | {0x000083c4, 0x00000000}, | ||
184 | {0x000083c8, 0x00000000}, | ||
185 | {0x000083cc, 0x00000200}, | ||
186 | {0x000083d0, 0x8c7901ff}, | ||
187 | }; | ||
188 | |||
189 | static const u32 qca953x_1p0_baseband_core[][2] = { | ||
190 | /* Addr allmodes */ | ||
191 | {0x00009800, 0xafe68e30}, | ||
192 | {0x00009804, 0xfd14e000}, | ||
193 | {0x00009808, 0x9c0a9f6b}, | ||
194 | {0x0000980c, 0x04900000}, | ||
195 | {0x00009814, 0x0280c00a}, | ||
196 | {0x00009818, 0x00000000}, | ||
197 | {0x0000981c, 0x00020028}, | ||
198 | {0x00009834, 0x6400a190}, | ||
199 | {0x00009838, 0x0108ecff}, | ||
200 | {0x0000983c, 0x14000600}, | ||
201 | {0x00009880, 0x201fff00}, | ||
202 | {0x00009884, 0x00001042}, | ||
203 | {0x000098a4, 0x00200400}, | ||
204 | {0x000098b0, 0x32840bbe}, | ||
205 | {0x000098bc, 0x00000002}, | ||
206 | {0x000098d0, 0x004b6a8e}, | ||
207 | {0x000098d4, 0x00000820}, | ||
208 | {0x000098dc, 0x00000000}, | ||
209 | {0x000098f0, 0x00000000}, | ||
210 | {0x000098f4, 0x00000000}, | ||
211 | {0x00009c04, 0xff55ff55}, | ||
212 | {0x00009c08, 0x0320ff55}, | ||
213 | {0x00009c0c, 0x00000000}, | ||
214 | {0x00009c10, 0x00000000}, | ||
215 | {0x00009c14, 0x00046384}, | ||
216 | {0x00009c18, 0x05b6b440}, | ||
217 | {0x00009c1c, 0x00b6b440}, | ||
218 | {0x00009d00, 0xc080a333}, | ||
219 | {0x00009d04, 0x40206c10}, | ||
220 | {0x00009d08, 0x009c4060}, | ||
221 | {0x00009d0c, 0x9883800a}, | ||
222 | {0x00009d10, 0x01884061}, | ||
223 | {0x00009d14, 0x00c0040b}, | ||
224 | {0x00009d18, 0x00000000}, | ||
225 | {0x00009e08, 0x0038230c}, | ||
226 | {0x00009e24, 0x990bb515}, | ||
227 | {0x00009e28, 0x0c6f0000}, | ||
228 | {0x00009e30, 0x06336f77}, | ||
229 | {0x00009e34, 0x6af6532f}, | ||
230 | {0x00009e38, 0x0cc80c00}, | ||
231 | {0x00009e40, 0x0d261820}, | ||
232 | {0x00009e4c, 0x00001004}, | ||
233 | {0x00009e50, 0x00ff03f1}, | ||
234 | {0x00009fc0, 0x813e4788}, | ||
235 | {0x00009fc4, 0x0001efb5}, | ||
236 | {0x00009fcc, 0x40000014}, | ||
237 | {0x00009fd0, 0x01193b91}, | ||
238 | {0x0000a20c, 0x00000000}, | ||
239 | {0x0000a220, 0x00000000}, | ||
240 | {0x0000a224, 0x00000000}, | ||
241 | {0x0000a228, 0x10002310}, | ||
242 | {0x0000a23c, 0x00000000}, | ||
243 | {0x0000a244, 0x0c000000}, | ||
244 | {0x0000a248, 0x00000140}, | ||
245 | {0x0000a2a0, 0x00000007}, | ||
246 | {0x0000a2c0, 0x00000007}, | ||
247 | {0x0000a2c8, 0x00000000}, | ||
248 | {0x0000a2d4, 0x00000000}, | ||
249 | {0x0000a2ec, 0x00000000}, | ||
250 | {0x0000a2f0, 0x00000000}, | ||
251 | {0x0000a2f4, 0x00000000}, | ||
252 | {0x0000a2f8, 0x00000000}, | ||
253 | {0x0000a344, 0x00000000}, | ||
254 | {0x0000a34c, 0x00000000}, | ||
255 | {0x0000a350, 0x0000a000}, | ||
256 | {0x0000a364, 0x00000000}, | ||
257 | {0x0000a370, 0x00000000}, | ||
258 | {0x0000a390, 0x00000001}, | ||
259 | {0x0000a394, 0x00000444}, | ||
260 | {0x0000a398, 0x1f020503}, | ||
261 | {0x0000a39c, 0x29180c03}, | ||
262 | {0x0000a3a0, 0x9a8b6844}, | ||
263 | {0x0000a3a4, 0x000000ff}, | ||
264 | {0x0000a3a8, 0x6a6a6a6a}, | ||
265 | {0x0000a3ac, 0x6a6a6a6a}, | ||
266 | {0x0000a3b0, 0x00c8641a}, | ||
267 | {0x0000a3b4, 0x0000001a}, | ||
268 | {0x0000a3b8, 0x0088642a}, | ||
269 | {0x0000a3bc, 0x000001fa}, | ||
270 | {0x0000a3c0, 0x20202020}, | ||
271 | {0x0000a3c4, 0x22222220}, | ||
272 | {0x0000a3c8, 0x20200020}, | ||
273 | {0x0000a3cc, 0x20202020}, | ||
274 | {0x0000a3d0, 0x20202020}, | ||
275 | {0x0000a3d4, 0x20202020}, | ||
276 | {0x0000a3d8, 0x20202020}, | ||
277 | {0x0000a3dc, 0x20202020}, | ||
278 | {0x0000a3e0, 0x20202020}, | ||
279 | {0x0000a3e4, 0x20202020}, | ||
280 | {0x0000a3e8, 0x20202020}, | ||
281 | {0x0000a3ec, 0x20202020}, | ||
282 | {0x0000a3f0, 0x00000000}, | ||
283 | {0x0000a3f4, 0x00000000}, | ||
284 | {0x0000a3f8, 0x0c9bd380}, | ||
285 | {0x0000a3fc, 0x000f0f01}, | ||
286 | {0x0000a400, 0x8fa91f01}, | ||
287 | {0x0000a404, 0x00000000}, | ||
288 | {0x0000a408, 0x0e79e5c6}, | ||
289 | {0x0000a40c, 0x00820820}, | ||
290 | {0x0000a414, 0x1ce42108}, | ||
291 | {0x0000a418, 0x2d001dce}, | ||
292 | {0x0000a41c, 0x1ce73908}, | ||
293 | {0x0000a420, 0x000001ce}, | ||
294 | {0x0000a424, 0x1ce738e7}, | ||
295 | {0x0000a428, 0x000001ce}, | ||
296 | {0x0000a42c, 0x1ce739ce}, | ||
297 | {0x0000a430, 0x1ce739ce}, | ||
298 | {0x0000a434, 0x00000000}, | ||
299 | {0x0000a438, 0x00001801}, | ||
300 | {0x0000a43c, 0x00100000}, | ||
301 | {0x0000a444, 0x00000000}, | ||
302 | {0x0000a448, 0x05000080}, | ||
303 | {0x0000a44c, 0x00000001}, | ||
304 | {0x0000a450, 0x00010000}, | ||
305 | {0x0000a458, 0x00000000}, | ||
306 | {0x0000a644, 0xbfad9d74}, | ||
307 | {0x0000a648, 0x0048060a}, | ||
308 | {0x0000a64c, 0x00003c37}, | ||
309 | {0x0000a670, 0x03020100}, | ||
310 | {0x0000a674, 0x09080504}, | ||
311 | {0x0000a678, 0x0d0c0b0a}, | ||
312 | {0x0000a67c, 0x13121110}, | ||
313 | {0x0000a680, 0x31301514}, | ||
314 | {0x0000a684, 0x35343332}, | ||
315 | {0x0000a688, 0x00000036}, | ||
316 | {0x0000a690, 0x08000838}, | ||
317 | {0x0000a7cc, 0x00000000}, | ||
318 | {0x0000a7d0, 0x00000000}, | ||
319 | {0x0000a7d4, 0x00000004}, | ||
320 | {0x0000a7dc, 0x00000000}, | ||
321 | {0x0000a8d0, 0x004b6a8e}, | ||
322 | {0x0000a8d4, 0x00000820}, | ||
323 | {0x0000a8dc, 0x00000000}, | ||
324 | {0x0000a8f0, 0x00000000}, | ||
325 | {0x0000a8f4, 0x00000000}, | ||
326 | {0x0000b2d0, 0x00000080}, | ||
327 | {0x0000b2d4, 0x00000000}, | ||
328 | {0x0000b2ec, 0x00000000}, | ||
329 | {0x0000b2f0, 0x00000000}, | ||
330 | {0x0000b2f4, 0x00000000}, | ||
331 | {0x0000b2f8, 0x00000000}, | ||
332 | {0x0000b408, 0x0e79e5c0}, | ||
333 | {0x0000b40c, 0x00820820}, | ||
334 | {0x0000b420, 0x00000000}, | ||
335 | }; | ||
336 | |||
337 | static const u32 qca953x_1p0_baseband_postamble[][5] = { | ||
338 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
339 | {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011}, | ||
340 | {0x00009820, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a012e}, | ||
341 | {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, | ||
342 | {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881}, | ||
343 | {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, | ||
344 | {0x00009830, 0x0000059c, 0x0000059c, 0x0000119c, 0x0000119c}, | ||
345 | {0x00009c00, 0x000000c4, 0x000000c4, 0x000000c4, 0x000000c4}, | ||
346 | {0x00009e00, 0x0372111a, 0x0372111a, 0x037216a0, 0x037216a0}, | ||
347 | {0x00009e04, 0x001c2020, 0x001c2020, 0x001c2020, 0x001c2020}, | ||
348 | {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2}, | ||
349 | {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec84d2e}, | ||
350 | {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3379605e, 0x33795d5e}, | ||
351 | {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
352 | {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, | ||
353 | {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, | ||
354 | {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021}, | ||
355 | {0x00009e3c, 0xcfa10820, 0xcfa10820, 0xcfa10822, 0xcfa10822}, | ||
356 | {0x00009e44, 0xfe321e27, 0xfe321e27, 0xfe291e27, 0xfe291e27}, | ||
357 | {0x00009e48, 0x5030201a, 0x5030201a, 0x50302012, 0x50302012}, | ||
358 | {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000}, | ||
359 | {0x0000a204, 0x005c0ec0, 0x005c0ec4, 0x005c0ec4, 0x005c0ec0}, | ||
360 | {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004}, | ||
361 | {0x0000a22c, 0x07e26a2f, 0x07e26a2f, 0x01026a2f, 0x01026a2f}, | ||
362 | {0x0000a230, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b}, | ||
363 | {0x0000a234, 0x00000fff, 0x10000fff, 0x10000fff, 0x00000fff}, | ||
364 | {0x0000a238, 0xffb01018, 0xffb01018, 0xffb01018, 0xffb01018}, | ||
365 | {0x0000a250, 0x00000000, 0x00000000, 0x00000210, 0x00000108}, | ||
366 | {0x0000a254, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898}, | ||
367 | {0x0000a258, 0x02020002, 0x02020002, 0x02020002, 0x02020002}, | ||
368 | {0x0000a25c, 0x01000e0e, 0x01000e0e, 0x01010e0e, 0x01010e0e}, | ||
369 | {0x0000a260, 0x0a021501, 0x0a021501, 0x3a021501, 0x3a021501}, | ||
370 | {0x0000a264, 0x00000e0e, 0x00000e0e, 0x01000e0e, 0x01000e0e}, | ||
371 | {0x0000a280, 0x00000007, 0x00000007, 0x0000000b, 0x0000000b}, | ||
372 | {0x0000a284, 0x00000000, 0x00000000, 0x00000010, 0x00000010}, | ||
373 | {0x0000a288, 0x00000110, 0x00000110, 0x00000110, 0x00000110}, | ||
374 | {0x0000a28c, 0x00022222, 0x00022222, 0x00022222, 0x00022222}, | ||
375 | {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18}, | ||
376 | {0x0000a2cc, 0x18c50033, 0x18c43433, 0x18c41033, 0x18c44c33}, | ||
377 | {0x0000a2d0, 0x00041982, 0x00041982, 0x00041982, 0x00041982}, | ||
378 | {0x0000a2d8, 0x7999a83b, 0x7999a83b, 0x7999a83b, 0x7999a83b}, | ||
379 | {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
380 | {0x0000a830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, | ||
381 | {0x0000ae04, 0x001c0000, 0x001c0000, 0x001c0000, 0x001c0000}, | ||
382 | {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
383 | {0x0000ae1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, | ||
384 | {0x0000ae20, 0x000001b5, 0x000001b5, 0x000001ce, 0x000001ce}, | ||
385 | {0x0000b284, 0x00000000, 0x00000000, 0x00000010, 0x00000010}, | ||
386 | }; | ||
387 | |||
388 | static const u32 qca953x_1p0_radio_core[][2] = { | ||
389 | /* Addr allmodes */ | ||
390 | {0x00016000, 0x36db6db6}, | ||
391 | {0x00016004, 0x6db6db40}, | ||
392 | {0x00016008, 0x73f00000}, | ||
393 | {0x0001600c, 0x00000000}, | ||
394 | {0x00016040, 0x3f80fff8}, | ||
395 | {0x0001604c, 0x000f0278}, | ||
396 | {0x00016050, 0x8036db6c}, | ||
397 | {0x00016054, 0x6db60000}, | ||
398 | {0x00016080, 0x00080000}, | ||
399 | {0x00016084, 0x0e48048c}, | ||
400 | {0x00016088, 0x14214514}, | ||
401 | {0x0001608c, 0x119f080a}, | ||
402 | {0x00016090, 0x24926490}, | ||
403 | {0x00016094, 0x00000000}, | ||
404 | {0x000160a0, 0xc2108ffe}, | ||
405 | {0x000160a4, 0x812fc370}, | ||
406 | {0x000160a8, 0x423c8000}, | ||
407 | {0x000160b4, 0x92480080}, | ||
408 | {0x000160c0, 0x006db6d8}, | ||
409 | {0x000160c4, 0x24b6db6c}, | ||
410 | {0x000160c8, 0x6db6db6c}, | ||
411 | {0x000160cc, 0x6db6fb7c}, | ||
412 | {0x000160d0, 0x6db6da44}, | ||
413 | {0x00016100, 0x07ff8001}, | ||
414 | {0x00016108, 0x00080010}, | ||
415 | {0x00016144, 0x01884080}, | ||
416 | {0x00016148, 0x000080d8}, | ||
417 | {0x00016280, 0x01000901}, | ||
418 | {0x00016284, 0x15d30000}, | ||
419 | {0x00016288, 0x00318000}, | ||
420 | {0x0001628c, 0x50000000}, | ||
421 | {0x00016380, 0x00000000}, | ||
422 | {0x00016384, 0x00000000}, | ||
423 | {0x00016388, 0x00800700}, | ||
424 | {0x0001638c, 0x00800700}, | ||
425 | {0x00016390, 0x00800700}, | ||
426 | {0x00016394, 0x00000000}, | ||
427 | {0x00016398, 0x00000000}, | ||
428 | {0x0001639c, 0x00000000}, | ||
429 | {0x000163a0, 0x00000001}, | ||
430 | {0x000163a4, 0x00000001}, | ||
431 | {0x000163a8, 0x00000000}, | ||
432 | {0x000163ac, 0x00000000}, | ||
433 | {0x000163b0, 0x00000000}, | ||
434 | {0x000163b4, 0x00000000}, | ||
435 | {0x000163b8, 0x00000000}, | ||
436 | {0x000163bc, 0x00000000}, | ||
437 | {0x000163c0, 0x000000a0}, | ||
438 | {0x000163c4, 0x000c0000}, | ||
439 | {0x000163c8, 0x14021402}, | ||
440 | {0x000163cc, 0x00001402}, | ||
441 | {0x000163d0, 0x00000000}, | ||
442 | {0x000163d4, 0x00000000}, | ||
443 | {0x00016400, 0x36db6db6}, | ||
444 | {0x00016404, 0x6db6db40}, | ||
445 | {0x00016408, 0x73f00000}, | ||
446 | {0x0001640c, 0x00000000}, | ||
447 | {0x00016440, 0x3f80fff8}, | ||
448 | {0x0001644c, 0x000f0278}, | ||
449 | {0x00016450, 0x8036db6c}, | ||
450 | {0x00016454, 0x6db60000}, | ||
451 | {0x00016500, 0x07ff8001}, | ||
452 | {0x00016508, 0x00080010}, | ||
453 | {0x00016544, 0x01884080}, | ||
454 | {0x00016548, 0x000080d8}, | ||
455 | {0x00016780, 0x00000000}, | ||
456 | {0x00016784, 0x00000000}, | ||
457 | {0x00016788, 0x00800700}, | ||
458 | {0x0001678c, 0x00800700}, | ||
459 | {0x00016790, 0x00800700}, | ||
460 | {0x00016794, 0x00000000}, | ||
461 | {0x00016798, 0x00000000}, | ||
462 | {0x0001679c, 0x00000000}, | ||
463 | {0x000167a0, 0x00000001}, | ||
464 | {0x000167a4, 0x00000001}, | ||
465 | {0x000167a8, 0x00000000}, | ||
466 | {0x000167ac, 0x00000000}, | ||
467 | {0x000167b0, 0x00000000}, | ||
468 | {0x000167b4, 0x00000000}, | ||
469 | {0x000167b8, 0x00000000}, | ||
470 | {0x000167bc, 0x00000000}, | ||
471 | {0x000167c0, 0x000000a0}, | ||
472 | {0x000167c4, 0x000c0000}, | ||
473 | {0x000167c8, 0x14021402}, | ||
474 | {0x000167cc, 0x00001402}, | ||
475 | {0x000167d0, 0x00000000}, | ||
476 | {0x000167d4, 0x00000000}, | ||
477 | }; | ||
478 | |||
479 | static const u32 qca953x_1p0_radio_postamble[][5] = { | ||
480 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
481 | {0x00016098, 0xd2dd5554, 0xd2dd5554, 0xc4128f5c, 0xc4128f5c}, | ||
482 | {0x0001609c, 0x0a566f3a, 0x0a566f3a, 0x0fd08f25, 0x0fd08f25}, | ||
483 | {0x000160ac, 0xa4647c00, 0xa4647c00, 0x24646800, 0x24646800}, | ||
484 | {0x000160b0, 0x01885f52, 0x01885f52, 0x00fe7f46, 0x00fe7f46}, | ||
485 | {0x00016104, 0xb7a00001, 0xb7a00001, 0xfff80005, 0xfff80005}, | ||
486 | {0x0001610c, 0xc0000000, 0xc0000000, 0x00000000, 0x00000000}, | ||
487 | {0x00016140, 0x10804008, 0x10804008, 0x50804000, 0x50804000}, | ||
488 | {0x00016504, 0xb7a00001, 0xb7a00001, 0xfff80001, 0xfff80001}, | ||
489 | {0x0001650c, 0xc0000000, 0xc0000000, 0x00000000, 0x00000000}, | ||
490 | {0x00016540, 0x10804008, 0x10804008, 0x50804000, 0x50804000}, | ||
491 | }; | ||
492 | |||
493 | static const u32 qca953x_1p0_soc_preamble[][2] = { | ||
494 | /* Addr allmodes */ | ||
495 | {0x00007000, 0x00000000}, | ||
496 | {0x00007004, 0x00000000}, | ||
497 | {0x00007008, 0x00000000}, | ||
498 | {0x0000700c, 0x00000000}, | ||
499 | {0x0000701c, 0x00000000}, | ||
500 | {0x00007020, 0x00000000}, | ||
501 | {0x00007024, 0x00000000}, | ||
502 | {0x00007028, 0x00000000}, | ||
503 | {0x0000702c, 0x00000000}, | ||
504 | {0x00007030, 0x00000000}, | ||
505 | {0x00007034, 0x00000002}, | ||
506 | {0x00007038, 0x000004c2}, | ||
507 | {0x00007048, 0x00000000}, | ||
508 | }; | ||
509 | |||
510 | static const u32 qca953x_1p0_common_rx_gain_bounds[][5] = { | ||
511 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
512 | {0x00009e44, 0xfe321e27, 0xfe321e27, 0xfe291e27, 0xfe291e27}, | ||
513 | {0x00009e48, 0x5030201a, 0x5030201a, 0x50302018, 0x50302018}, | ||
514 | }; | ||
515 | |||
516 | static const u32 qca953x_1p0_common_wo_xlna_rx_gain_bounds[][5] = { | ||
517 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
518 | {0x00009e44, 0xfe321e27, 0xfe321e27, 0xfe291e27, 0xfe291e27}, | ||
519 | {0x00009e48, 0x5030201a, 0x5030201a, 0x50302012, 0x50302012}, | ||
520 | }; | ||
521 | |||
522 | static const u32 qca953x_1p0_modes_xpa_tx_gain_table[][2] = { | ||
523 | /* Addr allmodes */ | ||
524 | {0x0000a2dc, 0xfffd5aaa}, | ||
525 | {0x0000a2e0, 0xfffe9ccc}, | ||
526 | {0x0000a2e4, 0xffffe0f0}, | ||
527 | {0x0000a2e8, 0xfffcff00}, | ||
528 | {0x0000a410, 0x000050da}, | ||
529 | {0x0000a500, 0x00000000}, | ||
530 | {0x0000a504, 0x04000002}, | ||
531 | {0x0000a508, 0x08000004}, | ||
532 | {0x0000a50c, 0x0c000006}, | ||
533 | {0x0000a510, 0x0f00000a}, | ||
534 | {0x0000a514, 0x1300000c}, | ||
535 | {0x0000a518, 0x1700000e}, | ||
536 | {0x0000a51c, 0x1b000064}, | ||
537 | {0x0000a520, 0x1f000242}, | ||
538 | {0x0000a524, 0x23000229}, | ||
539 | {0x0000a528, 0x270002a2}, | ||
540 | {0x0000a52c, 0x2c001203}, | ||
541 | {0x0000a530, 0x30001803}, | ||
542 | {0x0000a534, 0x33000881}, | ||
543 | {0x0000a538, 0x38001809}, | ||
544 | {0x0000a53c, 0x3a000814}, | ||
545 | {0x0000a540, 0x3f001a0c}, | ||
546 | {0x0000a544, 0x43001a0e}, | ||
547 | {0x0000a548, 0x46001812}, | ||
548 | {0x0000a54c, 0x49001884}, | ||
549 | {0x0000a550, 0x4d001e84}, | ||
550 | {0x0000a554, 0x50001e69}, | ||
551 | {0x0000a558, 0x550006f4}, | ||
552 | {0x0000a55c, 0x59000ad3}, | ||
553 | {0x0000a560, 0x5e000ad5}, | ||
554 | {0x0000a564, 0x61001ced}, | ||
555 | {0x0000a568, 0x660018d4}, | ||
556 | {0x0000a56c, 0x660018d4}, | ||
557 | {0x0000a570, 0x660018d4}, | ||
558 | {0x0000a574, 0x660018d4}, | ||
559 | {0x0000a578, 0x660018d4}, | ||
560 | {0x0000a57c, 0x660018d4}, | ||
561 | {0x0000a600, 0x00000000}, | ||
562 | {0x0000a604, 0x00000000}, | ||
563 | {0x0000a608, 0x00000000}, | ||
564 | {0x0000a60c, 0x03804000}, | ||
565 | {0x0000a610, 0x0300ca02}, | ||
566 | {0x0000a614, 0x00000e04}, | ||
567 | {0x0000a618, 0x03014000}, | ||
568 | {0x0000a61c, 0x00000000}, | ||
569 | {0x0000a620, 0x00000000}, | ||
570 | {0x0000a624, 0x03014000}, | ||
571 | {0x0000a628, 0x03804c05}, | ||
572 | {0x0000a62c, 0x0701de06}, | ||
573 | {0x0000a630, 0x07819c07}, | ||
574 | {0x0000a634, 0x0701dc07}, | ||
575 | {0x0000a638, 0x0701dc07}, | ||
576 | {0x0000a63c, 0x0701dc07}, | ||
577 | {0x0000b2dc, 0xfffd5aaa}, | ||
578 | {0x0000b2e0, 0xfffe9ccc}, | ||
579 | {0x0000b2e4, 0xffffe0f0}, | ||
580 | {0x0000b2e8, 0xfffcff00}, | ||
581 | {0x00016044, 0x010002d4}, | ||
582 | {0x00016048, 0x66482400}, | ||
583 | {0x00016280, 0x01000015}, | ||
584 | {0x00016444, 0x010002d4}, | ||
585 | {0x00016448, 0x66482400}, | ||
586 | }; | ||
587 | |||
588 | static const u32 qca953x_1p0_modes_no_xpa_tx_gain_table[][2] = { | ||
589 | /* Addr allmodes */ | ||
590 | {0x0000a2dc, 0xffd5f552}, | ||
591 | {0x0000a2e0, 0xffe60664}, | ||
592 | {0x0000a2e4, 0xfff80780}, | ||
593 | {0x0000a2e8, 0xfffff800}, | ||
594 | {0x0000a410, 0x000050d6}, | ||
595 | {0x0000a500, 0x00060020}, | ||
596 | {0x0000a504, 0x04060060}, | ||
597 | {0x0000a508, 0x080600a0}, | ||
598 | {0x0000a50c, 0x0c068020}, | ||
599 | {0x0000a510, 0x10068060}, | ||
600 | {0x0000a514, 0x140680a0}, | ||
601 | {0x0000a518, 0x18090040}, | ||
602 | {0x0000a51c, 0x1b090080}, | ||
603 | {0x0000a520, 0x1f0900c0}, | ||
604 | {0x0000a524, 0x240c0041}, | ||
605 | {0x0000a528, 0x280d0021}, | ||
606 | {0x0000a52c, 0x2d0f0061}, | ||
607 | {0x0000a530, 0x310f00a1}, | ||
608 | {0x0000a534, 0x350e00a2}, | ||
609 | {0x0000a538, 0x360e80a2}, | ||
610 | {0x0000a53c, 0x380f00a2}, | ||
611 | {0x0000a540, 0x3b0e00a3}, | ||
612 | {0x0000a544, 0x3d110083}, | ||
613 | {0x0000a548, 0x3e1100a3}, | ||
614 | {0x0000a54c, 0x401100e3}, | ||
615 | {0x0000a550, 0x421380e3}, | ||
616 | {0x0000a554, 0x431780e3}, | ||
617 | {0x0000a558, 0x461f80e3}, | ||
618 | {0x0000a55c, 0x461f80e3}, | ||
619 | {0x0000a560, 0x461f80e3}, | ||
620 | {0x0000a564, 0x461f80e3}, | ||
621 | {0x0000a568, 0x461f80e3}, | ||
622 | {0x0000a56c, 0x461f80e3}, | ||
623 | {0x0000a570, 0x461f80e3}, | ||
624 | {0x0000a574, 0x461f80e3}, | ||
625 | {0x0000a578, 0x461f80e3}, | ||
626 | {0x0000a57c, 0x461f80e3}, | ||
627 | {0x0000a600, 0x00000000}, | ||
628 | {0x0000a604, 0x00000000}, | ||
629 | {0x0000a608, 0x00000000}, | ||
630 | {0x0000a60c, 0x00804201}, | ||
631 | {0x0000a610, 0x01008201}, | ||
632 | {0x0000a614, 0x0180c402}, | ||
633 | {0x0000a618, 0x0180c603}, | ||
634 | {0x0000a61c, 0x0180c603}, | ||
635 | {0x0000a620, 0x01c10603}, | ||
636 | {0x0000a624, 0x01c10704}, | ||
637 | {0x0000a628, 0x02c18b05}, | ||
638 | {0x0000a62c, 0x0301cc07}, | ||
639 | {0x0000a630, 0x0301cc07}, | ||
640 | {0x0000a634, 0x0301cc07}, | ||
641 | {0x0000a638, 0x0301cc07}, | ||
642 | {0x0000a63c, 0x0301cc07}, | ||
643 | {0x0000b2dc, 0xffd5f552}, | ||
644 | {0x0000b2e0, 0xffe60664}, | ||
645 | {0x0000b2e4, 0xfff80780}, | ||
646 | {0x0000b2e8, 0xfffff800}, | ||
647 | {0x00016044, 0x049242db}, | ||
648 | {0x00016048, 0x6c927a70}, | ||
649 | {0x00016444, 0x049242db}, | ||
650 | {0x00016448, 0x6c927a70}, | ||
651 | }; | ||
652 | |||
653 | static const u32 qca953x_1p1_modes_no_xpa_tx_gain_table[][2] = { | ||
654 | /* Addr allmodes */ | ||
655 | {0x0000a2dc, 0xffd5f552}, | ||
656 | {0x0000a2e0, 0xffe60664}, | ||
657 | {0x0000a2e4, 0xfff80780}, | ||
658 | {0x0000a2e8, 0xfffff800}, | ||
659 | {0x0000a410, 0x000050de}, | ||
660 | {0x0000a500, 0x00000061}, | ||
661 | {0x0000a504, 0x04000063}, | ||
662 | {0x0000a508, 0x08000065}, | ||
663 | {0x0000a50c, 0x0c000261}, | ||
664 | {0x0000a510, 0x10000263}, | ||
665 | {0x0000a514, 0x14000265}, | ||
666 | {0x0000a518, 0x18000482}, | ||
667 | {0x0000a51c, 0x1b000484}, | ||
668 | {0x0000a520, 0x1f000486}, | ||
669 | {0x0000a524, 0x240008c2}, | ||
670 | {0x0000a528, 0x28000cc1}, | ||
671 | {0x0000a52c, 0x2d000ce3}, | ||
672 | {0x0000a530, 0x31000ce5}, | ||
673 | {0x0000a534, 0x350010e5}, | ||
674 | {0x0000a538, 0x360012e5}, | ||
675 | {0x0000a53c, 0x380014e5}, | ||
676 | {0x0000a540, 0x3b0018e5}, | ||
677 | {0x0000a544, 0x3d001d04}, | ||
678 | {0x0000a548, 0x3e001d05}, | ||
679 | {0x0000a54c, 0x40001d07}, | ||
680 | {0x0000a550, 0x42001f27}, | ||
681 | {0x0000a554, 0x43001f67}, | ||
682 | {0x0000a558, 0x46001fe7}, | ||
683 | {0x0000a55c, 0x47001f2b}, | ||
684 | {0x0000a560, 0x49001f0d}, | ||
685 | {0x0000a564, 0x4b001ed2}, | ||
686 | {0x0000a568, 0x4c001ed4}, | ||
687 | {0x0000a56c, 0x4e001f15}, | ||
688 | {0x0000a570, 0x4f001ff6}, | ||
689 | {0x0000a574, 0x4f001ff6}, | ||
690 | {0x0000a578, 0x4f001ff6}, | ||
691 | {0x0000a57c, 0x4f001ff6}, | ||
692 | {0x0000a600, 0x00000000}, | ||
693 | {0x0000a604, 0x00000000}, | ||
694 | {0x0000a608, 0x00000000}, | ||
695 | {0x0000a60c, 0x00804201}, | ||
696 | {0x0000a610, 0x01008201}, | ||
697 | {0x0000a614, 0x0180c402}, | ||
698 | {0x0000a618, 0x0180c603}, | ||
699 | {0x0000a61c, 0x0180c603}, | ||
700 | {0x0000a620, 0x01c10603}, | ||
701 | {0x0000a624, 0x01c10704}, | ||
702 | {0x0000a628, 0x02c18b05}, | ||
703 | {0x0000a62c, 0x02c14c07}, | ||
704 | {0x0000a630, 0x01008704}, | ||
705 | {0x0000a634, 0x01c10402}, | ||
706 | {0x0000a638, 0x0301cc07}, | ||
707 | {0x0000a63c, 0x0301cc07}, | ||
708 | {0x0000b2dc, 0xffd5f552}, | ||
709 | {0x0000b2e0, 0xffe60664}, | ||
710 | {0x0000b2e4, 0xfff80780}, | ||
711 | {0x0000b2e8, 0xfffff800}, | ||
712 | {0x00016044, 0x049242db}, | ||
713 | {0x00016048, 0x6c927a70}, | ||
714 | {0x00016444, 0x049242db}, | ||
715 | {0x00016448, 0x6c927a70}, | ||
716 | }; | ||
717 | |||
718 | #endif /* INITVALS_953X_H */ | ||
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index f2202e78fa7b..f622a986c8cc 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -455,10 +455,8 @@ bool ath9k_csa_is_finished(struct ath_softc *sc); | |||
455 | 455 | ||
456 | void ath_tx_complete_poll_work(struct work_struct *work); | 456 | void ath_tx_complete_poll_work(struct work_struct *work); |
457 | void ath_reset_work(struct work_struct *work); | 457 | void ath_reset_work(struct work_struct *work); |
458 | void ath_hw_check(struct work_struct *work); | 458 | bool ath_hw_check(struct ath_softc *sc); |
459 | void ath_hw_pll_work(struct work_struct *work); | 459 | void ath_hw_pll_work(struct work_struct *work); |
460 | void ath_rx_poll(unsigned long data); | ||
461 | void ath_start_rx_poll(struct ath_softc *sc, u8 nbeacon); | ||
462 | void ath_paprd_calibrate(struct work_struct *work); | 460 | void ath_paprd_calibrate(struct work_struct *work); |
463 | void ath_ani_calibrate(unsigned long data); | 461 | void ath_ani_calibrate(unsigned long data); |
464 | void ath_start_ani(struct ath_softc *sc); | 462 | void ath_start_ani(struct ath_softc *sc); |
@@ -722,12 +720,10 @@ struct ath_softc { | |||
722 | spinlock_t sc_pcu_lock; | 720 | spinlock_t sc_pcu_lock; |
723 | struct mutex mutex; | 721 | struct mutex mutex; |
724 | struct work_struct paprd_work; | 722 | struct work_struct paprd_work; |
725 | struct work_struct hw_check_work; | ||
726 | struct work_struct hw_reset_work; | 723 | struct work_struct hw_reset_work; |
727 | struct completion paprd_complete; | 724 | struct completion paprd_complete; |
728 | wait_queue_head_t tx_wait; | 725 | wait_queue_head_t tx_wait; |
729 | 726 | ||
730 | unsigned int hw_busy_count; | ||
731 | unsigned long sc_flags; | 727 | unsigned long sc_flags; |
732 | unsigned long driver_data; | 728 | unsigned long driver_data; |
733 | 729 | ||
@@ -761,7 +757,6 @@ struct ath_softc { | |||
761 | struct ath_beacon_config cur_beacon_conf; | 757 | struct ath_beacon_config cur_beacon_conf; |
762 | struct delayed_work tx_complete_work; | 758 | struct delayed_work tx_complete_work; |
763 | struct delayed_work hw_pll_work; | 759 | struct delayed_work hw_pll_work; |
764 | struct timer_list rx_poll_timer; | ||
765 | struct timer_list sleep_timer; | 760 | struct timer_list sleep_timer; |
766 | 761 | ||
767 | #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT | 762 | #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT |
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 112aff720e13..2e8bba0eb361 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c | |||
@@ -337,8 +337,14 @@ void ath9k_beacon_tasklet(unsigned long data) | |||
337 | 337 | ||
338 | ath9k_hw_check_nav(ah); | 338 | ath9k_hw_check_nav(ah); |
339 | 339 | ||
340 | if (!ath9k_hw_check_alive(ah)) | 340 | /* |
341 | ieee80211_queue_work(sc->hw, &sc->hw_check_work); | 341 | * If the previous beacon has not been transmitted |
342 | * and a MAC/BB hang has been identified, return | ||
343 | * here because a chip reset would have been | ||
344 | * initiated. | ||
345 | */ | ||
346 | if (!ath_hw_check(sc)) | ||
347 | return; | ||
342 | 348 | ||
343 | if (sc->beacon.bmisscnt < BSTUCK_THRESH * sc->nbcnvifs) { | 349 | if (sc->beacon.bmisscnt < BSTUCK_THRESH * sc->nbcnvifs) { |
344 | ath_dbg(common, BSTUCK, | 350 | ath_dbg(common, BSTUCK, |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index c028df76b564..b41e008298dc 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | |||
@@ -1077,7 +1077,7 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv, | |||
1077 | 1077 | ||
1078 | if (ieee80211_is_beacon(hdr->frame_control) && | 1078 | if (ieee80211_is_beacon(hdr->frame_control) && |
1079 | !is_zero_ether_addr(common->curbssid) && | 1079 | !is_zero_ether_addr(common->curbssid) && |
1080 | ether_addr_equal(hdr->addr3, common->curbssid)) { | 1080 | ether_addr_equal_64bits(hdr->addr3, common->curbssid)) { |
1081 | s8 rssi = rxbuf->rxstatus.rs_rssi; | 1081 | s8 rssi = rxbuf->rxstatus.rs_rssi; |
1082 | 1082 | ||
1083 | if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER)) | 1083 | if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER)) |
diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h index cc58a8ee1223..a47ea8423f1e 100644 --- a/drivers/net/wireless/ath/ath9k/hw-ops.h +++ b/drivers/net/wireless/ath/ath9k/hw-ops.h | |||
@@ -107,6 +107,21 @@ static inline void ath9k_hw_set_bt_ant_diversity(struct ath_hw *ah, bool enable) | |||
107 | 107 | ||
108 | /* Private hardware call ops */ | 108 | /* Private hardware call ops */ |
109 | 109 | ||
110 | static inline void ath9k_hw_init_hang_checks(struct ath_hw *ah) | ||
111 | { | ||
112 | ath9k_hw_private_ops(ah)->init_hang_checks(ah); | ||
113 | } | ||
114 | |||
115 | static inline bool ath9k_hw_detect_mac_hang(struct ath_hw *ah) | ||
116 | { | ||
117 | return ath9k_hw_private_ops(ah)->detect_mac_hang(ah); | ||
118 | } | ||
119 | |||
120 | static inline bool ath9k_hw_detect_bb_hang(struct ath_hw *ah) | ||
121 | { | ||
122 | return ath9k_hw_private_ops(ah)->detect_bb_hang(ah); | ||
123 | } | ||
124 | |||
110 | /* PHY ops */ | 125 | /* PHY ops */ |
111 | 126 | ||
112 | static inline int ath9k_hw_rf_set_freq(struct ath_hw *ah, | 127 | static inline int ath9k_hw_rf_set_freq(struct ath_hw *ah, |
@@ -232,4 +247,31 @@ static inline void ath9k_hw_set_radar_params(struct ath_hw *ah) | |||
232 | ath9k_hw_private_ops(ah)->set_radar_params(ah, &ah->radar_conf); | 247 | ath9k_hw_private_ops(ah)->set_radar_params(ah, &ah->radar_conf); |
233 | } | 248 | } |
234 | 249 | ||
250 | static inline void ath9k_hw_init_cal_settings(struct ath_hw *ah) | ||
251 | { | ||
252 | ath9k_hw_private_ops(ah)->init_cal_settings(ah); | ||
253 | } | ||
254 | |||
255 | static inline u32 ath9k_hw_compute_pll_control(struct ath_hw *ah, | ||
256 | struct ath9k_channel *chan) | ||
257 | { | ||
258 | return ath9k_hw_private_ops(ah)->compute_pll_control(ah, chan); | ||
259 | } | ||
260 | |||
261 | static inline void ath9k_hw_init_mode_gain_regs(struct ath_hw *ah) | ||
262 | { | ||
263 | if (!ath9k_hw_private_ops(ah)->init_mode_gain_regs) | ||
264 | return; | ||
265 | |||
266 | ath9k_hw_private_ops(ah)->init_mode_gain_regs(ah); | ||
267 | } | ||
268 | |||
269 | static inline void ath9k_hw_ani_cache_ini_regs(struct ath_hw *ah) | ||
270 | { | ||
271 | if (!ath9k_hw_private_ops(ah)->ani_cache_ini_regs) | ||
272 | return; | ||
273 | |||
274 | ath9k_hw_private_ops(ah)->ani_cache_ini_regs(ah); | ||
275 | } | ||
276 | |||
235 | #endif /* ATH9K_HW_OPS_H */ | 277 | #endif /* ATH9K_HW_OPS_H */ |
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index a4b1ae026216..ce41658a6003 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -37,57 +37,6 @@ MODULE_DESCRIPTION("Support for Atheros 802.11n wireless LAN cards."); | |||
37 | MODULE_SUPPORTED_DEVICE("Atheros 802.11n WLAN cards"); | 37 | MODULE_SUPPORTED_DEVICE("Atheros 802.11n WLAN cards"); |
38 | MODULE_LICENSE("Dual BSD/GPL"); | 38 | MODULE_LICENSE("Dual BSD/GPL"); |
39 | 39 | ||
40 | static int __init ath9k_init(void) | ||
41 | { | ||
42 | return 0; | ||
43 | } | ||
44 | module_init(ath9k_init); | ||
45 | |||
46 | static void __exit ath9k_exit(void) | ||
47 | { | ||
48 | return; | ||
49 | } | ||
50 | module_exit(ath9k_exit); | ||
51 | |||
52 | /* Private hardware callbacks */ | ||
53 | |||
54 | static void ath9k_hw_init_cal_settings(struct ath_hw *ah) | ||
55 | { | ||
56 | ath9k_hw_private_ops(ah)->init_cal_settings(ah); | ||
57 | } | ||
58 | |||
59 | static u32 ath9k_hw_compute_pll_control(struct ath_hw *ah, | ||
60 | struct ath9k_channel *chan) | ||
61 | { | ||
62 | return ath9k_hw_private_ops(ah)->compute_pll_control(ah, chan); | ||
63 | } | ||
64 | |||
65 | static void ath9k_hw_init_mode_gain_regs(struct ath_hw *ah) | ||
66 | { | ||
67 | if (!ath9k_hw_private_ops(ah)->init_mode_gain_regs) | ||
68 | return; | ||
69 | |||
70 | ath9k_hw_private_ops(ah)->init_mode_gain_regs(ah); | ||
71 | } | ||
72 | |||
73 | static void ath9k_hw_ani_cache_ini_regs(struct ath_hw *ah) | ||
74 | { | ||
75 | /* You will not have this callback if using the old ANI */ | ||
76 | if (!ath9k_hw_private_ops(ah)->ani_cache_ini_regs) | ||
77 | return; | ||
78 | |||
79 | ath9k_hw_private_ops(ah)->ani_cache_ini_regs(ah); | ||
80 | } | ||
81 | |||
82 | /********************/ | ||
83 | /* Helper Functions */ | ||
84 | /********************/ | ||
85 | |||
86 | #ifdef CONFIG_ATH9K_DEBUGFS | ||
87 | |||
88 | #endif | ||
89 | |||
90 | |||
91 | static void ath9k_hw_set_clockrate(struct ath_hw *ah) | 40 | static void ath9k_hw_set_clockrate(struct ath_hw *ah) |
92 | { | 41 | { |
93 | struct ath_common *common = ath9k_hw_common(ah); | 42 | struct ath_common *common = ath9k_hw_common(ah); |
@@ -296,6 +245,9 @@ static void ath9k_hw_read_revisions(struct ath_hw *ah) | |||
296 | case AR9300_DEVID_QCA955X: | 245 | case AR9300_DEVID_QCA955X: |
297 | ah->hw_version.macVersion = AR_SREV_VERSION_9550; | 246 | ah->hw_version.macVersion = AR_SREV_VERSION_9550; |
298 | return; | 247 | return; |
248 | case AR9300_DEVID_AR953X: | ||
249 | ah->hw_version.macVersion = AR_SREV_VERSION_9531; | ||
250 | return; | ||
299 | } | 251 | } |
300 | 252 | ||
301 | val = REG_READ(ah, AR_SREV) & AR_SREV_ID; | 253 | val = REG_READ(ah, AR_SREV) & AR_SREV_ID; |
@@ -397,9 +349,10 @@ static bool ath9k_hw_chip_test(struct ath_hw *ah) | |||
397 | 349 | ||
398 | static void ath9k_hw_init_config(struct ath_hw *ah) | 350 | static void ath9k_hw_init_config(struct ath_hw *ah) |
399 | { | 351 | { |
352 | struct ath_common *common = ath9k_hw_common(ah); | ||
353 | |||
400 | ah->config.dma_beacon_response_time = 1; | 354 | ah->config.dma_beacon_response_time = 1; |
401 | ah->config.sw_beacon_response_time = 6; | 355 | ah->config.sw_beacon_response_time = 6; |
402 | ah->config.ack_6mb = 0x0; | ||
403 | ah->config.cwm_ignore_extcca = 0; | 356 | ah->config.cwm_ignore_extcca = 0; |
404 | ah->config.analog_shiftreg = 1; | 357 | ah->config.analog_shiftreg = 1; |
405 | 358 | ||
@@ -423,6 +376,24 @@ static void ath9k_hw_init_config(struct ath_hw *ah) | |||
423 | */ | 376 | */ |
424 | if (num_possible_cpus() > 1) | 377 | if (num_possible_cpus() > 1) |
425 | ah->config.serialize_regmode = SER_REG_MODE_AUTO; | 378 | ah->config.serialize_regmode = SER_REG_MODE_AUTO; |
379 | |||
380 | if (NR_CPUS > 1 && ah->config.serialize_regmode == SER_REG_MODE_AUTO) { | ||
381 | if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI || | ||
382 | ((AR_SREV_9160(ah) || AR_SREV_9280(ah) || AR_SREV_9287(ah)) && | ||
383 | !ah->is_pciexpress)) { | ||
384 | ah->config.serialize_regmode = SER_REG_MODE_ON; | ||
385 | } else { | ||
386 | ah->config.serialize_regmode = SER_REG_MODE_OFF; | ||
387 | } | ||
388 | } | ||
389 | |||
390 | ath_dbg(common, RESET, "serialize_regmode is %d\n", | ||
391 | ah->config.serialize_regmode); | ||
392 | |||
393 | if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) | ||
394 | ah->config.max_txtrig_level = MAX_TX_FIFO_THRESHOLD >> 1; | ||
395 | else | ||
396 | ah->config.max_txtrig_level = MAX_TX_FIFO_THRESHOLD; | ||
426 | } | 397 | } |
427 | 398 | ||
428 | static void ath9k_hw_init_defaults(struct ath_hw *ah) | 399 | static void ath9k_hw_init_defaults(struct ath_hw *ah) |
@@ -435,15 +406,24 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah) | |||
435 | ah->hw_version.magic = AR5416_MAGIC; | 406 | ah->hw_version.magic = AR5416_MAGIC; |
436 | ah->hw_version.subvendorid = 0; | 407 | ah->hw_version.subvendorid = 0; |
437 | 408 | ||
438 | ah->sta_id1_defaults = | 409 | ah->sta_id1_defaults = AR_STA_ID1_CRPT_MIC_ENABLE | |
439 | AR_STA_ID1_CRPT_MIC_ENABLE | | 410 | AR_STA_ID1_MCAST_KSRCH; |
440 | AR_STA_ID1_MCAST_KSRCH; | ||
441 | if (AR_SREV_9100(ah)) | 411 | if (AR_SREV_9100(ah)) |
442 | ah->sta_id1_defaults |= AR_STA_ID1_AR9100_BA_FIX; | 412 | ah->sta_id1_defaults |= AR_STA_ID1_AR9100_BA_FIX; |
413 | |||
443 | ah->slottime = ATH9K_SLOT_TIME_9; | 414 | ah->slottime = ATH9K_SLOT_TIME_9; |
444 | ah->globaltxtimeout = (u32) -1; | 415 | ah->globaltxtimeout = (u32) -1; |
445 | ah->power_mode = ATH9K_PM_UNDEFINED; | 416 | ah->power_mode = ATH9K_PM_UNDEFINED; |
446 | ah->htc_reset_init = true; | 417 | ah->htc_reset_init = true; |
418 | |||
419 | ah->ani_function = ATH9K_ANI_ALL; | ||
420 | if (!AR_SREV_9300_20_OR_LATER(ah)) | ||
421 | ah->ani_function &= ~ATH9K_ANI_MRC_CCK; | ||
422 | |||
423 | if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) | ||
424 | ah->tx_trig_level = (AR_FTRIG_256B >> AR_FTRIG_S); | ||
425 | else | ||
426 | ah->tx_trig_level = (AR_FTRIG_512B >> AR_FTRIG_S); | ||
447 | } | 427 | } |
448 | 428 | ||
449 | static int ath9k_hw_init_macaddr(struct ath_hw *ah) | 429 | static int ath9k_hw_init_macaddr(struct ath_hw *ah) |
@@ -525,6 +505,31 @@ static int __ath9k_hw_init(struct ath_hw *ah) | |||
525 | 505 | ||
526 | ath9k_hw_read_revisions(ah); | 506 | ath9k_hw_read_revisions(ah); |
527 | 507 | ||
508 | switch (ah->hw_version.macVersion) { | ||
509 | case AR_SREV_VERSION_5416_PCI: | ||
510 | case AR_SREV_VERSION_5416_PCIE: | ||
511 | case AR_SREV_VERSION_9160: | ||
512 | case AR_SREV_VERSION_9100: | ||
513 | case AR_SREV_VERSION_9280: | ||
514 | case AR_SREV_VERSION_9285: | ||
515 | case AR_SREV_VERSION_9287: | ||
516 | case AR_SREV_VERSION_9271: | ||
517 | case AR_SREV_VERSION_9300: | ||
518 | case AR_SREV_VERSION_9330: | ||
519 | case AR_SREV_VERSION_9485: | ||
520 | case AR_SREV_VERSION_9340: | ||
521 | case AR_SREV_VERSION_9462: | ||
522 | case AR_SREV_VERSION_9550: | ||
523 | case AR_SREV_VERSION_9565: | ||
524 | case AR_SREV_VERSION_9531: | ||
525 | break; | ||
526 | default: | ||
527 | ath_err(common, | ||
528 | "Mac Chip Rev 0x%02x.%x is not supported by this driver\n", | ||
529 | ah->hw_version.macVersion, ah->hw_version.macRev); | ||
530 | return -EOPNOTSUPP; | ||
531 | } | ||
532 | |||
528 | /* | 533 | /* |
529 | * Read back AR_WA into a permanent copy and set bits 14 and 17. | 534 | * Read back AR_WA into a permanent copy and set bits 14 and 17. |
530 | * We need to do this to avoid RMW of this register. We cannot | 535 | * We need to do this to avoid RMW of this register. We cannot |
@@ -558,50 +563,6 @@ static int __ath9k_hw_init(struct ath_hw *ah) | |||
558 | return -EIO; | 563 | return -EIO; |
559 | } | 564 | } |
560 | 565 | ||
561 | if (NR_CPUS > 1 && ah->config.serialize_regmode == SER_REG_MODE_AUTO) { | ||
562 | if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI || | ||
563 | ((AR_SREV_9160(ah) || AR_SREV_9280(ah) || AR_SREV_9287(ah)) && | ||
564 | !ah->is_pciexpress)) { | ||
565 | ah->config.serialize_regmode = | ||
566 | SER_REG_MODE_ON; | ||
567 | } else { | ||
568 | ah->config.serialize_regmode = | ||
569 | SER_REG_MODE_OFF; | ||
570 | } | ||
571 | } | ||
572 | |||
573 | ath_dbg(common, RESET, "serialize_regmode is %d\n", | ||
574 | ah->config.serialize_regmode); | ||
575 | |||
576 | if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) | ||
577 | ah->config.max_txtrig_level = MAX_TX_FIFO_THRESHOLD >> 1; | ||
578 | else | ||
579 | ah->config.max_txtrig_level = MAX_TX_FIFO_THRESHOLD; | ||
580 | |||
581 | switch (ah->hw_version.macVersion) { | ||
582 | case AR_SREV_VERSION_5416_PCI: | ||
583 | case AR_SREV_VERSION_5416_PCIE: | ||
584 | case AR_SREV_VERSION_9160: | ||
585 | case AR_SREV_VERSION_9100: | ||
586 | case AR_SREV_VERSION_9280: | ||
587 | case AR_SREV_VERSION_9285: | ||
588 | case AR_SREV_VERSION_9287: | ||
589 | case AR_SREV_VERSION_9271: | ||
590 | case AR_SREV_VERSION_9300: | ||
591 | case AR_SREV_VERSION_9330: | ||
592 | case AR_SREV_VERSION_9485: | ||
593 | case AR_SREV_VERSION_9340: | ||
594 | case AR_SREV_VERSION_9462: | ||
595 | case AR_SREV_VERSION_9550: | ||
596 | case AR_SREV_VERSION_9565: | ||
597 | break; | ||
598 | default: | ||
599 | ath_err(common, | ||
600 | "Mac Chip Rev 0x%02x.%x is not supported by this driver\n", | ||
601 | ah->hw_version.macVersion, ah->hw_version.macRev); | ||
602 | return -EOPNOTSUPP; | ||
603 | } | ||
604 | |||
605 | if (AR_SREV_9271(ah) || AR_SREV_9100(ah) || AR_SREV_9340(ah) || | 566 | if (AR_SREV_9271(ah) || AR_SREV_9100(ah) || AR_SREV_9340(ah) || |
606 | AR_SREV_9330(ah) || AR_SREV_9550(ah)) | 567 | AR_SREV_9330(ah) || AR_SREV_9550(ah)) |
607 | ah->is_pciexpress = false; | 568 | ah->is_pciexpress = false; |
@@ -609,10 +570,6 @@ static int __ath9k_hw_init(struct ath_hw *ah) | |||
609 | ah->hw_version.phyRev = REG_READ(ah, AR_PHY_CHIP_ID); | 570 | ah->hw_version.phyRev = REG_READ(ah, AR_PHY_CHIP_ID); |
610 | ath9k_hw_init_cal_settings(ah); | 571 | ath9k_hw_init_cal_settings(ah); |
611 | 572 | ||
612 | ah->ani_function = ATH9K_ANI_ALL; | ||
613 | if (!AR_SREV_9300_20_OR_LATER(ah)) | ||
614 | ah->ani_function &= ~ATH9K_ANI_MRC_CCK; | ||
615 | |||
616 | if (!ah->is_pciexpress) | 573 | if (!ah->is_pciexpress) |
617 | ath9k_hw_disablepcie(ah); | 574 | ath9k_hw_disablepcie(ah); |
618 | 575 | ||
@@ -631,15 +588,7 @@ static int __ath9k_hw_init(struct ath_hw *ah) | |||
631 | return r; | 588 | return r; |
632 | } | 589 | } |
633 | 590 | ||
634 | if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) | 591 | ath9k_hw_init_hang_checks(ah); |
635 | ah->tx_trig_level = (AR_FTRIG_256B >> AR_FTRIG_S); | ||
636 | else | ||
637 | ah->tx_trig_level = (AR_FTRIG_512B >> AR_FTRIG_S); | ||
638 | |||
639 | if (AR_SREV_9330(ah)) | ||
640 | ah->bb_watchdog_timeout_ms = 85; | ||
641 | else | ||
642 | ah->bb_watchdog_timeout_ms = 25; | ||
643 | 592 | ||
644 | common->state = ATH_HW_INITIALIZED; | 593 | common->state = ATH_HW_INITIALIZED; |
645 | 594 | ||
@@ -672,6 +621,7 @@ int ath9k_hw_init(struct ath_hw *ah) | |||
672 | case AR9300_DEVID_AR9462: | 621 | case AR9300_DEVID_AR9462: |
673 | case AR9485_DEVID_AR1111: | 622 | case AR9485_DEVID_AR1111: |
674 | case AR9300_DEVID_AR9565: | 623 | case AR9300_DEVID_AR9565: |
624 | case AR9300_DEVID_AR953X: | ||
675 | break; | 625 | break; |
676 | default: | 626 | default: |
677 | if (common->bus_ops->ath_bus_type == ATH_USB) | 627 | if (common->bus_ops->ath_bus_type == ATH_USB) |
@@ -807,7 +757,7 @@ static void ath9k_hw_init_pll(struct ath_hw *ah, | |||
807 | /* program BB PLL phase_shift */ | 757 | /* program BB PLL phase_shift */ |
808 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL3, | 758 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL3, |
809 | AR_CH0_BB_DPLL3_PHASE_SHIFT, 0x1); | 759 | AR_CH0_BB_DPLL3_PHASE_SHIFT, 0x1); |
810 | } else if (AR_SREV_9340(ah) || AR_SREV_9550(ah)) { | 760 | } else if (AR_SREV_9340(ah) || AR_SREV_9550(ah) || AR_SREV_9531(ah)) { |
811 | u32 regval, pll2_divint, pll2_divfrac, refdiv; | 761 | u32 regval, pll2_divint, pll2_divfrac, refdiv; |
812 | 762 | ||
813 | REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x1142c); | 763 | REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x1142c); |
@@ -817,9 +767,15 @@ static void ath9k_hw_init_pll(struct ath_hw *ah, | |||
817 | udelay(100); | 767 | udelay(100); |
818 | 768 | ||
819 | if (ah->is_clk_25mhz) { | 769 | if (ah->is_clk_25mhz) { |
820 | pll2_divint = 0x54; | 770 | if (AR_SREV_9531(ah)) { |
821 | pll2_divfrac = 0x1eb85; | 771 | pll2_divint = 0x1c; |
822 | refdiv = 3; | 772 | pll2_divfrac = 0xa3d2; |
773 | refdiv = 1; | ||
774 | } else { | ||
775 | pll2_divint = 0x54; | ||
776 | pll2_divfrac = 0x1eb85; | ||
777 | refdiv = 3; | ||
778 | } | ||
823 | } else { | 779 | } else { |
824 | if (AR_SREV_9340(ah)) { | 780 | if (AR_SREV_9340(ah)) { |
825 | pll2_divint = 88; | 781 | pll2_divint = 88; |
@@ -833,7 +789,10 @@ static void ath9k_hw_init_pll(struct ath_hw *ah, | |||
833 | } | 789 | } |
834 | 790 | ||
835 | regval = REG_READ(ah, AR_PHY_PLL_MODE); | 791 | regval = REG_READ(ah, AR_PHY_PLL_MODE); |
836 | regval |= (0x1 << 16); | 792 | if (AR_SREV_9531(ah)) |
793 | regval |= (0x1 << 22); | ||
794 | else | ||
795 | regval |= (0x1 << 16); | ||
837 | REG_WRITE(ah, AR_PHY_PLL_MODE, regval); | 796 | REG_WRITE(ah, AR_PHY_PLL_MODE, regval); |
838 | udelay(100); | 797 | udelay(100); |
839 | 798 | ||
@@ -843,14 +802,33 @@ static void ath9k_hw_init_pll(struct ath_hw *ah, | |||
843 | 802 | ||
844 | regval = REG_READ(ah, AR_PHY_PLL_MODE); | 803 | regval = REG_READ(ah, AR_PHY_PLL_MODE); |
845 | if (AR_SREV_9340(ah)) | 804 | if (AR_SREV_9340(ah)) |
846 | regval = (regval & 0x80071fff) | (0x1 << 30) | | 805 | regval = (regval & 0x80071fff) | |
847 | (0x1 << 13) | (0x4 << 26) | (0x18 << 19); | 806 | (0x1 << 30) | |
807 | (0x1 << 13) | | ||
808 | (0x4 << 26) | | ||
809 | (0x18 << 19); | ||
810 | else if (AR_SREV_9531(ah)) | ||
811 | regval = (regval & 0x01c00fff) | | ||
812 | (0x1 << 31) | | ||
813 | (0x2 << 29) | | ||
814 | (0xa << 25) | | ||
815 | (0x1 << 19) | | ||
816 | (0x6 << 12); | ||
848 | else | 817 | else |
849 | regval = (regval & 0x80071fff) | (0x3 << 30) | | 818 | regval = (regval & 0x80071fff) | |
850 | (0x1 << 13) | (0x4 << 26) | (0x60 << 19); | 819 | (0x3 << 30) | |
820 | (0x1 << 13) | | ||
821 | (0x4 << 26) | | ||
822 | (0x60 << 19); | ||
851 | REG_WRITE(ah, AR_PHY_PLL_MODE, regval); | 823 | REG_WRITE(ah, AR_PHY_PLL_MODE, regval); |
852 | REG_WRITE(ah, AR_PHY_PLL_MODE, | 824 | |
853 | REG_READ(ah, AR_PHY_PLL_MODE) & 0xfffeffff); | 825 | if (AR_SREV_9531(ah)) |
826 | REG_WRITE(ah, AR_PHY_PLL_MODE, | ||
827 | REG_READ(ah, AR_PHY_PLL_MODE) & 0xffbfffff); | ||
828 | else | ||
829 | REG_WRITE(ah, AR_PHY_PLL_MODE, | ||
830 | REG_READ(ah, AR_PHY_PLL_MODE) & 0xfffeffff); | ||
831 | |||
854 | udelay(1000); | 832 | udelay(1000); |
855 | } | 833 | } |
856 | 834 | ||
@@ -1532,76 +1510,6 @@ static void ath9k_hw_apply_gpio_override(struct ath_hw *ah) | |||
1532 | } | 1510 | } |
1533 | } | 1511 | } |
1534 | 1512 | ||
1535 | static bool ath9k_hw_check_dcs(u32 dma_dbg, u32 num_dcu_states, | ||
1536 | int *hang_state, int *hang_pos) | ||
1537 | { | ||
1538 | static u32 dcu_chain_state[] = {5, 6, 9}; /* DCU chain stuck states */ | ||
1539 | u32 chain_state, dcs_pos, i; | ||
1540 | |||
1541 | for (dcs_pos = 0; dcs_pos < num_dcu_states; dcs_pos++) { | ||
1542 | chain_state = (dma_dbg >> (5 * dcs_pos)) & 0x1f; | ||
1543 | for (i = 0; i < 3; i++) { | ||
1544 | if (chain_state == dcu_chain_state[i]) { | ||
1545 | *hang_state = chain_state; | ||
1546 | *hang_pos = dcs_pos; | ||
1547 | return true; | ||
1548 | } | ||
1549 | } | ||
1550 | } | ||
1551 | return false; | ||
1552 | } | ||
1553 | |||
1554 | #define DCU_COMPLETE_STATE 1 | ||
1555 | #define DCU_COMPLETE_STATE_MASK 0x3 | ||
1556 | #define NUM_STATUS_READS 50 | ||
1557 | static bool ath9k_hw_detect_mac_hang(struct ath_hw *ah) | ||
1558 | { | ||
1559 | u32 chain_state, comp_state, dcs_reg = AR_DMADBG_4; | ||
1560 | u32 i, hang_pos, hang_state, num_state = 6; | ||
1561 | |||
1562 | comp_state = REG_READ(ah, AR_DMADBG_6); | ||
1563 | |||
1564 | if ((comp_state & DCU_COMPLETE_STATE_MASK) != DCU_COMPLETE_STATE) { | ||
1565 | ath_dbg(ath9k_hw_common(ah), RESET, | ||
1566 | "MAC Hang signature not found at DCU complete\n"); | ||
1567 | return false; | ||
1568 | } | ||
1569 | |||
1570 | chain_state = REG_READ(ah, dcs_reg); | ||
1571 | if (ath9k_hw_check_dcs(chain_state, num_state, &hang_state, &hang_pos)) | ||
1572 | goto hang_check_iter; | ||
1573 | |||
1574 | dcs_reg = AR_DMADBG_5; | ||
1575 | num_state = 4; | ||
1576 | chain_state = REG_READ(ah, dcs_reg); | ||
1577 | if (ath9k_hw_check_dcs(chain_state, num_state, &hang_state, &hang_pos)) | ||
1578 | goto hang_check_iter; | ||
1579 | |||
1580 | ath_dbg(ath9k_hw_common(ah), RESET, | ||
1581 | "MAC Hang signature 1 not found\n"); | ||
1582 | return false; | ||
1583 | |||
1584 | hang_check_iter: | ||
1585 | ath_dbg(ath9k_hw_common(ah), RESET, | ||
1586 | "DCU registers: chain %08x complete %08x Hang: state %d pos %d\n", | ||
1587 | chain_state, comp_state, hang_state, hang_pos); | ||
1588 | |||
1589 | for (i = 0; i < NUM_STATUS_READS; i++) { | ||
1590 | chain_state = REG_READ(ah, dcs_reg); | ||
1591 | chain_state = (chain_state >> (5 * hang_pos)) & 0x1f; | ||
1592 | comp_state = REG_READ(ah, AR_DMADBG_6); | ||
1593 | |||
1594 | if (((comp_state & DCU_COMPLETE_STATE_MASK) != | ||
1595 | DCU_COMPLETE_STATE) || | ||
1596 | (chain_state != hang_state)) | ||
1597 | return false; | ||
1598 | } | ||
1599 | |||
1600 | ath_dbg(ath9k_hw_common(ah), RESET, "MAC Hang signature 1 found\n"); | ||
1601 | |||
1602 | return true; | ||
1603 | } | ||
1604 | |||
1605 | void ath9k_hw_check_nav(struct ath_hw *ah) | 1513 | void ath9k_hw_check_nav(struct ath_hw *ah) |
1606 | { | 1514 | { |
1607 | struct ath_common *common = ath9k_hw_common(ah); | 1515 | struct ath_common *common = ath9k_hw_common(ah); |
@@ -1676,7 +1584,6 @@ static void ath9k_hw_reset_opmode(struct ath_hw *ah, | |||
1676 | 1584 | ||
1677 | REG_RMW(ah, AR_STA_ID1, macStaId1 | 1585 | REG_RMW(ah, AR_STA_ID1, macStaId1 |
1678 | | AR_STA_ID1_RTS_USE_DEF | 1586 | | AR_STA_ID1_RTS_USE_DEF |
1679 | | (ah->config.ack_6mb ? AR_STA_ID1_ACKCTS_6MB : 0) | ||
1680 | | ah->sta_id1_defaults, | 1587 | | ah->sta_id1_defaults, |
1681 | ~AR_STA_ID1_SADH_MASK); | 1588 | ~AR_STA_ID1_SADH_MASK); |
1682 | ath_hw_setbssidmask(common); | 1589 | ath_hw_setbssidmask(common); |
@@ -1735,7 +1642,7 @@ static void ath9k_hw_init_desc(struct ath_hw *ah) | |||
1735 | } | 1642 | } |
1736 | #ifdef __BIG_ENDIAN | 1643 | #ifdef __BIG_ENDIAN |
1737 | else if (AR_SREV_9330(ah) || AR_SREV_9340(ah) || | 1644 | else if (AR_SREV_9330(ah) || AR_SREV_9340(ah) || |
1738 | AR_SREV_9550(ah)) | 1645 | AR_SREV_9550(ah) || AR_SREV_9531(ah)) |
1739 | REG_RMW(ah, AR_CFG, AR_CFG_SWRB | AR_CFG_SWTB, 0); | 1646 | REG_RMW(ah, AR_CFG, AR_CFG_SWRB | AR_CFG_SWTB, 0); |
1740 | else | 1647 | else |
1741 | REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD); | 1648 | REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD); |
@@ -1865,7 +1772,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
1865 | /* Save TSF before chip reset, a cold reset clears it */ | 1772 | /* Save TSF before chip reset, a cold reset clears it */ |
1866 | tsf = ath9k_hw_gettsf64(ah); | 1773 | tsf = ath9k_hw_gettsf64(ah); |
1867 | getrawmonotonic(&ts); | 1774 | getrawmonotonic(&ts); |
1868 | usec = ts.tv_sec * 1000 + ts.tv_nsec / 1000; | 1775 | usec = ts.tv_sec * 1000000ULL + ts.tv_nsec / 1000; |
1869 | 1776 | ||
1870 | saveLedState = REG_READ(ah, AR_CFG_LED) & | 1777 | saveLedState = REG_READ(ah, AR_CFG_LED) & |
1871 | (AR_CFG_LED_ASSOC_CTL | AR_CFG_LED_MODE_SEL | | 1778 | (AR_CFG_LED_ASSOC_CTL | AR_CFG_LED_MODE_SEL | |
@@ -1899,7 +1806,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
1899 | 1806 | ||
1900 | /* Restore TSF */ | 1807 | /* Restore TSF */ |
1901 | getrawmonotonic(&ts); | 1808 | getrawmonotonic(&ts); |
1902 | usec = ts.tv_sec * 1000 + ts.tv_nsec / 1000 - usec; | 1809 | usec = ts.tv_sec * 1000000ULL + ts.tv_nsec / 1000 - usec; |
1903 | ath9k_hw_settsf64(ah, tsf + usec); | 1810 | ath9k_hw_settsf64(ah, tsf + usec); |
1904 | 1811 | ||
1905 | if (AR_SREV_9280_20_OR_LATER(ah)) | 1812 | if (AR_SREV_9280_20_OR_LATER(ah)) |
@@ -2008,10 +1915,11 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
2008 | ath9k_hw_loadnf(ah, chan); | 1915 | ath9k_hw_loadnf(ah, chan); |
2009 | ath9k_hw_start_nfcal(ah, true); | 1916 | ath9k_hw_start_nfcal(ah, true); |
2010 | 1917 | ||
2011 | if (AR_SREV_9300_20_OR_LATER(ah)) { | 1918 | if (AR_SREV_9300_20_OR_LATER(ah)) |
2012 | ar9003_hw_bb_watchdog_config(ah); | 1919 | ar9003_hw_bb_watchdog_config(ah); |
1920 | |||
1921 | if (ah->config.hw_hang_checks & HW_PHYRESTART_CLC_WAR) | ||
2013 | ar9003_hw_disable_phy_restart(ah); | 1922 | ar9003_hw_disable_phy_restart(ah); |
2014 | } | ||
2015 | 1923 | ||
2016 | ath9k_hw_apply_gpio_override(ah); | 1924 | ath9k_hw_apply_gpio_override(ah); |
2017 | 1925 | ||
@@ -2135,7 +2043,11 @@ static bool ath9k_hw_set_power_awake(struct ath_hw *ah) | |||
2135 | 2043 | ||
2136 | REG_SET_BIT(ah, AR_RTC_FORCE_WAKE, | 2044 | REG_SET_BIT(ah, AR_RTC_FORCE_WAKE, |
2137 | AR_RTC_FORCE_WAKE_EN); | 2045 | AR_RTC_FORCE_WAKE_EN); |
2138 | udelay(50); | 2046 | |
2047 | if (AR_SREV_9100(ah)) | ||
2048 | udelay(10000); | ||
2049 | else | ||
2050 | udelay(50); | ||
2139 | 2051 | ||
2140 | for (i = POWER_UP_TIME / 50; i > 0; i--) { | 2052 | for (i = POWER_UP_TIME / 50; i > 0; i--) { |
2141 | val = REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M; | 2053 | val = REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M; |
@@ -2564,13 +2476,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) | |||
2564 | ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) | 2476 | ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) |
2565 | pCap->hw_caps |= ATH9K_HW_CAP_PAPRD; | 2477 | pCap->hw_caps |= ATH9K_HW_CAP_PAPRD; |
2566 | 2478 | ||
2567 | /* | ||
2568 | * Fast channel change across bands is available | ||
2569 | * only for AR9462 and AR9565. | ||
2570 | */ | ||
2571 | if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) | ||
2572 | pCap->hw_caps |= ATH9K_HW_CAP_FCC_BAND_SWITCH; | ||
2573 | |||
2574 | return 0; | 2479 | return 0; |
2575 | } | 2480 | } |
2576 | 2481 | ||
@@ -3084,14 +2989,14 @@ void ath_gen_timer_isr(struct ath_hw *ah) | |||
3084 | trigger_mask &= timer_table->timer_mask; | 2989 | trigger_mask &= timer_table->timer_mask; |
3085 | thresh_mask &= timer_table->timer_mask; | 2990 | thresh_mask &= timer_table->timer_mask; |
3086 | 2991 | ||
3087 | trigger_mask &= ~thresh_mask; | ||
3088 | |||
3089 | for_each_set_bit(index, &thresh_mask, ARRAY_SIZE(timer_table->timers)) { | 2992 | for_each_set_bit(index, &thresh_mask, ARRAY_SIZE(timer_table->timers)) { |
3090 | timer = timer_table->timers[index]; | 2993 | timer = timer_table->timers[index]; |
3091 | if (!timer) | 2994 | if (!timer) |
3092 | continue; | 2995 | continue; |
3093 | if (!timer->overflow) | 2996 | if (!timer->overflow) |
3094 | continue; | 2997 | continue; |
2998 | |||
2999 | trigger_mask &= ~BIT(index); | ||
3095 | timer->overflow(timer->arg); | 3000 | timer->overflow(timer->arg); |
3096 | } | 3001 | } |
3097 | 3002 | ||
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 6132ffeb3048..e766399bdcda 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h | |||
@@ -52,6 +52,7 @@ | |||
52 | #define AR9300_DEVID_QCA955X 0x0038 | 52 | #define AR9300_DEVID_QCA955X 0x0038 |
53 | #define AR9485_DEVID_AR1111 0x0037 | 53 | #define AR9485_DEVID_AR1111 0x0037 |
54 | #define AR9300_DEVID_AR9565 0x0036 | 54 | #define AR9300_DEVID_AR9565 0x0036 |
55 | #define AR9300_DEVID_AR953X 0x003d | ||
55 | 56 | ||
56 | #define AR5416_AR9100_DEVID 0x000b | 57 | #define AR5416_AR9100_DEVID 0x000b |
57 | 58 | ||
@@ -277,10 +278,24 @@ struct ath9k_hw_capabilities { | |||
277 | u8 txs_len; | 278 | u8 txs_len; |
278 | }; | 279 | }; |
279 | 280 | ||
281 | #define AR_NO_SPUR 0x8000 | ||
282 | #define AR_BASE_FREQ_2GHZ 2300 | ||
283 | #define AR_BASE_FREQ_5GHZ 4900 | ||
284 | #define AR_SPUR_FEEQ_BOUND_HT40 19 | ||
285 | #define AR_SPUR_FEEQ_BOUND_HT20 10 | ||
286 | |||
287 | enum ath9k_hw_hang_checks { | ||
288 | HW_BB_WATCHDOG = BIT(0), | ||
289 | HW_PHYRESTART_CLC_WAR = BIT(1), | ||
290 | HW_BB_RIFS_HANG = BIT(2), | ||
291 | HW_BB_DFS_HANG = BIT(3), | ||
292 | HW_BB_RX_CLEAR_STUCK_HANG = BIT(4), | ||
293 | HW_MAC_HANG = BIT(5), | ||
294 | }; | ||
295 | |||
280 | struct ath9k_ops_config { | 296 | struct ath9k_ops_config { |
281 | int dma_beacon_response_time; | 297 | int dma_beacon_response_time; |
282 | int sw_beacon_response_time; | 298 | int sw_beacon_response_time; |
283 | int ack_6mb; | ||
284 | u32 cwm_ignore_extcca; | 299 | u32 cwm_ignore_extcca; |
285 | u32 pcie_waen; | 300 | u32 pcie_waen; |
286 | u8 analog_shiftreg; | 301 | u8 analog_shiftreg; |
@@ -292,13 +307,9 @@ struct ath9k_ops_config { | |||
292 | int serialize_regmode; | 307 | int serialize_regmode; |
293 | bool rx_intr_mitigation; | 308 | bool rx_intr_mitigation; |
294 | bool tx_intr_mitigation; | 309 | bool tx_intr_mitigation; |
295 | #define AR_NO_SPUR 0x8000 | ||
296 | #define AR_BASE_FREQ_2GHZ 2300 | ||
297 | #define AR_BASE_FREQ_5GHZ 4900 | ||
298 | #define AR_SPUR_FEEQ_BOUND_HT40 19 | ||
299 | #define AR_SPUR_FEEQ_BOUND_HT20 10 | ||
300 | u8 max_txtrig_level; | 310 | u8 max_txtrig_level; |
301 | u16 ani_poll_interval; /* ANI poll interval in ms */ | 311 | u16 ani_poll_interval; /* ANI poll interval in ms */ |
312 | u16 hw_hang_checks; | ||
302 | 313 | ||
303 | /* Platform specific config */ | 314 | /* Platform specific config */ |
304 | u32 aspm_l1_fix; | 315 | u32 aspm_l1_fix; |
@@ -573,6 +584,10 @@ struct ath_hw_radar_conf { | |||
573 | * register settings through the register initialization. | 584 | * register settings through the register initialization. |
574 | */ | 585 | */ |
575 | struct ath_hw_private_ops { | 586 | struct ath_hw_private_ops { |
587 | void (*init_hang_checks)(struct ath_hw *ah); | ||
588 | bool (*detect_mac_hang)(struct ath_hw *ah); | ||
589 | bool (*detect_bb_hang)(struct ath_hw *ah); | ||
590 | |||
576 | /* Calibration ops */ | 591 | /* Calibration ops */ |
577 | void (*init_cal_settings)(struct ath_hw *ah); | 592 | void (*init_cal_settings)(struct ath_hw *ah); |
578 | bool (*init_cal)(struct ath_hw *ah, struct ath9k_channel *chan); | 593 | bool (*init_cal)(struct ath_hw *ah, struct ath9k_channel *chan); |
@@ -1029,6 +1044,7 @@ void ar9002_hw_enable_async_fifo(struct ath_hw *ah); | |||
1029 | * Code specific to AR9003, we stuff these here to avoid callbacks | 1044 | * Code specific to AR9003, we stuff these here to avoid callbacks |
1030 | * for older families | 1045 | * for older families |
1031 | */ | 1046 | */ |
1047 | bool ar9003_hw_bb_watchdog_check(struct ath_hw *ah); | ||
1032 | void ar9003_hw_bb_watchdog_config(struct ath_hw *ah); | 1048 | void ar9003_hw_bb_watchdog_config(struct ath_hw *ah); |
1033 | void ar9003_hw_bb_watchdog_read(struct ath_hw *ah); | 1049 | void ar9003_hw_bb_watchdog_read(struct ath_hw *ah); |
1034 | void ar9003_hw_bb_watchdog_dbg_info(struct ath_hw *ah); | 1050 | void ar9003_hw_bb_watchdog_dbg_info(struct ath_hw *ah); |
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index e63465b7eab9..f2a17fcf1ae4 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c | |||
@@ -763,10 +763,8 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, | |||
763 | 763 | ||
764 | setup_timer(&sc->sleep_timer, ath_ps_full_sleep, (unsigned long)sc); | 764 | setup_timer(&sc->sleep_timer, ath_ps_full_sleep, (unsigned long)sc); |
765 | INIT_WORK(&sc->hw_reset_work, ath_reset_work); | 765 | INIT_WORK(&sc->hw_reset_work, ath_reset_work); |
766 | INIT_WORK(&sc->hw_check_work, ath_hw_check); | ||
767 | INIT_WORK(&sc->paprd_work, ath_paprd_calibrate); | 766 | INIT_WORK(&sc->paprd_work, ath_paprd_calibrate); |
768 | INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work); | 767 | INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work); |
769 | setup_timer(&sc->rx_poll_timer, ath_rx_poll, (unsigned long)sc); | ||
770 | 768 | ||
771 | /* | 769 | /* |
772 | * Cache line size is used to size and align various | 770 | * Cache line size is used to size and align various |
diff --git a/drivers/net/wireless/ath/ath9k/link.c b/drivers/net/wireless/ath/ath9k/link.c index aed7e29dc50f..30dcef5aba10 100644 --- a/drivers/net/wireless/ath/ath9k/link.c +++ b/drivers/net/wireless/ath/ath9k/link.c | |||
@@ -65,50 +65,26 @@ void ath_tx_complete_poll_work(struct work_struct *work) | |||
65 | /* | 65 | /* |
66 | * Checks if the BB/MAC is hung. | 66 | * Checks if the BB/MAC is hung. |
67 | */ | 67 | */ |
68 | void ath_hw_check(struct work_struct *work) | 68 | bool ath_hw_check(struct ath_softc *sc) |
69 | { | 69 | { |
70 | struct ath_softc *sc = container_of(work, struct ath_softc, hw_check_work); | ||
71 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 70 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
72 | unsigned long flags; | ||
73 | int busy; | ||
74 | u8 is_alive, nbeacon = 1; | ||
75 | enum ath_reset_type type; | 71 | enum ath_reset_type type; |
72 | bool is_alive; | ||
76 | 73 | ||
77 | ath9k_ps_wakeup(sc); | 74 | ath9k_ps_wakeup(sc); |
75 | |||
78 | is_alive = ath9k_hw_check_alive(sc->sc_ah); | 76 | is_alive = ath9k_hw_check_alive(sc->sc_ah); |
79 | 77 | ||
80 | if ((is_alive && !AR_SREV_9300(sc->sc_ah)) || sc->tx99_state) | 78 | if (!is_alive) { |
81 | goto out; | ||
82 | else if (!is_alive && AR_SREV_9300(sc->sc_ah)) { | ||
83 | ath_dbg(common, RESET, | 79 | ath_dbg(common, RESET, |
84 | "DCU stuck is detected. Schedule chip reset\n"); | 80 | "HW hang detected, schedule chip reset\n"); |
85 | type = RESET_TYPE_MAC_HANG; | 81 | type = RESET_TYPE_MAC_HANG; |
86 | goto sched_reset; | 82 | ath9k_queue_reset(sc, type); |
87 | } | ||
88 | |||
89 | spin_lock_irqsave(&common->cc_lock, flags); | ||
90 | busy = ath_update_survey_stats(sc); | ||
91 | spin_unlock_irqrestore(&common->cc_lock, flags); | ||
92 | |||
93 | ath_dbg(common, RESET, "Possible baseband hang, busy=%d (try %d)\n", | ||
94 | busy, sc->hw_busy_count + 1); | ||
95 | if (busy >= 99) { | ||
96 | if (++sc->hw_busy_count >= 3) { | ||
97 | type = RESET_TYPE_BB_HANG; | ||
98 | goto sched_reset; | ||
99 | } | ||
100 | } else if (busy >= 0) { | ||
101 | sc->hw_busy_count = 0; | ||
102 | nbeacon = 3; | ||
103 | } | 83 | } |
104 | 84 | ||
105 | ath_start_rx_poll(sc, nbeacon); | ||
106 | goto out; | ||
107 | |||
108 | sched_reset: | ||
109 | ath9k_queue_reset(sc, type); | ||
110 | out: | ||
111 | ath9k_ps_restore(sc); | 85 | ath9k_ps_restore(sc); |
86 | |||
87 | return is_alive; | ||
112 | } | 88 | } |
113 | 89 | ||
114 | /* | 90 | /* |
@@ -162,29 +138,6 @@ void ath_hw_pll_work(struct work_struct *work) | |||
162 | } | 138 | } |
163 | 139 | ||
164 | /* | 140 | /* |
165 | * RX Polling - monitors baseband hangs. | ||
166 | */ | ||
167 | void ath_start_rx_poll(struct ath_softc *sc, u8 nbeacon) | ||
168 | { | ||
169 | if (!AR_SREV_9300(sc->sc_ah)) | ||
170 | return; | ||
171 | |||
172 | if (!test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) | ||
173 | return; | ||
174 | |||
175 | mod_timer(&sc->rx_poll_timer, jiffies + msecs_to_jiffies | ||
176 | (nbeacon * sc->cur_beacon_conf.beacon_interval)); | ||
177 | } | ||
178 | |||
179 | void ath_rx_poll(unsigned long data) | ||
180 | { | ||
181 | struct ath_softc *sc = (struct ath_softc *)data; | ||
182 | |||
183 | if (!test_bit(SC_OP_INVALID, &sc->sc_flags)) | ||
184 | ieee80211_queue_work(sc->hw, &sc->hw_check_work); | ||
185 | } | ||
186 | |||
187 | /* | ||
188 | * PA Pre-distortion. | 141 | * PA Pre-distortion. |
189 | */ | 142 | */ |
190 | static void ath_paprd_activate(struct ath_softc *sc) | 143 | static void ath_paprd_activate(struct ath_softc *sc) |
@@ -409,10 +362,10 @@ void ath_ani_calibrate(unsigned long data) | |||
409 | 362 | ||
410 | /* Call ANI routine if necessary */ | 363 | /* Call ANI routine if necessary */ |
411 | if (aniflag) { | 364 | if (aniflag) { |
412 | spin_lock_irqsave(&common->cc_lock, flags); | 365 | spin_lock(&common->cc_lock); |
413 | ath9k_hw_ani_monitor(ah, ah->curchan); | 366 | ath9k_hw_ani_monitor(ah, ah->curchan); |
414 | ath_update_survey_stats(sc); | 367 | ath_update_survey_stats(sc); |
415 | spin_unlock_irqrestore(&common->cc_lock, flags); | 368 | spin_unlock(&common->cc_lock); |
416 | } | 369 | } |
417 | 370 | ||
418 | /* Perform calibration if necessary */ | 371 | /* Perform calibration if necessary */ |
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index 89d7e206992b..5f727588ca27 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c | |||
@@ -922,11 +922,29 @@ void ath9k_hw_set_interrupts(struct ath_hw *ah) | |||
922 | mask2 |= AR_IMR_S2_CST; | 922 | mask2 |= AR_IMR_S2_CST; |
923 | } | 923 | } |
924 | 924 | ||
925 | if (ah->config.hw_hang_checks & HW_BB_WATCHDOG) { | ||
926 | if (ints & ATH9K_INT_BB_WATCHDOG) { | ||
927 | mask |= AR_IMR_BCNMISC; | ||
928 | mask2 |= AR_IMR_S2_BB_WATCHDOG; | ||
929 | } | ||
930 | } | ||
931 | |||
925 | ath_dbg(common, INTERRUPT, "new IMR 0x%x\n", mask); | 932 | ath_dbg(common, INTERRUPT, "new IMR 0x%x\n", mask); |
926 | REG_WRITE(ah, AR_IMR, mask); | 933 | REG_WRITE(ah, AR_IMR, mask); |
927 | ah->imrs2_reg &= ~(AR_IMR_S2_TIM | AR_IMR_S2_DTIM | AR_IMR_S2_DTIMSYNC | | 934 | ah->imrs2_reg &= ~(AR_IMR_S2_TIM | |
928 | AR_IMR_S2_CABEND | AR_IMR_S2_CABTO | | 935 | AR_IMR_S2_DTIM | |
929 | AR_IMR_S2_TSFOOR | AR_IMR_S2_GTT | AR_IMR_S2_CST); | 936 | AR_IMR_S2_DTIMSYNC | |
937 | AR_IMR_S2_CABEND | | ||
938 | AR_IMR_S2_CABTO | | ||
939 | AR_IMR_S2_TSFOOR | | ||
940 | AR_IMR_S2_GTT | | ||
941 | AR_IMR_S2_CST); | ||
942 | |||
943 | if (ah->config.hw_hang_checks & HW_BB_WATCHDOG) { | ||
944 | if (ints & ATH9K_INT_BB_WATCHDOG) | ||
945 | ah->imrs2_reg &= ~AR_IMR_S2_BB_WATCHDOG; | ||
946 | } | ||
947 | |||
930 | ah->imrs2_reg |= mask2; | 948 | ah->imrs2_reg |= mask2; |
931 | REG_WRITE(ah, AR_IMR_S2, ah->imrs2_reg); | 949 | REG_WRITE(ah, AR_IMR_S2, ah->imrs2_reg); |
932 | 950 | ||
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 21b764ba6400..d0c3aec7c74e 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -170,7 +170,6 @@ void ath9k_ps_restore(struct ath_softc *sc) | |||
170 | static void __ath_cancel_work(struct ath_softc *sc) | 170 | static void __ath_cancel_work(struct ath_softc *sc) |
171 | { | 171 | { |
172 | cancel_work_sync(&sc->paprd_work); | 172 | cancel_work_sync(&sc->paprd_work); |
173 | cancel_work_sync(&sc->hw_check_work); | ||
174 | cancel_delayed_work_sync(&sc->tx_complete_work); | 173 | cancel_delayed_work_sync(&sc->tx_complete_work); |
175 | cancel_delayed_work_sync(&sc->hw_pll_work); | 174 | cancel_delayed_work_sync(&sc->hw_pll_work); |
176 | 175 | ||
@@ -194,7 +193,6 @@ void ath_restart_work(struct ath_softc *sc) | |||
194 | ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, | 193 | ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, |
195 | msecs_to_jiffies(ATH_PLL_WORK_INTERVAL)); | 194 | msecs_to_jiffies(ATH_PLL_WORK_INTERVAL)); |
196 | 195 | ||
197 | ath_start_rx_poll(sc, 3); | ||
198 | ath_start_ani(sc); | 196 | ath_start_ani(sc); |
199 | } | 197 | } |
200 | 198 | ||
@@ -204,11 +202,7 @@ static bool ath_prepare_reset(struct ath_softc *sc) | |||
204 | bool ret = true; | 202 | bool ret = true; |
205 | 203 | ||
206 | ieee80211_stop_queues(sc->hw); | 204 | ieee80211_stop_queues(sc->hw); |
207 | |||
208 | sc->hw_busy_count = 0; | ||
209 | ath_stop_ani(sc); | 205 | ath_stop_ani(sc); |
210 | del_timer_sync(&sc->rx_poll_timer); | ||
211 | |||
212 | ath9k_hw_disable_interrupts(ah); | 206 | ath9k_hw_disable_interrupts(ah); |
213 | 207 | ||
214 | if (!ath_drain_all_txq(sc)) | 208 | if (!ath_drain_all_txq(sc)) |
@@ -336,7 +330,6 @@ static int ath_set_channel(struct ath_softc *sc, struct cfg80211_chan_def *chand | |||
336 | struct ieee80211_hw *hw = sc->hw; | 330 | struct ieee80211_hw *hw = sc->hw; |
337 | struct ath9k_channel *hchan; | 331 | struct ath9k_channel *hchan; |
338 | struct ieee80211_channel *chan = chandef->chan; | 332 | struct ieee80211_channel *chan = chandef->chan; |
339 | unsigned long flags; | ||
340 | bool offchannel; | 333 | bool offchannel; |
341 | int pos = chan->hw_value; | 334 | int pos = chan->hw_value; |
342 | int old_pos = -1; | 335 | int old_pos = -1; |
@@ -354,9 +347,9 @@ static int ath_set_channel(struct ath_softc *sc, struct cfg80211_chan_def *chand | |||
354 | chan->center_freq, chandef->width); | 347 | chan->center_freq, chandef->width); |
355 | 348 | ||
356 | /* update survey stats for the old channel before switching */ | 349 | /* update survey stats for the old channel before switching */ |
357 | spin_lock_irqsave(&common->cc_lock, flags); | 350 | spin_lock_bh(&common->cc_lock); |
358 | ath_update_survey_stats(sc); | 351 | ath_update_survey_stats(sc); |
359 | spin_unlock_irqrestore(&common->cc_lock, flags); | 352 | spin_unlock_bh(&common->cc_lock); |
360 | 353 | ||
361 | ath9k_cmn_get_channel(hw, ah, chandef); | 354 | ath9k_cmn_get_channel(hw, ah, chandef); |
362 | 355 | ||
@@ -427,12 +420,6 @@ static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta, | |||
427 | an->vif = vif; | 420 | an->vif = vif; |
428 | 421 | ||
429 | ath_tx_node_init(sc, an); | 422 | ath_tx_node_init(sc, an); |
430 | |||
431 | if (sta->ht_cap.ht_supported) { | ||
432 | an->maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR + | ||
433 | sta->ht_cap.ampdu_factor); | ||
434 | an->mpdudensity = ath9k_parse_mpdudensity(sta->ht_cap.ampdu_density); | ||
435 | } | ||
436 | } | 423 | } |
437 | 424 | ||
438 | static void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta) | 425 | static void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta) |
@@ -454,14 +441,8 @@ void ath9k_tasklet(unsigned long data) | |||
454 | ath9k_ps_wakeup(sc); | 441 | ath9k_ps_wakeup(sc); |
455 | spin_lock(&sc->sc_pcu_lock); | 442 | spin_lock(&sc->sc_pcu_lock); |
456 | 443 | ||
457 | if ((status & ATH9K_INT_FATAL) || | 444 | if (status & ATH9K_INT_FATAL) { |
458 | (status & ATH9K_INT_BB_WATCHDOG)) { | 445 | type = RESET_TYPE_FATAL_INT; |
459 | |||
460 | if (status & ATH9K_INT_FATAL) | ||
461 | type = RESET_TYPE_FATAL_INT; | ||
462 | else | ||
463 | type = RESET_TYPE_BB_WATCHDOG; | ||
464 | |||
465 | ath9k_queue_reset(sc, type); | 446 | ath9k_queue_reset(sc, type); |
466 | 447 | ||
467 | /* | 448 | /* |
@@ -473,6 +454,28 @@ void ath9k_tasklet(unsigned long data) | |||
473 | goto out; | 454 | goto out; |
474 | } | 455 | } |
475 | 456 | ||
457 | if ((ah->config.hw_hang_checks & HW_BB_WATCHDOG) && | ||
458 | (status & ATH9K_INT_BB_WATCHDOG)) { | ||
459 | spin_lock(&common->cc_lock); | ||
460 | ath_hw_cycle_counters_update(common); | ||
461 | ar9003_hw_bb_watchdog_dbg_info(ah); | ||
462 | spin_unlock(&common->cc_lock); | ||
463 | |||
464 | if (ar9003_hw_bb_watchdog_check(ah)) { | ||
465 | type = RESET_TYPE_BB_WATCHDOG; | ||
466 | ath9k_queue_reset(sc, type); | ||
467 | |||
468 | /* | ||
469 | * Increment the ref. counter here so that | ||
470 | * interrupts are enabled in the reset routine. | ||
471 | */ | ||
472 | atomic_inc(&ah->intr_ref_cnt); | ||
473 | ath_dbg(common, ANY, | ||
474 | "BB_WATCHDOG: Skipping interrupts\n"); | ||
475 | goto out; | ||
476 | } | ||
477 | } | ||
478 | |||
476 | spin_lock_irqsave(&sc->sc_pm_lock, flags); | 479 | spin_lock_irqsave(&sc->sc_pm_lock, flags); |
477 | if ((status & ATH9K_INT_TSFOOR) && sc->ps_enabled) { | 480 | if ((status & ATH9K_INT_TSFOOR) && sc->ps_enabled) { |
478 | /* | 481 | /* |
@@ -541,7 +544,7 @@ irqreturn_t ath_isr(int irq, void *dev) | |||
541 | struct ath_hw *ah = sc->sc_ah; | 544 | struct ath_hw *ah = sc->sc_ah; |
542 | struct ath_common *common = ath9k_hw_common(ah); | 545 | struct ath_common *common = ath9k_hw_common(ah); |
543 | enum ath9k_int status; | 546 | enum ath9k_int status; |
544 | u32 sync_cause; | 547 | u32 sync_cause = 0; |
545 | bool sched = false; | 548 | bool sched = false; |
546 | 549 | ||
547 | /* | 550 | /* |
@@ -593,16 +596,9 @@ irqreturn_t ath_isr(int irq, void *dev) | |||
593 | !(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA))) | 596 | !(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA))) |
594 | goto chip_reset; | 597 | goto chip_reset; |
595 | 598 | ||
596 | if ((ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) && | 599 | if ((ah->config.hw_hang_checks & HW_BB_WATCHDOG) && |
597 | (status & ATH9K_INT_BB_WATCHDOG)) { | 600 | (status & ATH9K_INT_BB_WATCHDOG)) |
598 | |||
599 | spin_lock(&common->cc_lock); | ||
600 | ath_hw_cycle_counters_update(common); | ||
601 | ar9003_hw_bb_watchdog_dbg_info(ah); | ||
602 | spin_unlock(&common->cc_lock); | ||
603 | |||
604 | goto chip_reset; | 601 | goto chip_reset; |
605 | } | ||
606 | 602 | ||
607 | #ifdef CONFIG_ATH9K_WOW | 603 | #ifdef CONFIG_ATH9K_WOW |
608 | if (status & ATH9K_INT_BMISS) { | 604 | if (status & ATH9K_INT_BMISS) { |
@@ -732,11 +728,13 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
732 | 728 | ||
733 | if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) | 729 | if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) |
734 | ah->imask |= ATH9K_INT_RXHP | | 730 | ah->imask |= ATH9K_INT_RXHP | |
735 | ATH9K_INT_RXLP | | 731 | ATH9K_INT_RXLP; |
736 | ATH9K_INT_BB_WATCHDOG; | ||
737 | else | 732 | else |
738 | ah->imask |= ATH9K_INT_RX; | 733 | ah->imask |= ATH9K_INT_RX; |
739 | 734 | ||
735 | if (ah->config.hw_hang_checks & HW_BB_WATCHDOG) | ||
736 | ah->imask |= ATH9K_INT_BB_WATCHDOG; | ||
737 | |||
740 | ah->imask |= ATH9K_INT_GTT; | 738 | ah->imask |= ATH9K_INT_GTT; |
741 | 739 | ||
742 | if (ah->caps.hw_caps & ATH9K_HW_CAP_HT) | 740 | if (ah->caps.hw_caps & ATH9K_HW_CAP_HT) |
@@ -860,7 +858,6 @@ static void ath9k_stop(struct ieee80211_hw *hw) | |||
860 | mutex_lock(&sc->mutex); | 858 | mutex_lock(&sc->mutex); |
861 | 859 | ||
862 | ath_cancel_work(sc); | 860 | ath_cancel_work(sc); |
863 | del_timer_sync(&sc->rx_poll_timer); | ||
864 | 861 | ||
865 | if (test_bit(SC_OP_INVALID, &sc->sc_flags)) { | 862 | if (test_bit(SC_OP_INVALID, &sc->sc_flags)) { |
866 | ath_dbg(common, ANY, "Device not present\n"); | 863 | ath_dbg(common, ANY, "Device not present\n"); |
@@ -1791,13 +1788,12 @@ static int ath9k_get_survey(struct ieee80211_hw *hw, int idx, | |||
1791 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 1788 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
1792 | struct ieee80211_supported_band *sband; | 1789 | struct ieee80211_supported_band *sband; |
1793 | struct ieee80211_channel *chan; | 1790 | struct ieee80211_channel *chan; |
1794 | unsigned long flags; | ||
1795 | int pos; | 1791 | int pos; |
1796 | 1792 | ||
1797 | if (config_enabled(CONFIG_ATH9K_TX99)) | 1793 | if (config_enabled(CONFIG_ATH9K_TX99)) |
1798 | return -EOPNOTSUPP; | 1794 | return -EOPNOTSUPP; |
1799 | 1795 | ||
1800 | spin_lock_irqsave(&common->cc_lock, flags); | 1796 | spin_lock_bh(&common->cc_lock); |
1801 | if (idx == 0) | 1797 | if (idx == 0) |
1802 | ath_update_survey_stats(sc); | 1798 | ath_update_survey_stats(sc); |
1803 | 1799 | ||
@@ -1811,7 +1807,7 @@ static int ath9k_get_survey(struct ieee80211_hw *hw, int idx, | |||
1811 | sband = hw->wiphy->bands[IEEE80211_BAND_5GHZ]; | 1807 | sband = hw->wiphy->bands[IEEE80211_BAND_5GHZ]; |
1812 | 1808 | ||
1813 | if (!sband || idx >= sband->n_channels) { | 1809 | if (!sband || idx >= sband->n_channels) { |
1814 | spin_unlock_irqrestore(&common->cc_lock, flags); | 1810 | spin_unlock_bh(&common->cc_lock); |
1815 | return -ENOENT; | 1811 | return -ENOENT; |
1816 | } | 1812 | } |
1817 | 1813 | ||
@@ -1819,7 +1815,7 @@ static int ath9k_get_survey(struct ieee80211_hw *hw, int idx, | |||
1819 | pos = chan->hw_value; | 1815 | pos = chan->hw_value; |
1820 | memcpy(survey, &sc->survey[pos], sizeof(*survey)); | 1816 | memcpy(survey, &sc->survey[pos], sizeof(*survey)); |
1821 | survey->channel = chan; | 1817 | survey->channel = chan; |
1822 | spin_unlock_irqrestore(&common->cc_lock, flags); | 1818 | spin_unlock_bh(&common->cc_lock); |
1823 | 1819 | ||
1824 | return 0; | 1820 | return 0; |
1825 | } | 1821 | } |
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index e9a585758941..55724b02316b 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c | |||
@@ -412,6 +412,16 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = { | |||
412 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, | 412 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, |
413 | 0x0036, | 413 | 0x0036, |
414 | 0x11AD, /* LITEON */ | 414 | 0x11AD, /* LITEON */ |
415 | 0x06B2), | ||
416 | .driver_data = ATH9K_PCI_AR9565_1ANT }, | ||
417 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, | ||
418 | 0x0036, | ||
419 | 0x11AD, /* LITEON */ | ||
420 | 0x0842), | ||
421 | .driver_data = ATH9K_PCI_AR9565_1ANT }, | ||
422 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, | ||
423 | 0x0036, | ||
424 | 0x11AD, /* LITEON */ | ||
415 | 0x6671), | 425 | 0x6671), |
416 | .driver_data = ATH9K_PCI_AR9565_1ANT }, | 426 | .driver_data = ATH9K_PCI_AR9565_1ANT }, |
417 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, | 427 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, |
@@ -424,6 +434,16 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = { | |||
424 | 0x1B9A, /* XAVI */ | 434 | 0x1B9A, /* XAVI */ |
425 | 0x2812), | 435 | 0x2812), |
426 | .driver_data = ATH9K_PCI_AR9565_1ANT }, | 436 | .driver_data = ATH9K_PCI_AR9565_1ANT }, |
437 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, | ||
438 | 0x0036, | ||
439 | 0x1B9A, /* XAVI */ | ||
440 | 0x28A1), | ||
441 | .driver_data = ATH9K_PCI_AR9565_1ANT }, | ||
442 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, | ||
443 | 0x0036, | ||
444 | PCI_VENDOR_ID_AZWAVE, | ||
445 | 0x218A), | ||
446 | .driver_data = ATH9K_PCI_AR9565_1ANT }, | ||
427 | 447 | ||
428 | /* WB335 1-ANT / Antenna Diversity */ | 448 | /* WB335 1-ANT / Antenna Diversity */ |
429 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, | 449 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, |
@@ -469,22 +489,17 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = { | |||
469 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, | 489 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, |
470 | 0x0036, | 490 | 0x0036, |
471 | 0x11AD, /* LITEON */ | 491 | 0x11AD, /* LITEON */ |
472 | 0x0682), | 492 | 0x06A2), |
473 | .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV }, | 493 | .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV }, |
474 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, | 494 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, |
475 | 0x0036, | 495 | 0x0036, |
476 | PCI_VENDOR_ID_AZWAVE, | 496 | 0x11AD, /* LITEON */ |
477 | 0x213A), | 497 | 0x0682), |
478 | .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV }, | ||
479 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, | ||
480 | 0x0036, | ||
481 | PCI_VENDOR_ID_LENOVO, | ||
482 | 0x3026), | ||
483 | .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV }, | 498 | .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV }, |
484 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, | 499 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, |
485 | 0x0036, | 500 | 0x0036, |
486 | PCI_VENDOR_ID_LENOVO, | 501 | PCI_VENDOR_ID_AZWAVE, |
487 | 0x4026), | 502 | 0x213A), |
488 | .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV }, | 503 | .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV }, |
489 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, | 504 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, |
490 | 0x0036, | 505 | 0x0036, |
@@ -504,37 +519,35 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = { | |||
504 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, | 519 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, |
505 | 0x0036, | 520 | 0x0036, |
506 | PCI_VENDOR_ID_DELL, | 521 | PCI_VENDOR_ID_DELL, |
507 | 0x020E), | 522 | 0x020C), |
508 | .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV }, | 523 | .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV }, |
509 | 524 | ||
510 | /* WB335 2-ANT */ | 525 | /* WB335 2-ANT / Antenna-Diversity */ |
511 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, | 526 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, |
512 | 0x0036, | 527 | 0x0036, |
513 | PCI_VENDOR_ID_SAMSUNG, | 528 | PCI_VENDOR_ID_SAMSUNG, |
514 | 0x411A), | 529 | 0x411A), |
515 | .driver_data = ATH9K_PCI_AR9565_2ANT }, | 530 | .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, |
516 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, | 531 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, |
517 | 0x0036, | 532 | 0x0036, |
518 | PCI_VENDOR_ID_SAMSUNG, | 533 | PCI_VENDOR_ID_SAMSUNG, |
519 | 0x411B), | 534 | 0x411B), |
520 | .driver_data = ATH9K_PCI_AR9565_2ANT }, | 535 | .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, |
521 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, | 536 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, |
522 | 0x0036, | 537 | 0x0036, |
523 | PCI_VENDOR_ID_SAMSUNG, | 538 | PCI_VENDOR_ID_SAMSUNG, |
524 | 0x411C), | 539 | 0x411C), |
525 | .driver_data = ATH9K_PCI_AR9565_2ANT }, | 540 | .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, |
526 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, | 541 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, |
527 | 0x0036, | 542 | 0x0036, |
528 | PCI_VENDOR_ID_SAMSUNG, | 543 | PCI_VENDOR_ID_SAMSUNG, |
529 | 0x411D), | 544 | 0x411D), |
530 | .driver_data = ATH9K_PCI_AR9565_2ANT }, | 545 | .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, |
531 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, | 546 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, |
532 | 0x0036, | 547 | 0x0036, |
533 | PCI_VENDOR_ID_SAMSUNG, | 548 | PCI_VENDOR_ID_SAMSUNG, |
534 | 0x411E), | 549 | 0x411E), |
535 | .driver_data = ATH9K_PCI_AR9565_2ANT }, | 550 | .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, |
536 | |||
537 | /* WB335 2-ANT / Antenna-Diversity */ | ||
538 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, | 551 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, |
539 | 0x0036, | 552 | 0x0036, |
540 | PCI_VENDOR_ID_ATHEROS, | 553 | PCI_VENDOR_ID_ATHEROS, |
@@ -562,11 +575,31 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = { | |||
562 | .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, | 575 | .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, |
563 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, | 576 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, |
564 | 0x0036, | 577 | 0x0036, |
578 | 0x11AD, /* LITEON */ | ||
579 | 0x0832), | ||
580 | .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, | ||
581 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, | ||
582 | 0x0036, | ||
583 | 0x11AD, /* LITEON */ | ||
584 | 0x0692), | ||
585 | .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, | ||
586 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, | ||
587 | 0x0036, | ||
565 | PCI_VENDOR_ID_AZWAVE, | 588 | PCI_VENDOR_ID_AZWAVE, |
566 | 0x2130), | 589 | 0x2130), |
567 | .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, | 590 | .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, |
568 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, | 591 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, |
569 | 0x0036, | 592 | 0x0036, |
593 | PCI_VENDOR_ID_AZWAVE, | ||
594 | 0x213B), | ||
595 | .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, | ||
596 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, | ||
597 | 0x0036, | ||
598 | PCI_VENDOR_ID_AZWAVE, | ||
599 | 0x2182), | ||
600 | .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, | ||
601 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, | ||
602 | 0x0036, | ||
570 | 0x144F, /* ASKEY */ | 603 | 0x144F, /* ASKEY */ |
571 | 0x7202), | 604 | 0x7202), |
572 | .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, | 605 | .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, |
@@ -577,6 +610,11 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = { | |||
577 | .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, | 610 | .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, |
578 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, | 611 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, |
579 | 0x0036, | 612 | 0x0036, |
613 | 0x1B9A, /* XAVI */ | ||
614 | 0x28A2), | ||
615 | .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, | ||
616 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, | ||
617 | 0x0036, | ||
580 | 0x185F, /* WNC */ | 618 | 0x185F, /* WNC */ |
581 | 0x3027), | 619 | 0x3027), |
582 | .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, | 620 | .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, |
@@ -590,6 +628,31 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = { | |||
590 | PCI_VENDOR_ID_FOXCONN, | 628 | PCI_VENDOR_ID_FOXCONN, |
591 | 0xE07F), | 629 | 0xE07F), |
592 | .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, | 630 | .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, |
631 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, | ||
632 | 0x0036, | ||
633 | PCI_VENDOR_ID_FOXCONN, | ||
634 | 0xE081), | ||
635 | .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, | ||
636 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, | ||
637 | 0x0036, | ||
638 | PCI_VENDOR_ID_LENOVO, | ||
639 | 0x3026), | ||
640 | .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, | ||
641 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, | ||
642 | 0x0036, | ||
643 | PCI_VENDOR_ID_LENOVO, | ||
644 | 0x4026), | ||
645 | .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, | ||
646 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, | ||
647 | 0x0036, | ||
648 | PCI_VENDOR_ID_ASUSTEK, | ||
649 | 0x85F2), | ||
650 | .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, | ||
651 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, | ||
652 | 0x0036, | ||
653 | PCI_VENDOR_ID_DELL, | ||
654 | 0x020E), | ||
655 | .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, | ||
593 | 656 | ||
594 | /* PCI-E AR9565 (WB335) */ | 657 | /* PCI-E AR9565 (WB335) */ |
595 | { PCI_VDEVICE(ATHEROS, 0x0036), | 658 | { PCI_VDEVICE(ATHEROS, 0x0036), |
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 3692b2a501a2..f7cc5b37a18f 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
@@ -419,7 +419,7 @@ u32 ath_calcrxfilter(struct ath_softc *sc) | |||
419 | rfilt |= ATH9K_RX_FILTER_MCAST_BCAST_ALL; | 419 | rfilt |= ATH9K_RX_FILTER_MCAST_BCAST_ALL; |
420 | } | 420 | } |
421 | 421 | ||
422 | if (AR_SREV_9550(sc->sc_ah)) | 422 | if (AR_SREV_9550(sc->sc_ah) || AR_SREV_9531(sc->sc_ah)) |
423 | rfilt |= ATH9K_RX_FILTER_4ADDRESS; | 423 | rfilt |= ATH9K_RX_FILTER_4ADDRESS; |
424 | 424 | ||
425 | return rfilt; | 425 | return rfilt; |
@@ -850,20 +850,15 @@ static int ath9k_process_rate(struct ath_common *common, | |||
850 | enum ieee80211_band band; | 850 | enum ieee80211_band band; |
851 | unsigned int i = 0; | 851 | unsigned int i = 0; |
852 | struct ath_softc __maybe_unused *sc = common->priv; | 852 | struct ath_softc __maybe_unused *sc = common->priv; |
853 | struct ath_hw *ah = sc->sc_ah; | ||
853 | 854 | ||
854 | band = hw->conf.chandef.chan->band; | 855 | band = ah->curchan->chan->band; |
855 | sband = hw->wiphy->bands[band]; | 856 | sband = hw->wiphy->bands[band]; |
856 | 857 | ||
857 | switch (hw->conf.chandef.width) { | 858 | if (IS_CHAN_QUARTER_RATE(ah->curchan)) |
858 | case NL80211_CHAN_WIDTH_5: | ||
859 | rxs->flag |= RX_FLAG_5MHZ; | 859 | rxs->flag |= RX_FLAG_5MHZ; |
860 | break; | 860 | else if (IS_CHAN_HALF_RATE(ah->curchan)) |
861 | case NL80211_CHAN_WIDTH_10: | ||
862 | rxs->flag |= RX_FLAG_10MHZ; | 861 | rxs->flag |= RX_FLAG_10MHZ; |
863 | break; | ||
864 | default: | ||
865 | break; | ||
866 | } | ||
867 | 862 | ||
868 | if (rx_stats->rs_rate & 0x80) { | 863 | if (rx_stats->rs_rate & 0x80) { |
869 | /* HT rate */ | 864 | /* HT rate */ |
@@ -982,7 +977,7 @@ static bool ath9k_is_mybeacon(struct ath_softc *sc, struct ieee80211_hdr *hdr) | |||
982 | if (ieee80211_is_beacon(hdr->frame_control)) { | 977 | if (ieee80211_is_beacon(hdr->frame_control)) { |
983 | RX_STAT_INC(rx_beacons); | 978 | RX_STAT_INC(rx_beacons); |
984 | if (!is_zero_ether_addr(common->curbssid) && | 979 | if (!is_zero_ether_addr(common->curbssid) && |
985 | ether_addr_equal(hdr->addr3, common->curbssid)) | 980 | ether_addr_equal_64bits(hdr->addr3, common->curbssid)) |
986 | return true; | 981 | return true; |
987 | } | 982 | } |
988 | 983 | ||
@@ -1077,9 +1072,13 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc, | |||
1077 | } | 1072 | } |
1078 | 1073 | ||
1079 | rx_stats->is_mybeacon = ath9k_is_mybeacon(sc, hdr); | 1074 | rx_stats->is_mybeacon = ath9k_is_mybeacon(sc, hdr); |
1080 | if (rx_stats->is_mybeacon) { | 1075 | |
1081 | sc->hw_busy_count = 0; | 1076 | /* |
1082 | ath_start_rx_poll(sc, 3); | 1077 | * This shouldn't happen, but have a safety check anyway. |
1078 | */ | ||
1079 | if (WARN_ON(!ah->curchan)) { | ||
1080 | ret = -EINVAL; | ||
1081 | goto exit; | ||
1083 | } | 1082 | } |
1084 | 1083 | ||
1085 | if (ath9k_process_rate(common, hw, rx_stats, rx_status)) { | 1084 | if (ath9k_process_rate(common, hw, rx_stats, rx_status)) { |
@@ -1089,8 +1088,8 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc, | |||
1089 | 1088 | ||
1090 | ath9k_process_rssi(common, hw, rx_stats, rx_status); | 1089 | ath9k_process_rssi(common, hw, rx_stats, rx_status); |
1091 | 1090 | ||
1092 | rx_status->band = hw->conf.chandef.chan->band; | 1091 | rx_status->band = ah->curchan->chan->band; |
1093 | rx_status->freq = hw->conf.chandef.chan->center_freq; | 1092 | rx_status->freq = ah->curchan->chan->center_freq; |
1094 | rx_status->antenna = rx_stats->rs_antenna; | 1093 | rx_status->antenna = rx_stats->rs_antenna; |
1095 | rx_status->flag |= RX_FLAG_MACTIME_END; | 1094 | rx_status->flag |= RX_FLAG_MACTIME_END; |
1096 | 1095 | ||
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index 9ad007312c9d..b1fd3fa84983 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h | |||
@@ -304,6 +304,7 @@ | |||
304 | #define AR_IMR_S2 0x00ac | 304 | #define AR_IMR_S2 0x00ac |
305 | #define AR_IMR_S2_QCU_TXURN 0x000003FF | 305 | #define AR_IMR_S2_QCU_TXURN 0x000003FF |
306 | #define AR_IMR_S2_QCU_TXURN_S 0 | 306 | #define AR_IMR_S2_QCU_TXURN_S 0 |
307 | #define AR_IMR_S2_BB_WATCHDOG 0x00010000 | ||
307 | #define AR_IMR_S2_CST 0x00400000 | 308 | #define AR_IMR_S2_CST 0x00400000 |
308 | #define AR_IMR_S2_GTT 0x00800000 | 309 | #define AR_IMR_S2_GTT 0x00800000 |
309 | #define AR_IMR_S2_TIM 0x01000000 | 310 | #define AR_IMR_S2_TIM 0x01000000 |
@@ -812,6 +813,9 @@ | |||
812 | #define AR_SREV_REVISION_9565_101 1 | 813 | #define AR_SREV_REVISION_9565_101 1 |
813 | #define AR_SREV_REVISION_9565_11 2 | 814 | #define AR_SREV_REVISION_9565_11 2 |
814 | #define AR_SREV_VERSION_9550 0x400 | 815 | #define AR_SREV_VERSION_9550 0x400 |
816 | #define AR_SREV_VERSION_9531 0x500 | ||
817 | #define AR_SREV_REVISION_9531_10 0 | ||
818 | #define AR_SREV_REVISION_9531_11 1 | ||
815 | 819 | ||
816 | #define AR_SREV_5416(_ah) \ | 820 | #define AR_SREV_5416(_ah) \ |
817 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \ | 821 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \ |
@@ -945,11 +949,19 @@ | |||
945 | #define AR_SREV_9580(_ah) \ | 949 | #define AR_SREV_9580(_ah) \ |
946 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9580) && \ | 950 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9580) && \ |
947 | ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9580_10)) | 951 | ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9580_10)) |
948 | |||
949 | #define AR_SREV_9580_10(_ah) \ | 952 | #define AR_SREV_9580_10(_ah) \ |
950 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9580) && \ | 953 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9580) && \ |
951 | ((_ah)->hw_version.macRev == AR_SREV_REVISION_9580_10)) | 954 | ((_ah)->hw_version.macRev == AR_SREV_REVISION_9580_10)) |
952 | 955 | ||
956 | #define AR_SREV_9531(_ah) \ | ||
957 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9531)) | ||
958 | #define AR_SREV_9531_10(_ah) \ | ||
959 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9531) && \ | ||
960 | ((_ah)->hw_version.macRev == AR_SREV_REVISION_9531_10)) | ||
961 | #define AR_SREV_9531_11(_ah) \ | ||
962 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9531) && \ | ||
963 | ((_ah)->hw_version.macRev == AR_SREV_REVISION_9531_11)) | ||
964 | |||
953 | /* NOTE: When adding chips newer than Peacock, add chip check here */ | 965 | /* NOTE: When adding chips newer than Peacock, add chip check here */ |
954 | #define AR_SREV_9580_10_OR_LATER(_ah) \ | 966 | #define AR_SREV_9580_10_OR_LATER(_ah) \ |
955 | (AR_SREV_9580(_ah)) | 967 | (AR_SREV_9580(_ah)) |
diff --git a/drivers/net/wireless/ath/ath9k/spectral.c b/drivers/net/wireless/ath/ath9k/spectral.c index 11adb5eb51cc..99f4de95c264 100644 --- a/drivers/net/wireless/ath/ath9k/spectral.c +++ b/drivers/net/wireless/ath/ath9k/spectral.c | |||
@@ -497,7 +497,7 @@ static int remove_buf_file_handler(struct dentry *dentry) | |||
497 | return 0; | 497 | return 0; |
498 | } | 498 | } |
499 | 499 | ||
500 | struct rchan_callbacks rfs_spec_scan_cb = { | 500 | static struct rchan_callbacks rfs_spec_scan_cb = { |
501 | .create_buf_file = create_buf_file_handler, | 501 | .create_buf_file = create_buf_file_handler, |
502 | .remove_buf_file = remove_buf_file_handler, | 502 | .remove_buf_file = remove_buf_file_handler, |
503 | }; | 503 | }; |
diff --git a/drivers/net/wireless/ath/ath9k/wow.c b/drivers/net/wireless/ath/ath9k/wow.c index f1cde81bb7a2..1b3230fa3651 100644 --- a/drivers/net/wireless/ath/ath9k/wow.c +++ b/drivers/net/wireless/ath/ath9k/wow.c | |||
@@ -197,7 +197,6 @@ int ath9k_suspend(struct ieee80211_hw *hw, | |||
197 | 197 | ||
198 | ath_cancel_work(sc); | 198 | ath_cancel_work(sc); |
199 | ath_stop_ani(sc); | 199 | ath_stop_ani(sc); |
200 | del_timer_sync(&sc->rx_poll_timer); | ||
201 | 200 | ||
202 | if (test_bit(SC_OP_INVALID, &sc->sc_flags)) { | 201 | if (test_bit(SC_OP_INVALID, &sc->sc_flags)) { |
203 | ath_dbg(common, ANY, "Device not present\n"); | 202 | ath_dbg(common, ANY, "Device not present\n"); |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 9d735c55a0f3..e8d0e7fc77da 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -774,11 +774,6 @@ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf, | |||
774 | if (bt_aggr_limit) | 774 | if (bt_aggr_limit) |
775 | aggr_limit = bt_aggr_limit; | 775 | aggr_limit = bt_aggr_limit; |
776 | 776 | ||
777 | /* | ||
778 | * h/w can accept aggregates up to 16 bit lengths (65535). | ||
779 | * The IE, however can hold up to 65536, which shows up here | ||
780 | * as zero. Ignore 65536 since we are constrained by hw. | ||
781 | */ | ||
782 | if (tid->an->maxampdu) | 777 | if (tid->an->maxampdu) |
783 | aggr_limit = min(aggr_limit, tid->an->maxampdu); | 778 | aggr_limit = min(aggr_limit, tid->an->maxampdu); |
784 | 779 | ||
@@ -1403,8 +1398,8 @@ int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, | |||
1403 | * has already been added. | 1398 | * has already been added. |
1404 | */ | 1399 | */ |
1405 | if (sta->ht_cap.ht_supported) { | 1400 | if (sta->ht_cap.ht_supported) { |
1406 | an->maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR + | 1401 | an->maxampdu = (1 << (IEEE80211_HT_MAX_AMPDU_FACTOR + |
1407 | sta->ht_cap.ampdu_factor); | 1402 | sta->ht_cap.ampdu_factor)) - 1; |
1408 | density = ath9k_parse_mpdudensity(sta->ht_cap.ampdu_density); | 1403 | density = ath9k_parse_mpdudensity(sta->ht_cap.ampdu_density); |
1409 | an->mpdudensity = density; | 1404 | an->mpdudensity = density; |
1410 | } | 1405 | } |
diff --git a/drivers/net/wireless/ath/carl9170/debug.c b/drivers/net/wireless/ath/carl9170/debug.c index 3d70cd277fd7..1c0af9cd9a85 100644 --- a/drivers/net/wireless/ath/carl9170/debug.c +++ b/drivers/net/wireless/ath/carl9170/debug.c | |||
@@ -37,7 +37,6 @@ | |||
37 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 37 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
38 | */ | 38 | */ |
39 | 39 | ||
40 | #include <linux/init.h> | ||
41 | #include <linux/slab.h> | 40 | #include <linux/slab.h> |
42 | #include <linux/module.h> | 41 | #include <linux/module.h> |
43 | #include <linux/seq_file.h> | 42 | #include <linux/seq_file.h> |
diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c index 349fa22a921a..4c3f576c3144 100644 --- a/drivers/net/wireless/ath/carl9170/main.c +++ b/drivers/net/wireless/ath/carl9170/main.c | |||
@@ -37,7 +37,6 @@ | |||
37 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 37 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
38 | */ | 38 | */ |
39 | 39 | ||
40 | #include <linux/init.h> | ||
41 | #include <linux/slab.h> | 40 | #include <linux/slab.h> |
42 | #include <linux/module.h> | 41 | #include <linux/module.h> |
43 | #include <linux/etherdevice.h> | 42 | #include <linux/etherdevice.h> |
diff --git a/drivers/net/wireless/ath/carl9170/rx.c b/drivers/net/wireless/ath/carl9170/rx.c index e935f61c7fad..1b1b20751ead 100644 --- a/drivers/net/wireless/ath/carl9170/rx.c +++ b/drivers/net/wireless/ath/carl9170/rx.c | |||
@@ -37,7 +37,6 @@ | |||
37 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 37 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
38 | */ | 38 | */ |
39 | 39 | ||
40 | #include <linux/init.h> | ||
41 | #include <linux/slab.h> | 40 | #include <linux/slab.h> |
42 | #include <linux/module.h> | 41 | #include <linux/module.h> |
43 | #include <linux/etherdevice.h> | 42 | #include <linux/etherdevice.h> |
@@ -536,7 +535,7 @@ static void carl9170_ps_beacon(struct ar9170 *ar, void *data, unsigned int len) | |||
536 | return; | 535 | return; |
537 | 536 | ||
538 | /* and only beacons from the associated BSSID, please */ | 537 | /* and only beacons from the associated BSSID, please */ |
539 | if (!ether_addr_equal(hdr->addr3, ar->common.curbssid) || | 538 | if (!ether_addr_equal_64bits(hdr->addr3, ar->common.curbssid) || |
540 | !ar->common.curaid) | 539 | !ar->common.curaid) |
541 | return; | 540 | return; |
542 | 541 | ||
@@ -602,8 +601,8 @@ static void carl9170_ba_check(struct ar9170 *ar, void *data, unsigned int len) | |||
602 | 601 | ||
603 | if (bar->start_seq_num == entry_bar->start_seq_num && | 602 | if (bar->start_seq_num == entry_bar->start_seq_num && |
604 | TID_CHECK(bar->control, entry_bar->control) && | 603 | TID_CHECK(bar->control, entry_bar->control) && |
605 | ether_addr_equal(bar->ra, entry_bar->ta) && | 604 | ether_addr_equal_64bits(bar->ra, entry_bar->ta) && |
606 | ether_addr_equal(bar->ta, entry_bar->ra)) { | 605 | ether_addr_equal_64bits(bar->ta, entry_bar->ra)) { |
607 | struct ieee80211_tx_info *tx_info; | 606 | struct ieee80211_tx_info *tx_info; |
608 | 607 | ||
609 | tx_info = IEEE80211_SKB_CB(entry_skb); | 608 | tx_info = IEEE80211_SKB_CB(entry_skb); |
diff --git a/drivers/net/wireless/ath/carl9170/tx.c b/drivers/net/wireless/ath/carl9170/tx.c index e3f696ee4d23..4cadfd48ffdf 100644 --- a/drivers/net/wireless/ath/carl9170/tx.c +++ b/drivers/net/wireless/ath/carl9170/tx.c | |||
@@ -37,7 +37,6 @@ | |||
37 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 37 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
38 | */ | 38 | */ |
39 | 39 | ||
40 | #include <linux/init.h> | ||
41 | #include <linux/slab.h> | 40 | #include <linux/slab.h> |
42 | #include <linux/module.h> | 41 | #include <linux/module.h> |
43 | #include <linux/etherdevice.h> | 42 | #include <linux/etherdevice.h> |
diff --git a/drivers/net/wireless/ath/wil6210/interrupt.c b/drivers/net/wireless/ath/wil6210/interrupt.c index 8205d3e4ab66..10919f95a83c 100644 --- a/drivers/net/wireless/ath/wil6210/interrupt.c +++ b/drivers/net/wireless/ath/wil6210/interrupt.c | |||
@@ -156,6 +156,19 @@ void wil6210_enable_irq(struct wil6210_priv *wil) | |||
156 | iowrite32(WIL_ICR_ICC_VALUE, wil->csr + HOSTADDR(RGF_DMA_EP_MISC_ICR) + | 156 | iowrite32(WIL_ICR_ICC_VALUE, wil->csr + HOSTADDR(RGF_DMA_EP_MISC_ICR) + |
157 | offsetof(struct RGF_ICR, ICC)); | 157 | offsetof(struct RGF_ICR, ICC)); |
158 | 158 | ||
159 | /* interrupt moderation parameters */ | ||
160 | if (wil->wdev->iftype == NL80211_IFTYPE_MONITOR) { | ||
161 | /* disable interrupt moderation for monitor | ||
162 | * to get better timestamp precision | ||
163 | */ | ||
164 | iowrite32(0, wil->csr + HOSTADDR(RGF_DMA_ITR_CNT_CRL)); | ||
165 | } else { | ||
166 | iowrite32(WIL6210_ITR_TRSH, | ||
167 | wil->csr + HOSTADDR(RGF_DMA_ITR_CNT_TRSH)); | ||
168 | iowrite32(BIT_DMA_ITR_CNT_CRL_EN, | ||
169 | wil->csr + HOSTADDR(RGF_DMA_ITR_CNT_CRL)); | ||
170 | } | ||
171 | |||
159 | wil6210_unmask_irq_pseudo(wil); | 172 | wil6210_unmask_irq_pseudo(wil); |
160 | wil6210_unmask_irq_tx(wil); | 173 | wil6210_unmask_irq_tx(wil); |
161 | wil6210_unmask_irq_rx(wil); | 174 | wil6210_unmask_irq_rx(wil); |
diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c index d505b2676a73..9b88440ef05b 100644 --- a/drivers/net/wireless/ath/wil6210/txrx.c +++ b/drivers/net/wireless/ath/wil6210/txrx.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/ip.h> | 21 | #include <linux/ip.h> |
22 | #include <linux/ipv6.h> | 22 | #include <linux/ipv6.h> |
23 | #include <net/ipv6.h> | 23 | #include <net/ipv6.h> |
24 | #include <asm/processor.h> | ||
24 | 25 | ||
25 | #include "wil6210.h" | 26 | #include "wil6210.h" |
26 | #include "wmi.h" | 27 | #include "wmi.h" |
@@ -377,6 +378,8 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil, | |||
377 | } | 378 | } |
378 | skb_trim(skb, dmalen); | 379 | skb_trim(skb, dmalen); |
379 | 380 | ||
381 | prefetch(skb->data); | ||
382 | |||
380 | wil_hex_dump_txrx("Rx ", DUMP_PREFIX_OFFSET, 16, 1, | 383 | wil_hex_dump_txrx("Rx ", DUMP_PREFIX_OFFSET, 16, 1, |
381 | skb->data, skb_headlen(skb), false); | 384 | skb->data, skb_headlen(skb), false); |
382 | 385 | ||
@@ -673,9 +676,12 @@ static int wil_tx_desc_offload_cksum_set(struct wil6210_priv *wil, | |||
673 | if (skb->ip_summed != CHECKSUM_PARTIAL) | 676 | if (skb->ip_summed != CHECKSUM_PARTIAL) |
674 | return 0; | 677 | return 0; |
675 | 678 | ||
679 | d->dma.b11 = ETH_HLEN; /* MAC header length */ | ||
680 | |||
676 | switch (skb->protocol) { | 681 | switch (skb->protocol) { |
677 | case cpu_to_be16(ETH_P_IP): | 682 | case cpu_to_be16(ETH_P_IP): |
678 | protocol = ip_hdr(skb)->protocol; | 683 | protocol = ip_hdr(skb)->protocol; |
684 | d->dma.b11 |= BIT(DMA_CFG_DESC_TX_OFFLOAD_CFG_L3T_IPV4_POS); | ||
679 | break; | 685 | break; |
680 | case cpu_to_be16(ETH_P_IPV6): | 686 | case cpu_to_be16(ETH_P_IPV6): |
681 | protocol = ipv6_hdr(skb)->nexthdr; | 687 | protocol = ipv6_hdr(skb)->nexthdr; |
@@ -701,8 +707,6 @@ static int wil_tx_desc_offload_cksum_set(struct wil6210_priv *wil, | |||
701 | } | 707 | } |
702 | 708 | ||
703 | d->dma.ip_length = skb_network_header_len(skb); | 709 | d->dma.ip_length = skb_network_header_len(skb); |
704 | d->dma.b11 = ETH_HLEN; /* MAC header length */ | ||
705 | d->dma.b11 |= BIT(DMA_CFG_DESC_TX_OFFLOAD_CFG_L3T_IPV4_POS); | ||
706 | /* Enable TCP/UDP checksum */ | 710 | /* Enable TCP/UDP checksum */ |
707 | d->dma.d0 |= BIT(DMA_CFG_DESC_TX_0_TCP_UDP_CHECKSUM_EN_POS); | 711 | d->dma.d0 |= BIT(DMA_CFG_DESC_TX_0_TCP_UDP_CHECKSUM_EN_POS); |
708 | /* Calculate pseudo-header */ | 712 | /* Calculate pseudo-header */ |
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h index c4a51638736a..1f91eaf95bbe 100644 --- a/drivers/net/wireless/ath/wil6210/wil6210.h +++ b/drivers/net/wireless/ath/wil6210/wil6210.h | |||
@@ -39,6 +39,7 @@ static inline u32 WIL_GET_BITS(u32 x, int b0, int b1) | |||
39 | #define WIL6210_MAX_TX_RINGS (24) /* HW limit */ | 39 | #define WIL6210_MAX_TX_RINGS (24) /* HW limit */ |
40 | #define WIL6210_MAX_CID (8) /* HW limit */ | 40 | #define WIL6210_MAX_CID (8) /* HW limit */ |
41 | #define WIL6210_NAPI_BUDGET (16) /* arbitrary */ | 41 | #define WIL6210_NAPI_BUDGET (16) /* arbitrary */ |
42 | #define WIL6210_ITR_TRSH (10000) /* arbitrary - about 15 IRQs/msec */ | ||
42 | 43 | ||
43 | /* Hardware definitions begin */ | 44 | /* Hardware definitions begin */ |
44 | 45 | ||
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c index b73b7e3e2196..bf93ea859f2d 100644 --- a/drivers/net/wireless/atmel.c +++ b/drivers/net/wireless/atmel.c | |||
@@ -39,7 +39,6 @@ | |||
39 | 39 | ||
40 | ******************************************************************************/ | 40 | ******************************************************************************/ |
41 | 41 | ||
42 | #include <linux/init.h> | ||
43 | #include <linux/interrupt.h> | 42 | #include <linux/interrupt.h> |
44 | 43 | ||
45 | #include <linux/kernel.h> | 44 | #include <linux/kernel.h> |
diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c index 5e2749dd1124..4cfb4d99ced0 100644 --- a/drivers/net/wireless/atmel_cs.c +++ b/drivers/net/wireless/atmel_cs.c | |||
@@ -32,7 +32,6 @@ | |||
32 | #ifdef __IN_PCMCIA_PACKAGE__ | 32 | #ifdef __IN_PCMCIA_PACKAGE__ |
33 | #include <pcmcia/k_compat.h> | 33 | #include <pcmcia/k_compat.h> |
34 | #endif | 34 | #endif |
35 | #include <linux/init.h> | ||
36 | #include <linux/kernel.h> | 35 | #include <linux/kernel.h> |
37 | #include <linux/module.h> | 36 | #include <linux/module.h> |
38 | #include <linux/ptrace.h> | 37 | #include <linux/ptrace.h> |
diff --git a/drivers/net/wireless/atmel_pci.c b/drivers/net/wireless/atmel_pci.c index 64d5973ec28b..5cd97e3cbee3 100644 --- a/drivers/net/wireless/atmel_pci.c +++ b/drivers/net/wireless/atmel_pci.c | |||
@@ -22,7 +22,6 @@ | |||
22 | #include <linux/pci.h> | 22 | #include <linux/pci.h> |
23 | #include <linux/kernel.h> | 23 | #include <linux/kernel.h> |
24 | #include <linux/module.h> | 24 | #include <linux/module.h> |
25 | #include <linux/init.h> | ||
26 | #include <linux/netdevice.h> | 25 | #include <linux/netdevice.h> |
27 | #include "atmel.h" | 26 | #include "atmel.h" |
28 | 27 | ||
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c index 12c27d13df7f..c229210d50ba 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c | |||
@@ -41,9 +41,6 @@ struct brcmf_proto_bcdc_dcmd { | |||
41 | __le32 status; /* status code returned from the device */ | 41 | __le32 status; /* status code returned from the device */ |
42 | }; | 42 | }; |
43 | 43 | ||
44 | /* Max valid buffer size that can be sent to the dongle */ | ||
45 | #define BCDC_MAX_MSG_SIZE (ETH_FRAME_LEN+ETH_FCS_LEN) | ||
46 | |||
47 | /* BCDC flag definitions */ | 44 | /* BCDC flag definitions */ |
48 | #define BCDC_DCMD_ERROR 0x01 /* 1=cmd failed */ | 45 | #define BCDC_DCMD_ERROR 0x01 /* 1=cmd failed */ |
49 | #define BCDC_DCMD_SET 0x02 /* 0=get, 1=set cmd */ | 46 | #define BCDC_DCMD_SET 0x02 /* 0=get, 1=set cmd */ |
@@ -133,9 +130,12 @@ brcmf_proto_bcdc_msg(struct brcmf_pub *drvr, int ifidx, uint cmd, void *buf, | |||
133 | if (buf) | 130 | if (buf) |
134 | memcpy(bcdc->buf, buf, len); | 131 | memcpy(bcdc->buf, buf, len); |
135 | 132 | ||
133 | len += sizeof(*msg); | ||
134 | if (len > BRCMF_TX_IOCTL_MAX_MSG_SIZE) | ||
135 | len = BRCMF_TX_IOCTL_MAX_MSG_SIZE; | ||
136 | |||
136 | /* Send request */ | 137 | /* Send request */ |
137 | return brcmf_bus_txctl(drvr->bus_if, (unsigned char *)&bcdc->msg, | 138 | return brcmf_bus_txctl(drvr->bus_if, (unsigned char *)&bcdc->msg, len); |
138 | len + sizeof(struct brcmf_proto_bcdc_dcmd)); | ||
139 | } | 139 | } |
140 | 140 | ||
141 | static int brcmf_proto_bcdc_cmplt(struct brcmf_pub *drvr, u32 id, u32 len) | 141 | static int brcmf_proto_bcdc_cmplt(struct brcmf_pub *drvr, u32 id, u32 len) |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c index 2b5cde67e728..34c993dd0602 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | |||
@@ -47,8 +47,6 @@ | |||
47 | 47 | ||
48 | #define SDIOH_API_ACCESS_RETRY_LIMIT 2 | 48 | #define SDIOH_API_ACCESS_RETRY_LIMIT 2 |
49 | 49 | ||
50 | #define SDIO_VENDOR_ID_BROADCOM 0x02d0 | ||
51 | |||
52 | #define DMA_ALIGN_MASK 0x03 | 50 | #define DMA_ALIGN_MASK 0x03 |
53 | 51 | ||
54 | #define SDIO_FUNC1_BLOCKSIZE 64 | 52 | #define SDIO_FUNC1_BLOCKSIZE 64 |
@@ -216,94 +214,104 @@ static inline int brcmf_sdiod_f0_writeb(struct sdio_func *func, | |||
216 | return err_ret; | 214 | return err_ret; |
217 | } | 215 | } |
218 | 216 | ||
219 | static int brcmf_sdiod_request_byte(struct brcmf_sdio_dev *sdiodev, uint rw, | 217 | static int brcmf_sdiod_request_data(struct brcmf_sdio_dev *sdiodev, u8 fn, |
220 | uint func, uint regaddr, u8 *byte) | 218 | u32 addr, u8 regsz, void *data, bool write) |
221 | { | 219 | { |
222 | int err_ret; | 220 | struct sdio_func *func; |
221 | int ret; | ||
223 | 222 | ||
224 | brcmf_dbg(SDIO, "rw=%d, func=%d, addr=0x%05x\n", rw, func, regaddr); | 223 | brcmf_dbg(SDIO, "rw=%d, func=%d, addr=0x%05x, nbytes=%d\n", |
224 | write, fn, addr, regsz); | ||
225 | 225 | ||
226 | brcmf_sdiod_pm_resume_wait(sdiodev, &sdiodev->request_byte_wait); | 226 | brcmf_sdiod_pm_resume_wait(sdiodev, &sdiodev->request_word_wait); |
227 | if (brcmf_sdiod_pm_resume_error(sdiodev)) | 227 | if (brcmf_sdiod_pm_resume_error(sdiodev)) |
228 | return -EIO; | 228 | return -EIO; |
229 | 229 | ||
230 | if (rw && func == 0) { | 230 | /* only allow byte access on F0 */ |
231 | /* handle F0 separately */ | 231 | if (WARN_ON(regsz > 1 && !fn)) |
232 | err_ret = brcmf_sdiod_f0_writeb(sdiodev->func[func], | 232 | return -EINVAL; |
233 | regaddr, *byte); | 233 | func = sdiodev->func[fn]; |
234 | } else { | 234 | |
235 | if (rw) /* CMD52 Write */ | 235 | switch (regsz) { |
236 | sdio_writeb(sdiodev->func[func], *byte, regaddr, | 236 | case sizeof(u8): |
237 | &err_ret); | 237 | if (write) { |
238 | else if (func == 0) { | 238 | if (fn) |
239 | *byte = sdio_f0_readb(sdiodev->func[func], regaddr, | 239 | sdio_writeb(func, *(u8 *)data, addr, &ret); |
240 | &err_ret); | 240 | else |
241 | ret = brcmf_sdiod_f0_writeb(func, addr, | ||
242 | *(u8 *)data); | ||
241 | } else { | 243 | } else { |
242 | *byte = sdio_readb(sdiodev->func[func], regaddr, | 244 | if (fn) |
243 | &err_ret); | 245 | *(u8 *)data = sdio_readb(func, addr, &ret); |
246 | else | ||
247 | *(u8 *)data = sdio_f0_readb(func, addr, &ret); | ||
244 | } | 248 | } |
249 | break; | ||
250 | case sizeof(u16): | ||
251 | if (write) | ||
252 | sdio_writew(func, *(u16 *)data, addr, &ret); | ||
253 | else | ||
254 | *(u16 *)data = sdio_readw(func, addr, &ret); | ||
255 | break; | ||
256 | case sizeof(u32): | ||
257 | if (write) | ||
258 | sdio_writel(func, *(u32 *)data, addr, &ret); | ||
259 | else | ||
260 | *(u32 *)data = sdio_readl(func, addr, &ret); | ||
261 | break; | ||
262 | default: | ||
263 | brcmf_err("invalid size: %d\n", regsz); | ||
264 | break; | ||
245 | } | 265 | } |
246 | 266 | ||
247 | if (err_ret) { | 267 | if (ret) { |
248 | /* | 268 | /* |
249 | * SleepCSR register access can fail when | 269 | * SleepCSR register access can fail when |
250 | * waking up the device so reduce this noise | 270 | * waking up the device so reduce this noise |
251 | * in the logs. | 271 | * in the logs. |
252 | */ | 272 | */ |
253 | if (regaddr != SBSDIO_FUNC1_SLEEPCSR) | 273 | if (addr != SBSDIO_FUNC1_SLEEPCSR) |
254 | brcmf_err("Failed to %s byte F%d:@0x%05x=%02x, Err: %d\n", | 274 | brcmf_err("failed to %s data F%d@0x%05x, err: %d\n", |
255 | rw ? "write" : "read", func, regaddr, *byte, | 275 | write ? "write" : "read", fn, addr, ret); |
256 | err_ret); | ||
257 | else | 276 | else |
258 | brcmf_dbg(SDIO, "Failed to %s byte F%d:@0x%05x=%02x, Err: %d\n", | 277 | brcmf_dbg(SDIO, "failed to %s data F%d@0x%05x, err: %d\n", |
259 | rw ? "write" : "read", func, regaddr, *byte, | 278 | write ? "write" : "read", fn, addr, ret); |
260 | err_ret); | ||
261 | } | 279 | } |
262 | return err_ret; | 280 | return ret; |
263 | } | 281 | } |
264 | 282 | ||
265 | static int brcmf_sdiod_request_word(struct brcmf_sdio_dev *sdiodev, uint rw, | 283 | static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr, |
266 | uint func, uint addr, u32 *word, | 284 | u8 regsz, void *data, bool write) |
267 | uint nbytes) | ||
268 | { | 285 | { |
269 | int err_ret = -EIO; | 286 | u8 func_num; |
270 | 287 | s32 retry = 0; | |
271 | if (func == 0) { | 288 | int ret; |
272 | brcmf_err("Only CMD52 allowed to F0\n"); | ||
273 | return -EINVAL; | ||
274 | } | ||
275 | |||
276 | brcmf_dbg(SDIO, "rw=%d, func=%d, addr=0x%05x, nbytes=%d\n", | ||
277 | rw, func, addr, nbytes); | ||
278 | 289 | ||
279 | brcmf_sdiod_pm_resume_wait(sdiodev, &sdiodev->request_word_wait); | 290 | /* |
280 | if (brcmf_sdiod_pm_resume_error(sdiodev)) | 291 | * figure out how to read the register based on address range |
281 | return -EIO; | 292 | * 0x00 ~ 0x7FF: function 0 CCCR and FBR |
293 | * 0x10000 ~ 0x1FFFF: function 1 miscellaneous registers | ||
294 | * The rest: function 1 silicon backplane core registers | ||
295 | */ | ||
296 | if ((addr & ~REG_F0_REG_MASK) == 0) | ||
297 | func_num = SDIO_FUNC_0; | ||
298 | else | ||
299 | func_num = SDIO_FUNC_1; | ||
282 | 300 | ||
283 | if (rw) { /* CMD52 Write */ | 301 | do { |
284 | if (nbytes == 4) | 302 | if (!write) |
285 | sdio_writel(sdiodev->func[func], *word, addr, | 303 | memset(data, 0, regsz); |
286 | &err_ret); | 304 | /* for retry wait for 1 ms till bus get settled down */ |
287 | else if (nbytes == 2) | 305 | if (retry) |
288 | sdio_writew(sdiodev->func[func], (*word & 0xFFFF), | 306 | usleep_range(1000, 2000); |
289 | addr, &err_ret); | 307 | ret = brcmf_sdiod_request_data(sdiodev, func_num, addr, regsz, |
290 | else | 308 | data, write); |
291 | brcmf_err("Invalid nbytes: %d\n", nbytes); | 309 | } while (ret != 0 && retry++ < SDIOH_API_ACCESS_RETRY_LIMIT); |
292 | } else { /* CMD52 Read */ | ||
293 | if (nbytes == 4) | ||
294 | *word = sdio_readl(sdiodev->func[func], addr, &err_ret); | ||
295 | else if (nbytes == 2) | ||
296 | *word = sdio_readw(sdiodev->func[func], addr, | ||
297 | &err_ret) & 0xFFFF; | ||
298 | else | ||
299 | brcmf_err("Invalid nbytes: %d\n", nbytes); | ||
300 | } | ||
301 | 310 | ||
302 | if (err_ret) | 311 | if (ret != 0) |
303 | brcmf_err("Failed to %s word, Err: 0x%08x\n", | 312 | brcmf_err("failed with %d\n", ret); |
304 | rw ? "write" : "read", err_ret); | ||
305 | 313 | ||
306 | return err_ret; | 314 | return ret; |
307 | } | 315 | } |
308 | 316 | ||
309 | static int | 317 | static int |
@@ -311,24 +319,17 @@ brcmf_sdiod_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address) | |||
311 | { | 319 | { |
312 | int err = 0, i; | 320 | int err = 0, i; |
313 | u8 addr[3]; | 321 | u8 addr[3]; |
314 | s32 retry; | ||
315 | 322 | ||
316 | addr[0] = (address >> 8) & SBSDIO_SBADDRLOW_MASK; | 323 | addr[0] = (address >> 8) & SBSDIO_SBADDRLOW_MASK; |
317 | addr[1] = (address >> 16) & SBSDIO_SBADDRMID_MASK; | 324 | addr[1] = (address >> 16) & SBSDIO_SBADDRMID_MASK; |
318 | addr[2] = (address >> 24) & SBSDIO_SBADDRHIGH_MASK; | 325 | addr[2] = (address >> 24) & SBSDIO_SBADDRHIGH_MASK; |
319 | 326 | ||
320 | for (i = 0; i < 3; i++) { | 327 | for (i = 0; i < 3; i++) { |
321 | retry = 0; | 328 | err = brcmf_sdiod_regrw_helper(sdiodev, |
322 | do { | 329 | SBSDIO_FUNC1_SBADDRLOW + i, |
323 | if (retry) | 330 | sizeof(u8), &addr[i], true); |
324 | usleep_range(1000, 2000); | ||
325 | err = brcmf_sdiod_request_byte(sdiodev, SDIOH_WRITE, | ||
326 | SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW + i, | ||
327 | &addr[i]); | ||
328 | } while (err != 0 && retry++ < SDIOH_API_ACCESS_RETRY_LIMIT); | ||
329 | |||
330 | if (err) { | 331 | if (err) { |
331 | brcmf_err("failed at addr:0x%0x\n", | 332 | brcmf_err("failed at addr: 0x%0x\n", |
332 | SBSDIO_FUNC1_SBADDRLOW + i); | 333 | SBSDIO_FUNC1_SBADDRLOW + i); |
333 | break; | 334 | break; |
334 | } | 335 | } |
@@ -359,61 +360,14 @@ brcmf_sdiod_addrprep(struct brcmf_sdio_dev *sdiodev, uint width, u32 *addr) | |||
359 | return 0; | 360 | return 0; |
360 | } | 361 | } |
361 | 362 | ||
362 | static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr, | ||
363 | void *data, bool write) | ||
364 | { | ||
365 | u8 func_num, reg_size; | ||
366 | s32 retry = 0; | ||
367 | int ret; | ||
368 | |||
369 | /* | ||
370 | * figure out how to read the register based on address range | ||
371 | * 0x00 ~ 0x7FF: function 0 CCCR and FBR | ||
372 | * 0x10000 ~ 0x1FFFF: function 1 miscellaneous registers | ||
373 | * The rest: function 1 silicon backplane core registers | ||
374 | */ | ||
375 | if ((addr & ~REG_F0_REG_MASK) == 0) { | ||
376 | func_num = SDIO_FUNC_0; | ||
377 | reg_size = 1; | ||
378 | } else if ((addr & ~REG_F1_MISC_MASK) == 0) { | ||
379 | func_num = SDIO_FUNC_1; | ||
380 | reg_size = 1; | ||
381 | } else { | ||
382 | func_num = SDIO_FUNC_1; | ||
383 | reg_size = 4; | ||
384 | |||
385 | ret = brcmf_sdiod_addrprep(sdiodev, reg_size, &addr); | ||
386 | if (ret) | ||
387 | goto done; | ||
388 | } | ||
389 | |||
390 | do { | ||
391 | if (!write) | ||
392 | memset(data, 0, reg_size); | ||
393 | if (retry) /* wait for 1 ms till bus get settled down */ | ||
394 | usleep_range(1000, 2000); | ||
395 | if (reg_size == 1) | ||
396 | ret = brcmf_sdiod_request_byte(sdiodev, write, | ||
397 | func_num, addr, data); | ||
398 | else | ||
399 | ret = brcmf_sdiod_request_word(sdiodev, write, | ||
400 | func_num, addr, data, 4); | ||
401 | } while (ret != 0 && retry++ < SDIOH_API_ACCESS_RETRY_LIMIT); | ||
402 | |||
403 | done: | ||
404 | if (ret != 0) | ||
405 | brcmf_err("failed with %d\n", ret); | ||
406 | |||
407 | return ret; | ||
408 | } | ||
409 | |||
410 | u8 brcmf_sdiod_regrb(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret) | 363 | u8 brcmf_sdiod_regrb(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret) |
411 | { | 364 | { |
412 | u8 data; | 365 | u8 data; |
413 | int retval; | 366 | int retval; |
414 | 367 | ||
415 | brcmf_dbg(SDIO, "addr:0x%08x\n", addr); | 368 | brcmf_dbg(SDIO, "addr:0x%08x\n", addr); |
416 | retval = brcmf_sdiod_regrw_helper(sdiodev, addr, &data, false); | 369 | retval = brcmf_sdiod_regrw_helper(sdiodev, addr, sizeof(data), &data, |
370 | false); | ||
417 | brcmf_dbg(SDIO, "data:0x%02x\n", data); | 371 | brcmf_dbg(SDIO, "data:0x%02x\n", data); |
418 | 372 | ||
419 | if (ret) | 373 | if (ret) |
@@ -428,9 +382,14 @@ u32 brcmf_sdiod_regrl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret) | |||
428 | int retval; | 382 | int retval; |
429 | 383 | ||
430 | brcmf_dbg(SDIO, "addr:0x%08x\n", addr); | 384 | brcmf_dbg(SDIO, "addr:0x%08x\n", addr); |
431 | retval = brcmf_sdiod_regrw_helper(sdiodev, addr, &data, false); | 385 | retval = brcmf_sdiod_addrprep(sdiodev, sizeof(data), &addr); |
386 | if (retval) | ||
387 | goto done; | ||
388 | retval = brcmf_sdiod_regrw_helper(sdiodev, addr, sizeof(data), &data, | ||
389 | false); | ||
432 | brcmf_dbg(SDIO, "data:0x%08x\n", data); | 390 | brcmf_dbg(SDIO, "data:0x%08x\n", data); |
433 | 391 | ||
392 | done: | ||
434 | if (ret) | 393 | if (ret) |
435 | *ret = retval; | 394 | *ret = retval; |
436 | 395 | ||
@@ -443,8 +402,8 @@ void brcmf_sdiod_regwb(struct brcmf_sdio_dev *sdiodev, u32 addr, | |||
443 | int retval; | 402 | int retval; |
444 | 403 | ||
445 | brcmf_dbg(SDIO, "addr:0x%08x, data:0x%02x\n", addr, data); | 404 | brcmf_dbg(SDIO, "addr:0x%08x, data:0x%02x\n", addr, data); |
446 | retval = brcmf_sdiod_regrw_helper(sdiodev, addr, &data, true); | 405 | retval = brcmf_sdiod_regrw_helper(sdiodev, addr, sizeof(data), &data, |
447 | 406 | true); | |
448 | if (ret) | 407 | if (ret) |
449 | *ret = retval; | 408 | *ret = retval; |
450 | } | 409 | } |
@@ -455,8 +414,13 @@ void brcmf_sdiod_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr, | |||
455 | int retval; | 414 | int retval; |
456 | 415 | ||
457 | brcmf_dbg(SDIO, "addr:0x%08x, data:0x%08x\n", addr, data); | 416 | brcmf_dbg(SDIO, "addr:0x%08x, data:0x%08x\n", addr, data); |
458 | retval = brcmf_sdiod_regrw_helper(sdiodev, addr, &data, true); | 417 | retval = brcmf_sdiod_addrprep(sdiodev, sizeof(data), &addr); |
418 | if (retval) | ||
419 | goto done; | ||
420 | retval = brcmf_sdiod_regrw_helper(sdiodev, addr, sizeof(data), &data, | ||
421 | true); | ||
459 | 422 | ||
423 | done: | ||
460 | if (ret) | 424 | if (ret) |
461 | *ret = retval; | 425 | *ret = retval; |
462 | } | 426 | } |
@@ -879,8 +843,8 @@ int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, uint fn) | |||
879 | brcmf_dbg(SDIO, "Enter\n"); | 843 | brcmf_dbg(SDIO, "Enter\n"); |
880 | 844 | ||
881 | /* issue abort cmd52 command through F0 */ | 845 | /* issue abort cmd52 command through F0 */ |
882 | brcmf_sdiod_request_byte(sdiodev, SDIOH_WRITE, SDIO_FUNC_0, | 846 | brcmf_sdiod_request_data(sdiodev, SDIO_FUNC_0, SDIO_CCCR_ABORT, |
883 | SDIO_CCCR_ABORT, &t_func); | 847 | sizeof(t_func), &t_func, true); |
884 | 848 | ||
885 | brcmf_dbg(SDIO, "Exit\n"); | 849 | brcmf_dbg(SDIO, "Exit\n"); |
886 | return 0; | 850 | return 0; |
@@ -981,6 +945,7 @@ static const struct sdio_device_id brcmf_sdmmc_ids[] = { | |||
981 | {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4329)}, | 945 | {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4329)}, |
982 | {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4330)}, | 946 | {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4330)}, |
983 | {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4334)}, | 947 | {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4334)}, |
948 | {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_43362)}, | ||
984 | {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, | 949 | {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, |
985 | SDIO_DEVICE_ID_BROADCOM_4335_4339)}, | 950 | SDIO_DEVICE_ID_BROADCOM_4335_4339)}, |
986 | { /* end: all zeroes */ }, | 951 | { /* end: all zeroes */ }, |
@@ -1037,7 +1002,6 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func, | |||
1037 | sdiodev->pdata = brcmfmac_sdio_pdata; | 1002 | sdiodev->pdata = brcmfmac_sdio_pdata; |
1038 | 1003 | ||
1039 | atomic_set(&sdiodev->suspend, false); | 1004 | atomic_set(&sdiodev->suspend, false); |
1040 | init_waitqueue_head(&sdiodev->request_byte_wait); | ||
1041 | init_waitqueue_head(&sdiodev->request_word_wait); | 1005 | init_waitqueue_head(&sdiodev->request_word_wait); |
1042 | init_waitqueue_head(&sdiodev->request_buffer_wait); | 1006 | init_waitqueue_head(&sdiodev->request_buffer_wait); |
1043 | 1007 | ||
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h index 252024bcbc3b..939d6b132922 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h | |||
@@ -21,8 +21,6 @@ | |||
21 | #ifndef _BRCMF_H_ | 21 | #ifndef _BRCMF_H_ |
22 | #define _BRCMF_H_ | 22 | #define _BRCMF_H_ |
23 | 23 | ||
24 | #define BRCMF_VERSION_STR "4.218.248.5" | ||
25 | |||
26 | #include "fweh.h" | 24 | #include "fweh.h" |
27 | 25 | ||
28 | #define TOE_TX_CSUM_OL 0x00000001 | 26 | #define TOE_TX_CSUM_OL 0x00000001 |
@@ -39,6 +37,11 @@ | |||
39 | #define BRCMF_DCMD_MEDLEN 1536 | 37 | #define BRCMF_DCMD_MEDLEN 1536 |
40 | #define BRCMF_DCMD_MAXLEN 8192 | 38 | #define BRCMF_DCMD_MAXLEN 8192 |
41 | 39 | ||
40 | /* IOCTL from host to device are limited in lenght. A device can only handle | ||
41 | * ethernet frame size. This limitation is to be applied by protocol layer. | ||
42 | */ | ||
43 | #define BRCMF_TX_IOCTL_MAX_MSG_SIZE (ETH_FRAME_LEN+ETH_FCS_LEN) | ||
44 | |||
42 | #define BRCMF_AMPDU_RX_REORDER_MAXFLOWS 256 | 45 | #define BRCMF_AMPDU_RX_REORDER_MAXFLOWS 256 |
43 | 46 | ||
44 | /* Length of firmware version string stored for | 47 | /* Length of firmware version string stored for |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c index 548dbb5542c6..6a8983a1fb9c 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c | |||
@@ -32,15 +32,6 @@ | |||
32 | #define BRCMF_DEFAULT_SCAN_UNASSOC_TIME 40 | 32 | #define BRCMF_DEFAULT_SCAN_UNASSOC_TIME 40 |
33 | #define BRCMF_DEFAULT_PACKET_FILTER "100 0 0 0 0x01 0x00" | 33 | #define BRCMF_DEFAULT_PACKET_FILTER "100 0 0 0 0x01 0x00" |
34 | 34 | ||
35 | #ifdef DEBUG | ||
36 | static const char brcmf_version[] = | ||
37 | "Dongle Host Driver, version " BRCMF_VERSION_STR "\nCompiled on " | ||
38 | __DATE__ " at " __TIME__; | ||
39 | #else | ||
40 | static const char brcmf_version[] = | ||
41 | "Dongle Host Driver, version " BRCMF_VERSION_STR; | ||
42 | #endif | ||
43 | |||
44 | 35 | ||
45 | bool brcmf_c_prec_enq(struct device *dev, struct pktq *q, | 36 | bool brcmf_c_prec_enq(struct device *dev, struct pktq *q, |
46 | struct sk_buff *pkt, int prec) | 37 | struct sk_buff *pkt, int prec) |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index bce0b8e511fd..af39edae8c62 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c | |||
@@ -702,7 +702,7 @@ int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked) | |||
702 | 702 | ||
703 | brcmf_dbg(INFO, "%s: Broadcom Dongle Host Driver\n", ndev->name); | 703 | brcmf_dbg(INFO, "%s: Broadcom Dongle Host Driver\n", ndev->name); |
704 | 704 | ||
705 | ndev->destructor = free_netdev; | 705 | ndev->destructor = brcmf_cfg80211_free_netdev; |
706 | return 0; | 706 | return 0; |
707 | 707 | ||
708 | fail: | 708 | fail: |
@@ -859,8 +859,6 @@ void brcmf_del_if(struct brcmf_pub *drvr, s32 bssidx) | |||
859 | } | 859 | } |
860 | /* unregister will take care of freeing it */ | 860 | /* unregister will take care of freeing it */ |
861 | unregister_netdev(ifp->ndev); | 861 | unregister_netdev(ifp->ndev); |
862 | if (bssidx == 0) | ||
863 | brcmf_cfg80211_detach(drvr->config); | ||
864 | } else { | 862 | } else { |
865 | kfree(ifp); | 863 | kfree(ifp); |
866 | } | 864 | } |
@@ -963,8 +961,7 @@ int brcmf_bus_start(struct device *dev) | |||
963 | fail: | 961 | fail: |
964 | if (ret < 0) { | 962 | if (ret < 0) { |
965 | brcmf_err("failed: %d\n", ret); | 963 | brcmf_err("failed: %d\n", ret); |
966 | if (drvr->config) | 964 | brcmf_cfg80211_detach(drvr->config); |
967 | brcmf_cfg80211_detach(drvr->config); | ||
968 | if (drvr->fws) { | 965 | if (drvr->fws) { |
969 | brcmf_fws_del_interface(ifp); | 966 | brcmf_fws_del_interface(ifp); |
970 | brcmf_fws_deinit(drvr); | 967 | brcmf_fws_deinit(drvr); |
@@ -1039,6 +1036,8 @@ void brcmf_detach(struct device *dev) | |||
1039 | brcmf_del_if(drvr, i); | 1036 | brcmf_del_if(drvr, i); |
1040 | } | 1037 | } |
1041 | 1038 | ||
1039 | brcmf_cfg80211_detach(drvr->config); | ||
1040 | |||
1042 | brcmf_bus_detach(drvr); | 1041 | brcmf_bus_detach(drvr); |
1043 | 1042 | ||
1044 | brcmf_proto_detach(drvr); | 1043 | brcmf_proto_detach(drvr); |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index f214510e3bee..9c7f08a13105 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | |||
@@ -509,6 +509,8 @@ enum brcmf_sdio_frmtype { | |||
509 | #define BCM4334_NVRAM_NAME "brcm/brcmfmac4334-sdio.txt" | 509 | #define BCM4334_NVRAM_NAME "brcm/brcmfmac4334-sdio.txt" |
510 | #define BCM4335_FIRMWARE_NAME "brcm/brcmfmac4335-sdio.bin" | 510 | #define BCM4335_FIRMWARE_NAME "brcm/brcmfmac4335-sdio.bin" |
511 | #define BCM4335_NVRAM_NAME "brcm/brcmfmac4335-sdio.txt" | 511 | #define BCM4335_NVRAM_NAME "brcm/brcmfmac4335-sdio.txt" |
512 | #define BCM43362_FIRMWARE_NAME "brcm/brcmfmac43362-sdio.bin" | ||
513 | #define BCM43362_NVRAM_NAME "brcm/brcmfmac43362-sdio.txt" | ||
512 | #define BCM4339_FIRMWARE_NAME "brcm/brcmfmac4339-sdio.bin" | 514 | #define BCM4339_FIRMWARE_NAME "brcm/brcmfmac4339-sdio.bin" |
513 | #define BCM4339_NVRAM_NAME "brcm/brcmfmac4339-sdio.txt" | 515 | #define BCM4339_NVRAM_NAME "brcm/brcmfmac4339-sdio.txt" |
514 | 516 | ||
@@ -526,6 +528,8 @@ MODULE_FIRMWARE(BCM4334_FIRMWARE_NAME); | |||
526 | MODULE_FIRMWARE(BCM4334_NVRAM_NAME); | 528 | MODULE_FIRMWARE(BCM4334_NVRAM_NAME); |
527 | MODULE_FIRMWARE(BCM4335_FIRMWARE_NAME); | 529 | MODULE_FIRMWARE(BCM4335_FIRMWARE_NAME); |
528 | MODULE_FIRMWARE(BCM4335_NVRAM_NAME); | 530 | MODULE_FIRMWARE(BCM4335_NVRAM_NAME); |
531 | MODULE_FIRMWARE(BCM43362_FIRMWARE_NAME); | ||
532 | MODULE_FIRMWARE(BCM43362_NVRAM_NAME); | ||
529 | MODULE_FIRMWARE(BCM4339_FIRMWARE_NAME); | 533 | MODULE_FIRMWARE(BCM4339_FIRMWARE_NAME); |
530 | MODULE_FIRMWARE(BCM4339_NVRAM_NAME); | 534 | MODULE_FIRMWARE(BCM4339_NVRAM_NAME); |
531 | 535 | ||
@@ -552,6 +556,7 @@ static const struct brcmf_firmware_names brcmf_fwname_data[] = { | |||
552 | { BCM4330_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4330) }, | 556 | { BCM4330_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4330) }, |
553 | { BCM4334_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4334) }, | 557 | { BCM4334_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4334) }, |
554 | { BCM4335_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4335) }, | 558 | { BCM4335_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4335) }, |
559 | { BCM43362_CHIP_ID, 0xFFFFFFFE, BRCMF_FIRMWARE_NVRAM(BCM43362) }, | ||
555 | { BCM4339_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4339) } | 560 | { BCM4339_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4339) } |
556 | }; | 561 | }; |
557 | 562 | ||
@@ -3384,7 +3389,8 @@ err: | |||
3384 | 3389 | ||
3385 | static bool brcmf_sdio_sr_capable(struct brcmf_sdio *bus) | 3390 | static bool brcmf_sdio_sr_capable(struct brcmf_sdio *bus) |
3386 | { | 3391 | { |
3387 | u32 addr, reg; | 3392 | u32 addr, reg, pmu_cc3_mask = ~0; |
3393 | int err; | ||
3388 | 3394 | ||
3389 | brcmf_dbg(TRACE, "Enter\n"); | 3395 | brcmf_dbg(TRACE, "Enter\n"); |
3390 | 3396 | ||
@@ -3392,13 +3398,27 @@ static bool brcmf_sdio_sr_capable(struct brcmf_sdio *bus) | |||
3392 | if (bus->ci->pmurev < 17) | 3398 | if (bus->ci->pmurev < 17) |
3393 | return false; | 3399 | return false; |
3394 | 3400 | ||
3395 | /* read PMU chipcontrol register 3*/ | 3401 | switch (bus->ci->chip) { |
3396 | addr = CORE_CC_REG(bus->ci->c_inf[0].base, chipcontrol_addr); | 3402 | case BCM43241_CHIP_ID: |
3397 | brcmf_sdiod_regwl(bus->sdiodev, addr, 3, NULL); | 3403 | case BCM4335_CHIP_ID: |
3398 | addr = CORE_CC_REG(bus->ci->c_inf[0].base, chipcontrol_data); | 3404 | case BCM4339_CHIP_ID: |
3399 | reg = brcmf_sdiod_regrl(bus->sdiodev, addr, NULL); | 3405 | /* read PMU chipcontrol register 3 */ |
3406 | addr = CORE_CC_REG(bus->ci->c_inf[0].base, chipcontrol_addr); | ||
3407 | brcmf_sdiod_regwl(bus->sdiodev, addr, 3, NULL); | ||
3408 | addr = CORE_CC_REG(bus->ci->c_inf[0].base, chipcontrol_data); | ||
3409 | reg = brcmf_sdiod_regrl(bus->sdiodev, addr, NULL); | ||
3410 | return (reg & pmu_cc3_mask) != 0; | ||
3411 | default: | ||
3412 | addr = CORE_CC_REG(bus->ci->c_inf[0].base, pmucapabilities_ext); | ||
3413 | reg = brcmf_sdiod_regrl(bus->sdiodev, addr, &err); | ||
3414 | if ((reg & PCAPEXT_SR_SUPPORTED_MASK) == 0) | ||
3415 | return false; | ||
3400 | 3416 | ||
3401 | return (bool)reg; | 3417 | addr = CORE_CC_REG(bus->ci->c_inf[0].base, retention_ctl); |
3418 | reg = brcmf_sdiod_regrl(bus->sdiodev, addr, NULL); | ||
3419 | return (reg & (PMU_RCTL_MACPHY_DISABLE_MASK | | ||
3420 | PMU_RCTL_LOGIC_DISABLE_MASK)) == 0; | ||
3421 | } | ||
3402 | } | 3422 | } |
3403 | 3423 | ||
3404 | static void brcmf_sdio_sr_init(struct brcmf_sdio *bus) | 3424 | static void brcmf_sdio_sr_init(struct brcmf_sdio *bus) |
@@ -3615,7 +3635,7 @@ static int brcmf_sdio_bus_init(struct device *dev) | |||
3615 | } | 3635 | } |
3616 | 3636 | ||
3617 | /* If we didn't come up, turn off backplane clock */ | 3637 | /* If we didn't come up, turn off backplane clock */ |
3618 | if (bus_if->state != BRCMF_BUS_DATA) | 3638 | if (ret != 0) |
3619 | brcmf_sdio_clkctl(bus, CLK_NONE, false); | 3639 | brcmf_sdio_clkctl(bus, CLK_NONE, false); |
3620 | 3640 | ||
3621 | exit: | 3641 | exit: |
@@ -3750,31 +3770,6 @@ static void brcmf_sdio_dataworker(struct work_struct *work) | |||
3750 | } | 3770 | } |
3751 | } | 3771 | } |
3752 | 3772 | ||
3753 | static void brcmf_sdio_release_malloc(struct brcmf_sdio *bus) | ||
3754 | { | ||
3755 | brcmf_dbg(TRACE, "Enter\n"); | ||
3756 | |||
3757 | kfree(bus->rxbuf); | ||
3758 | bus->rxctl = bus->rxbuf = NULL; | ||
3759 | bus->rxlen = 0; | ||
3760 | } | ||
3761 | |||
3762 | static bool brcmf_sdio_probe_malloc(struct brcmf_sdio *bus) | ||
3763 | { | ||
3764 | brcmf_dbg(TRACE, "Enter\n"); | ||
3765 | |||
3766 | if (bus->sdiodev->bus_if->maxctl) { | ||
3767 | bus->rxblen = | ||
3768 | roundup((bus->sdiodev->bus_if->maxctl + SDPCM_HDRLEN), | ||
3769 | ALIGNMENT) + bus->head_align; | ||
3770 | bus->rxbuf = kmalloc(bus->rxblen, GFP_ATOMIC); | ||
3771 | if (!(bus->rxbuf)) | ||
3772 | return false; | ||
3773 | } | ||
3774 | |||
3775 | return true; | ||
3776 | } | ||
3777 | |||
3778 | static bool | 3773 | static bool |
3779 | brcmf_sdio_probe_attach(struct brcmf_sdio *bus) | 3774 | brcmf_sdio_probe_attach(struct brcmf_sdio *bus) |
3780 | { | 3775 | { |
@@ -3888,39 +3883,6 @@ fail: | |||
3888 | return false; | 3883 | return false; |
3889 | } | 3884 | } |
3890 | 3885 | ||
3891 | static bool brcmf_sdio_probe_init(struct brcmf_sdio *bus) | ||
3892 | { | ||
3893 | brcmf_dbg(TRACE, "Enter\n"); | ||
3894 | |||
3895 | sdio_claim_host(bus->sdiodev->func[1]); | ||
3896 | |||
3897 | /* Disable F2 to clear any intermediate frame state on the dongle */ | ||
3898 | sdio_disable_func(bus->sdiodev->func[SDIO_FUNC_2]); | ||
3899 | |||
3900 | bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN; | ||
3901 | bus->rxflow = false; | ||
3902 | |||
3903 | /* Done with backplane-dependent accesses, can drop clock... */ | ||
3904 | brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL); | ||
3905 | |||
3906 | sdio_release_host(bus->sdiodev->func[1]); | ||
3907 | |||
3908 | /* ...and initialize clock/power states */ | ||
3909 | bus->clkstate = CLK_SDONLY; | ||
3910 | bus->idletime = BRCMF_IDLE_INTERVAL; | ||
3911 | bus->idleclock = BRCMF_IDLE_ACTIVE; | ||
3912 | |||
3913 | /* Query the F2 block size, set roundup accordingly */ | ||
3914 | bus->blocksize = bus->sdiodev->func[2]->cur_blksize; | ||
3915 | bus->roundup = min(max_roundup, bus->blocksize); | ||
3916 | |||
3917 | /* SR state */ | ||
3918 | bus->sleeping = false; | ||
3919 | bus->sr_enabled = false; | ||
3920 | |||
3921 | return true; | ||
3922 | } | ||
3923 | |||
3924 | static int | 3886 | static int |
3925 | brcmf_sdio_watchdog_thread(void *data) | 3887 | brcmf_sdio_watchdog_thread(void *data) |
3926 | { | 3888 | { |
@@ -3955,24 +3917,6 @@ brcmf_sdio_watchdog(unsigned long data) | |||
3955 | } | 3917 | } |
3956 | } | 3918 | } |
3957 | 3919 | ||
3958 | static void brcmf_sdio_release_dongle(struct brcmf_sdio *bus) | ||
3959 | { | ||
3960 | brcmf_dbg(TRACE, "Enter\n"); | ||
3961 | |||
3962 | if (bus->ci) { | ||
3963 | sdio_claim_host(bus->sdiodev->func[1]); | ||
3964 | brcmf_sdio_clkctl(bus, CLK_AVAIL, false); | ||
3965 | brcmf_sdio_clkctl(bus, CLK_NONE, false); | ||
3966 | sdio_release_host(bus->sdiodev->func[1]); | ||
3967 | brcmf_sdio_chip_detach(&bus->ci); | ||
3968 | if (bus->vars && bus->varsz) | ||
3969 | kfree(bus->vars); | ||
3970 | bus->vars = NULL; | ||
3971 | } | ||
3972 | |||
3973 | brcmf_dbg(TRACE, "Disconnected\n"); | ||
3974 | } | ||
3975 | |||
3976 | static struct brcmf_bus_ops brcmf_sdio_bus_ops = { | 3920 | static struct brcmf_bus_ops brcmf_sdio_bus_ops = { |
3977 | .stop = brcmf_sdio_bus_stop, | 3921 | .stop = brcmf_sdio_bus_stop, |
3978 | .preinit = brcmf_sdio_bus_preinit, | 3922 | .preinit = brcmf_sdio_bus_preinit, |
@@ -4066,15 +4010,42 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev) | |||
4066 | } | 4010 | } |
4067 | 4011 | ||
4068 | /* Allocate buffers */ | 4012 | /* Allocate buffers */ |
4069 | if (!(brcmf_sdio_probe_malloc(bus))) { | 4013 | if (bus->sdiodev->bus_if->maxctl) { |
4070 | brcmf_err("brcmf_sdio_probe_malloc failed\n"); | 4014 | bus->rxblen = |
4071 | goto fail; | 4015 | roundup((bus->sdiodev->bus_if->maxctl + SDPCM_HDRLEN), |
4016 | ALIGNMENT) + bus->head_align; | ||
4017 | bus->rxbuf = kmalloc(bus->rxblen, GFP_ATOMIC); | ||
4018 | if (!(bus->rxbuf)) { | ||
4019 | brcmf_err("rxbuf allocation failed\n"); | ||
4020 | goto fail; | ||
4021 | } | ||
4072 | } | 4022 | } |
4073 | 4023 | ||
4074 | if (!(brcmf_sdio_probe_init(bus))) { | 4024 | sdio_claim_host(bus->sdiodev->func[1]); |
4075 | brcmf_err("brcmf_sdio_probe_init failed\n"); | 4025 | |
4076 | goto fail; | 4026 | /* Disable F2 to clear any intermediate frame state on the dongle */ |
4077 | } | 4027 | sdio_disable_func(bus->sdiodev->func[SDIO_FUNC_2]); |
4028 | |||
4029 | bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN; | ||
4030 | bus->rxflow = false; | ||
4031 | |||
4032 | /* Done with backplane-dependent accesses, can drop clock... */ | ||
4033 | brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL); | ||
4034 | |||
4035 | sdio_release_host(bus->sdiodev->func[1]); | ||
4036 | |||
4037 | /* ...and initialize clock/power states */ | ||
4038 | bus->clkstate = CLK_SDONLY; | ||
4039 | bus->idletime = BRCMF_IDLE_INTERVAL; | ||
4040 | bus->idleclock = BRCMF_IDLE_ACTIVE; | ||
4041 | |||
4042 | /* Query the F2 block size, set roundup accordingly */ | ||
4043 | bus->blocksize = bus->sdiodev->func[2]->cur_blksize; | ||
4044 | bus->roundup = min(max_roundup, bus->blocksize); | ||
4045 | |||
4046 | /* SR state */ | ||
4047 | bus->sleeping = false; | ||
4048 | bus->sr_enabled = false; | ||
4078 | 4049 | ||
4079 | brcmf_sdio_debugfs_create(bus); | 4050 | brcmf_sdio_debugfs_create(bus); |
4080 | brcmf_dbg(INFO, "completed!!\n"); | 4051 | brcmf_dbg(INFO, "completed!!\n"); |
@@ -4108,12 +4079,20 @@ void brcmf_sdio_remove(struct brcmf_sdio *bus) | |||
4108 | 4079 | ||
4109 | if (bus->sdiodev->bus_if->drvr) { | 4080 | if (bus->sdiodev->bus_if->drvr) { |
4110 | brcmf_detach(bus->sdiodev->dev); | 4081 | brcmf_detach(bus->sdiodev->dev); |
4111 | brcmf_sdio_release_dongle(bus); | 4082 | } |
4083 | |||
4084 | if (bus->ci) { | ||
4085 | sdio_claim_host(bus->sdiodev->func[1]); | ||
4086 | brcmf_sdio_clkctl(bus, CLK_AVAIL, false); | ||
4087 | brcmf_sdio_clkctl(bus, CLK_NONE, false); | ||
4088 | sdio_release_host(bus->sdiodev->func[1]); | ||
4089 | brcmf_sdio_chip_detach(&bus->ci); | ||
4112 | } | 4090 | } |
4113 | 4091 | ||
4114 | brcmu_pkt_buf_free_skb(bus->txglom_sgpad); | 4092 | brcmu_pkt_buf_free_skb(bus->txglom_sgpad); |
4115 | brcmf_sdio_release_malloc(bus); | 4093 | kfree(bus->rxbuf); |
4116 | kfree(bus->hdrbuf); | 4094 | kfree(bus->hdrbuf); |
4095 | kfree(bus->vars); | ||
4117 | kfree(bus); | 4096 | kfree(bus); |
4118 | } | 4097 | } |
4119 | 4098 | ||
@@ -4131,7 +4110,7 @@ void brcmf_sdio_wd_timer(struct brcmf_sdio *bus, uint wdtick) | |||
4131 | } | 4110 | } |
4132 | 4111 | ||
4133 | /* don't start the wd until fw is loaded */ | 4112 | /* don't start the wd until fw is loaded */ |
4134 | if (bus->sdiodev->bus_if->state == BRCMF_BUS_DOWN) | 4113 | if (bus->sdiodev->bus_if->state != BRCMF_BUS_DATA) |
4135 | return; | 4114 | return; |
4136 | 4115 | ||
4137 | if (wdtick) { | 4116 | if (wdtick) { |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c index 7918c1033662..c3e7d76dbf35 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c | |||
@@ -1873,7 +1873,7 @@ int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb) | |||
1873 | brcmf_dbg(DATA, "tx proto=0x%X\n", ntohs(eh->h_proto)); | 1873 | brcmf_dbg(DATA, "tx proto=0x%X\n", ntohs(eh->h_proto)); |
1874 | /* determine the priority */ | 1874 | /* determine the priority */ |
1875 | if (!skb->priority) | 1875 | if (!skb->priority) |
1876 | skb->priority = cfg80211_classify8021d(skb); | 1876 | skb->priority = cfg80211_classify8021d(skb, NULL); |
1877 | 1877 | ||
1878 | drvr->tx_multicast += !!multicast; | 1878 | drvr->tx_multicast += !!multicast; |
1879 | if (pae) | 1879 | if (pae) |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c index 185af8a84c9a..fc4f98b275d7 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c | |||
@@ -1955,21 +1955,21 @@ s32 brcmf_p2p_attach(struct brcmf_cfg80211_info *cfg) | |||
1955 | err = brcmf_fil_iovar_int_set(pri_ifp, "p2p_disc", 1); | 1955 | err = brcmf_fil_iovar_int_set(pri_ifp, "p2p_disc", 1); |
1956 | if (err < 0) { | 1956 | if (err < 0) { |
1957 | brcmf_err("set p2p_disc error\n"); | 1957 | brcmf_err("set p2p_disc error\n"); |
1958 | brcmf_free_vif(cfg, p2p_vif); | 1958 | brcmf_free_vif(p2p_vif); |
1959 | goto exit; | 1959 | goto exit; |
1960 | } | 1960 | } |
1961 | /* obtain bsscfg index for P2P discovery */ | 1961 | /* obtain bsscfg index for P2P discovery */ |
1962 | err = brcmf_fil_iovar_int_get(pri_ifp, "p2p_dev", &bssidx); | 1962 | err = brcmf_fil_iovar_int_get(pri_ifp, "p2p_dev", &bssidx); |
1963 | if (err < 0) { | 1963 | if (err < 0) { |
1964 | brcmf_err("retrieving discover bsscfg index failed\n"); | 1964 | brcmf_err("retrieving discover bsscfg index failed\n"); |
1965 | brcmf_free_vif(cfg, p2p_vif); | 1965 | brcmf_free_vif(p2p_vif); |
1966 | goto exit; | 1966 | goto exit; |
1967 | } | 1967 | } |
1968 | /* Verify that firmware uses same bssidx as driver !! */ | 1968 | /* Verify that firmware uses same bssidx as driver !! */ |
1969 | if (p2p_ifp->bssidx != bssidx) { | 1969 | if (p2p_ifp->bssidx != bssidx) { |
1970 | brcmf_err("Incorrect bssidx=%d, compared to p2p_ifp->bssidx=%d\n", | 1970 | brcmf_err("Incorrect bssidx=%d, compared to p2p_ifp->bssidx=%d\n", |
1971 | bssidx, p2p_ifp->bssidx); | 1971 | bssidx, p2p_ifp->bssidx); |
1972 | brcmf_free_vif(cfg, p2p_vif); | 1972 | brcmf_free_vif(p2p_vif); |
1973 | goto exit; | 1973 | goto exit; |
1974 | } | 1974 | } |
1975 | 1975 | ||
@@ -1997,7 +1997,7 @@ void brcmf_p2p_detach(struct brcmf_p2p_info *p2p) | |||
1997 | brcmf_p2p_cancel_remain_on_channel(vif->ifp); | 1997 | brcmf_p2p_cancel_remain_on_channel(vif->ifp); |
1998 | brcmf_p2p_deinit_discovery(p2p); | 1998 | brcmf_p2p_deinit_discovery(p2p); |
1999 | /* remove discovery interface */ | 1999 | /* remove discovery interface */ |
2000 | brcmf_free_vif(p2p->cfg, vif); | 2000 | brcmf_free_vif(vif); |
2001 | p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL; | 2001 | p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL; |
2002 | } | 2002 | } |
2003 | /* just set it all to zero */ | 2003 | /* just set it all to zero */ |
@@ -2222,7 +2222,7 @@ static struct wireless_dev *brcmf_p2p_create_p2pdev(struct brcmf_p2p_info *p2p, | |||
2222 | return &p2p_vif->wdev; | 2222 | return &p2p_vif->wdev; |
2223 | 2223 | ||
2224 | fail: | 2224 | fail: |
2225 | brcmf_free_vif(p2p->cfg, p2p_vif); | 2225 | brcmf_free_vif(p2p_vif); |
2226 | return ERR_PTR(err); | 2226 | return ERR_PTR(err); |
2227 | } | 2227 | } |
2228 | 2228 | ||
@@ -2231,31 +2231,12 @@ fail: | |||
2231 | * | 2231 | * |
2232 | * @vif: virtual interface object to delete. | 2232 | * @vif: virtual interface object to delete. |
2233 | */ | 2233 | */ |
2234 | static void brcmf_p2p_delete_p2pdev(struct brcmf_cfg80211_info *cfg, | 2234 | static void brcmf_p2p_delete_p2pdev(struct brcmf_p2p_info *p2p, |
2235 | struct brcmf_cfg80211_vif *vif) | 2235 | struct brcmf_cfg80211_vif *vif) |
2236 | { | 2236 | { |
2237 | cfg80211_unregister_wdev(&vif->wdev); | 2237 | cfg80211_unregister_wdev(&vif->wdev); |
2238 | cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL; | 2238 | p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL; |
2239 | brcmf_free_vif(cfg, vif); | 2239 | brcmf_free_vif(vif); |
2240 | } | ||
2241 | |||
2242 | /** | ||
2243 | * brcmf_p2p_free_p2p_if() - free up net device related data. | ||
2244 | * | ||
2245 | * @ndev: net device that needs to be freed. | ||
2246 | */ | ||
2247 | static void brcmf_p2p_free_p2p_if(struct net_device *ndev) | ||
2248 | { | ||
2249 | struct brcmf_cfg80211_info *cfg; | ||
2250 | struct brcmf_cfg80211_vif *vif; | ||
2251 | struct brcmf_if *ifp; | ||
2252 | |||
2253 | ifp = netdev_priv(ndev); | ||
2254 | cfg = ifp->drvr->config; | ||
2255 | vif = ifp->vif; | ||
2256 | |||
2257 | brcmf_free_vif(cfg, vif); | ||
2258 | free_netdev(ifp->ndev); | ||
2259 | } | 2240 | } |
2260 | 2241 | ||
2261 | /** | 2242 | /** |
@@ -2335,8 +2316,6 @@ struct wireless_dev *brcmf_p2p_add_vif(struct wiphy *wiphy, const char *name, | |||
2335 | brcmf_err("Registering netdevice failed\n"); | 2316 | brcmf_err("Registering netdevice failed\n"); |
2336 | goto fail; | 2317 | goto fail; |
2337 | } | 2318 | } |
2338 | /* override destructor */ | ||
2339 | ifp->ndev->destructor = brcmf_p2p_free_p2p_if; | ||
2340 | 2319 | ||
2341 | cfg->p2p.bss_idx[P2PAPI_BSSCFG_CONNECTION].vif = vif; | 2320 | cfg->p2p.bss_idx[P2PAPI_BSSCFG_CONNECTION].vif = vif; |
2342 | /* Disable firmware roaming for P2P interface */ | 2321 | /* Disable firmware roaming for P2P interface */ |
@@ -2349,7 +2328,7 @@ struct wireless_dev *brcmf_p2p_add_vif(struct wiphy *wiphy, const char *name, | |||
2349 | return &ifp->vif->wdev; | 2328 | return &ifp->vif->wdev; |
2350 | 2329 | ||
2351 | fail: | 2330 | fail: |
2352 | brcmf_free_vif(cfg, vif); | 2331 | brcmf_free_vif(vif); |
2353 | return ERR_PTR(err); | 2332 | return ERR_PTR(err); |
2354 | } | 2333 | } |
2355 | 2334 | ||
@@ -2358,8 +2337,6 @@ fail: | |||
2358 | * | 2337 | * |
2359 | * @wiphy: wiphy device of interface. | 2338 | * @wiphy: wiphy device of interface. |
2360 | * @wdev: wireless device of interface. | 2339 | * @wdev: wireless device of interface. |
2361 | * | ||
2362 | * TODO: not yet supported. | ||
2363 | */ | 2340 | */ |
2364 | int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev) | 2341 | int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev) |
2365 | { | 2342 | { |
@@ -2385,7 +2362,7 @@ int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev) | |||
2385 | break; | 2362 | break; |
2386 | 2363 | ||
2387 | case NL80211_IFTYPE_P2P_DEVICE: | 2364 | case NL80211_IFTYPE_P2P_DEVICE: |
2388 | brcmf_p2p_delete_p2pdev(cfg, vif); | 2365 | brcmf_p2p_delete_p2pdev(p2p, vif); |
2389 | return 0; | 2366 | return 0; |
2390 | default: | 2367 | default: |
2391 | return -ENOTSUPP; | 2368 | return -ENOTSUPP; |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c index 5f39f28e6efb..9fd40675f18e 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/netdevice.h> | 19 | #include <linux/netdevice.h> |
20 | #include <linux/mmc/card.h> | 20 | #include <linux/mmc/card.h> |
21 | #include <linux/mmc/sdio_func.h> | 21 | #include <linux/mmc/sdio_func.h> |
22 | #include <linux/mmc/sdio_ids.h> | ||
22 | #include <linux/ssb/ssb_regs.h> | 23 | #include <linux/ssb/ssb_regs.h> |
23 | #include <linux/bcma/bcma.h> | 24 | #include <linux/bcma/bcma.h> |
24 | 25 | ||
@@ -83,6 +84,24 @@ static const struct sdiod_drive_str sdiod_drvstr_tab1_1v8[] = { | |||
83 | {0, 0x1} | 84 | {0, 0x1} |
84 | }; | 85 | }; |
85 | 86 | ||
87 | /* SDIO Drive Strength to sel value table for PMU Rev 13 (1.8v) */ | ||
88 | static const struct sdiod_drive_str sdiod_drive_strength_tab5_1v8[] = { | ||
89 | {6, 0x7}, | ||
90 | {5, 0x6}, | ||
91 | {4, 0x5}, | ||
92 | {3, 0x4}, | ||
93 | {2, 0x2}, | ||
94 | {1, 0x1}, | ||
95 | {0, 0x0} | ||
96 | }; | ||
97 | |||
98 | /* SDIO Drive Strength to sel value table for PMU Rev 17 (1.8v) */ | ||
99 | static const struct sdiod_drive_str sdiod_drvstr_tab6_1v8[] = { | ||
100 | {3, 0x3}, | ||
101 | {2, 0x2}, | ||
102 | {1, 0x1}, | ||
103 | {0, 0x0} }; | ||
104 | |||
86 | /* SDIO Drive Strength to sel value table for 43143 PMU Rev 17 (3.3V) */ | 105 | /* SDIO Drive Strength to sel value table for 43143 PMU Rev 17 (3.3V) */ |
87 | static const struct sdiod_drive_str sdiod_drvstr_tab2_3v3[] = { | 106 | static const struct sdiod_drive_str sdiod_drvstr_tab2_3v3[] = { |
88 | {16, 0x7}, | 107 | {16, 0x7}, |
@@ -569,6 +588,23 @@ static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev, | |||
569 | ci->ramsize = 0xc0000; | 588 | ci->ramsize = 0xc0000; |
570 | ci->rambase = 0x180000; | 589 | ci->rambase = 0x180000; |
571 | break; | 590 | break; |
591 | case BCM43362_CHIP_ID: | ||
592 | ci->c_inf[0].wrapbase = 0x18100000; | ||
593 | ci->c_inf[0].cib = 0x27004211; | ||
594 | ci->c_inf[1].id = BCMA_CORE_SDIO_DEV; | ||
595 | ci->c_inf[1].base = 0x18002000; | ||
596 | ci->c_inf[1].wrapbase = 0x18102000; | ||
597 | ci->c_inf[1].cib = 0x0a004211; | ||
598 | ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM; | ||
599 | ci->c_inf[2].base = 0x18004000; | ||
600 | ci->c_inf[2].wrapbase = 0x18104000; | ||
601 | ci->c_inf[2].cib = 0x08080401; | ||
602 | ci->c_inf[3].id = BCMA_CORE_ARM_CM3; | ||
603 | ci->c_inf[3].base = 0x18003000; | ||
604 | ci->c_inf[3].wrapbase = 0x18103000; | ||
605 | ci->c_inf[3].cib = 0x03004211; | ||
606 | ci->ramsize = 0x3C000; | ||
607 | break; | ||
572 | default: | 608 | default: |
573 | brcmf_err("chipid 0x%x is not supported\n", ci->chip); | 609 | brcmf_err("chipid 0x%x is not supported\n", ci->chip); |
574 | return -ENODEV; | 610 | return -ENODEV; |
@@ -757,6 +793,11 @@ brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev, | |||
757 | str_mask = 0x00003800; | 793 | str_mask = 0x00003800; |
758 | str_shift = 11; | 794 | str_shift = 11; |
759 | break; | 795 | break; |
796 | case SDIOD_DRVSTR_KEY(BCM4334_CHIP_ID, 17): | ||
797 | str_tab = sdiod_drvstr_tab6_1v8; | ||
798 | str_mask = 0x00001800; | ||
799 | str_shift = 11; | ||
800 | break; | ||
760 | case SDIOD_DRVSTR_KEY(BCM43143_CHIP_ID, 17): | 801 | case SDIOD_DRVSTR_KEY(BCM43143_CHIP_ID, 17): |
761 | /* note: 43143 does not support tristate */ | 802 | /* note: 43143 does not support tristate */ |
762 | i = ARRAY_SIZE(sdiod_drvstr_tab2_3v3) - 1; | 803 | i = ARRAY_SIZE(sdiod_drvstr_tab2_3v3) - 1; |
@@ -769,6 +810,11 @@ brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev, | |||
769 | brcmf_sdio_chip_name(ci->chip, chn, 8), | 810 | brcmf_sdio_chip_name(ci->chip, chn, 8), |
770 | drivestrength); | 811 | drivestrength); |
771 | break; | 812 | break; |
813 | case SDIOD_DRVSTR_KEY(BCM43362_CHIP_ID, 13): | ||
814 | str_tab = sdiod_drive_strength_tab5_1v8; | ||
815 | str_mask = 0x00003800; | ||
816 | str_shift = 11; | ||
817 | break; | ||
772 | default: | 818 | default: |
773 | brcmf_err("No SDIO Drive strength init done for chip %s rev %d pmurev %d\n", | 819 | brcmf_err("No SDIO Drive strength init done for chip %s rev %d pmurev %d\n", |
774 | brcmf_sdio_chip_name(ci->chip, chn, 8), | 820 | brcmf_sdio_chip_name(ci->chip, chn, 8), |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h index d0f4b45b24c7..7ea424e20773 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h | |||
@@ -54,14 +54,6 @@ | |||
54 | 54 | ||
55 | #define BRCMF_MAX_CORENUM 6 | 55 | #define BRCMF_MAX_CORENUM 6 |
56 | 56 | ||
57 | /* SDIO device ID */ | ||
58 | #define SDIO_DEVICE_ID_BROADCOM_43143 43143 | ||
59 | #define SDIO_DEVICE_ID_BROADCOM_43241 0x4324 | ||
60 | #define SDIO_DEVICE_ID_BROADCOM_4329 0x4329 | ||
61 | #define SDIO_DEVICE_ID_BROADCOM_4330 0x4330 | ||
62 | #define SDIO_DEVICE_ID_BROADCOM_4334 0x4334 | ||
63 | #define SDIO_DEVICE_ID_BROADCOM_4335_4339 0x4335 | ||
64 | |||
65 | struct chip_core_info { | 57 | struct chip_core_info { |
66 | u16 id; | 58 | u16 id; |
67 | u16 rev; | 59 | u16 rev; |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h index a0981b32c729..092e9c824992 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h | |||
@@ -167,7 +167,6 @@ struct brcmf_sdio_dev { | |||
167 | u32 sbwad; /* Save backplane window address */ | 167 | u32 sbwad; /* Save backplane window address */ |
168 | struct brcmf_sdio *bus; | 168 | struct brcmf_sdio *bus; |
169 | atomic_t suspend; /* suspend flag */ | 169 | atomic_t suspend; /* suspend flag */ |
170 | wait_queue_head_t request_byte_wait; | ||
171 | wait_queue_head_t request_word_wait; | 170 | wait_queue_head_t request_word_wait; |
172 | wait_queue_head_t request_buffer_wait; | 171 | wait_queue_head_t request_buffer_wait; |
173 | struct device *dev; | 172 | struct device *dev; |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index 3966fe0fcfd9..aad83aef7d93 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | |||
@@ -1095,10 +1095,10 @@ static void brcmf_link_down(struct brcmf_cfg80211_vif *vif) | |||
1095 | BRCMF_C_DISASSOC, NULL, 0); | 1095 | BRCMF_C_DISASSOC, NULL, 0); |
1096 | if (err) { | 1096 | if (err) { |
1097 | brcmf_err("WLC_DISASSOC failed (%d)\n", err); | 1097 | brcmf_err("WLC_DISASSOC failed (%d)\n", err); |
1098 | cfg80211_disconnected(vif->wdev.netdev, 0, | ||
1099 | NULL, 0, GFP_KERNEL); | ||
1100 | } | 1098 | } |
1101 | clear_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state); | 1099 | clear_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state); |
1100 | cfg80211_disconnected(vif->wdev.netdev, 0, NULL, 0, GFP_KERNEL); | ||
1101 | |||
1102 | } | 1102 | } |
1103 | clear_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state); | 1103 | clear_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state); |
1104 | clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status); | 1104 | clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status); |
@@ -1758,6 +1758,7 @@ brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev, | |||
1758 | return -EIO; | 1758 | return -EIO; |
1759 | 1759 | ||
1760 | clear_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state); | 1760 | clear_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state); |
1761 | cfg80211_disconnected(ndev, reason_code, NULL, 0, GFP_KERNEL); | ||
1761 | 1762 | ||
1762 | memcpy(&scbval.ea, &profile->bssid, ETH_ALEN); | 1763 | memcpy(&scbval.ea, &profile->bssid, ETH_ALEN); |
1763 | scbval.val = cpu_to_le32(reason_code); | 1764 | scbval.val = cpu_to_le32(reason_code); |
@@ -4359,9 +4360,6 @@ struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg, | |||
4359 | { | 4360 | { |
4360 | struct brcmf_cfg80211_vif *vif; | 4361 | struct brcmf_cfg80211_vif *vif; |
4361 | 4362 | ||
4362 | if (cfg->vif_cnt == BRCMF_IFACE_MAX_CNT) | ||
4363 | return ERR_PTR(-ENOSPC); | ||
4364 | |||
4365 | brcmf_dbg(TRACE, "allocating virtual interface (size=%zu)\n", | 4363 | brcmf_dbg(TRACE, "allocating virtual interface (size=%zu)\n", |
4366 | sizeof(*vif)); | 4364 | sizeof(*vif)); |
4367 | vif = kzalloc(sizeof(*vif), GFP_KERNEL); | 4365 | vif = kzalloc(sizeof(*vif), GFP_KERNEL); |
@@ -4378,21 +4376,25 @@ struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg, | |||
4378 | brcmf_init_prof(&vif->profile); | 4376 | brcmf_init_prof(&vif->profile); |
4379 | 4377 | ||
4380 | list_add_tail(&vif->list, &cfg->vif_list); | 4378 | list_add_tail(&vif->list, &cfg->vif_list); |
4381 | cfg->vif_cnt++; | ||
4382 | return vif; | 4379 | return vif; |
4383 | } | 4380 | } |
4384 | 4381 | ||
4385 | void brcmf_free_vif(struct brcmf_cfg80211_info *cfg, | 4382 | void brcmf_free_vif(struct brcmf_cfg80211_vif *vif) |
4386 | struct brcmf_cfg80211_vif *vif) | ||
4387 | { | 4383 | { |
4388 | list_del(&vif->list); | 4384 | list_del(&vif->list); |
4389 | cfg->vif_cnt--; | ||
4390 | |||
4391 | kfree(vif); | 4385 | kfree(vif); |
4392 | if (!cfg->vif_cnt) { | 4386 | } |
4393 | wiphy_unregister(cfg->wiphy); | 4387 | |
4394 | wiphy_free(cfg->wiphy); | 4388 | void brcmf_cfg80211_free_netdev(struct net_device *ndev) |
4395 | } | 4389 | { |
4390 | struct brcmf_cfg80211_vif *vif; | ||
4391 | struct brcmf_if *ifp; | ||
4392 | |||
4393 | ifp = netdev_priv(ndev); | ||
4394 | vif = ifp->vif; | ||
4395 | |||
4396 | brcmf_free_vif(vif); | ||
4397 | free_netdev(ndev); | ||
4396 | } | 4398 | } |
4397 | 4399 | ||
4398 | static bool brcmf_is_linkup(const struct brcmf_event_msg *e) | 4400 | static bool brcmf_is_linkup(const struct brcmf_event_msg *e) |
@@ -4979,20 +4981,20 @@ cfg80211_p2p_attach_out: | |||
4979 | wl_deinit_priv(cfg); | 4981 | wl_deinit_priv(cfg); |
4980 | 4982 | ||
4981 | cfg80211_attach_out: | 4983 | cfg80211_attach_out: |
4982 | brcmf_free_vif(cfg, vif); | 4984 | brcmf_free_vif(vif); |
4983 | return NULL; | 4985 | return NULL; |
4984 | } | 4986 | } |
4985 | 4987 | ||
4986 | void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg) | 4988 | void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg) |
4987 | { | 4989 | { |
4988 | struct brcmf_cfg80211_vif *vif; | 4990 | if (!cfg) |
4989 | struct brcmf_cfg80211_vif *tmp; | 4991 | return; |
4990 | 4992 | ||
4991 | wl_deinit_priv(cfg); | 4993 | WARN_ON(!list_empty(&cfg->vif_list)); |
4994 | wiphy_unregister(cfg->wiphy); | ||
4992 | brcmf_btcoex_detach(cfg); | 4995 | brcmf_btcoex_detach(cfg); |
4993 | list_for_each_entry_safe(vif, tmp, &cfg->vif_list, list) { | 4996 | wl_deinit_priv(cfg); |
4994 | brcmf_free_vif(cfg, vif); | 4997 | wiphy_free(cfg->wiphy); |
4995 | } | ||
4996 | } | 4998 | } |
4997 | 4999 | ||
4998 | static s32 | 5000 | static s32 |
@@ -5087,7 +5089,8 @@ dongle_scantime_out: | |||
5087 | } | 5089 | } |
5088 | 5090 | ||
5089 | 5091 | ||
5090 | static s32 brcmf_construct_reginfo(struct brcmf_cfg80211_info *cfg, u32 bw_cap) | 5092 | static s32 brcmf_construct_reginfo(struct brcmf_cfg80211_info *cfg, |
5093 | u32 bw_cap[]) | ||
5091 | { | 5094 | { |
5092 | struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); | 5095 | struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); |
5093 | struct ieee80211_channel *band_chan_arr; | 5096 | struct ieee80211_channel *band_chan_arr; |
@@ -5100,7 +5103,6 @@ static s32 brcmf_construct_reginfo(struct brcmf_cfg80211_info *cfg, u32 bw_cap) | |||
5100 | enum ieee80211_band band; | 5103 | enum ieee80211_band band; |
5101 | u32 channel; | 5104 | u32 channel; |
5102 | u32 *n_cnt; | 5105 | u32 *n_cnt; |
5103 | bool ht40_allowed; | ||
5104 | u32 index; | 5106 | u32 index; |
5105 | u32 ht40_flag; | 5107 | u32 ht40_flag; |
5106 | bool update; | 5108 | bool update; |
@@ -5133,18 +5135,17 @@ static s32 brcmf_construct_reginfo(struct brcmf_cfg80211_info *cfg, u32 bw_cap) | |||
5133 | array_size = ARRAY_SIZE(__wl_2ghz_channels); | 5135 | array_size = ARRAY_SIZE(__wl_2ghz_channels); |
5134 | n_cnt = &__wl_band_2ghz.n_channels; | 5136 | n_cnt = &__wl_band_2ghz.n_channels; |
5135 | band = IEEE80211_BAND_2GHZ; | 5137 | band = IEEE80211_BAND_2GHZ; |
5136 | ht40_allowed = (bw_cap == WLC_N_BW_40ALL); | ||
5137 | } else if (ch.band == BRCMU_CHAN_BAND_5G) { | 5138 | } else if (ch.band == BRCMU_CHAN_BAND_5G) { |
5138 | band_chan_arr = __wl_5ghz_a_channels; | 5139 | band_chan_arr = __wl_5ghz_a_channels; |
5139 | array_size = ARRAY_SIZE(__wl_5ghz_a_channels); | 5140 | array_size = ARRAY_SIZE(__wl_5ghz_a_channels); |
5140 | n_cnt = &__wl_band_5ghz_a.n_channels; | 5141 | n_cnt = &__wl_band_5ghz_a.n_channels; |
5141 | band = IEEE80211_BAND_5GHZ; | 5142 | band = IEEE80211_BAND_5GHZ; |
5142 | ht40_allowed = !(bw_cap == WLC_N_BW_20ALL); | ||
5143 | } else { | 5143 | } else { |
5144 | brcmf_err("Invalid channel Sepc. 0x%x.\n", ch.chspec); | 5144 | brcmf_err("Invalid channel Spec. 0x%x.\n", ch.chspec); |
5145 | continue; | 5145 | continue; |
5146 | } | 5146 | } |
5147 | if (!ht40_allowed && ch.bw == BRCMU_CHAN_BW_40) | 5147 | if (!(bw_cap[band] & WLC_BW_40MHZ_BIT) && |
5148 | ch.bw == BRCMU_CHAN_BW_40) | ||
5148 | continue; | 5149 | continue; |
5149 | update = false; | 5150 | update = false; |
5150 | for (j = 0; (j < *n_cnt && (*n_cnt < array_size)); j++) { | 5151 | for (j = 0; (j < *n_cnt && (*n_cnt < array_size)); j++) { |
@@ -5162,7 +5163,10 @@ static s32 brcmf_construct_reginfo(struct brcmf_cfg80211_info *cfg, u32 bw_cap) | |||
5162 | ieee80211_channel_to_frequency(ch.chnum, band); | 5163 | ieee80211_channel_to_frequency(ch.chnum, band); |
5163 | band_chan_arr[index].hw_value = ch.chnum; | 5164 | band_chan_arr[index].hw_value = ch.chnum; |
5164 | 5165 | ||
5165 | if (ch.bw == BRCMU_CHAN_BW_40 && ht40_allowed) { | 5166 | brcmf_err("channel %d: f=%d bw=%d sb=%d\n", |
5167 | ch.chnum, band_chan_arr[index].center_freq, | ||
5168 | ch.bw, ch.sb); | ||
5169 | if (ch.bw == BRCMU_CHAN_BW_40) { | ||
5166 | /* assuming the order is HT20, HT40 Upper, | 5170 | /* assuming the order is HT20, HT40 Upper, |
5167 | * HT40 lower from chanspecs | 5171 | * HT40 lower from chanspecs |
5168 | */ | 5172 | */ |
@@ -5213,6 +5217,46 @@ exit: | |||
5213 | return err; | 5217 | return err; |
5214 | } | 5218 | } |
5215 | 5219 | ||
5220 | static void brcmf_get_bwcap(struct brcmf_if *ifp, u32 bw_cap[]) | ||
5221 | { | ||
5222 | u32 band, mimo_bwcap; | ||
5223 | int err; | ||
5224 | |||
5225 | band = WLC_BAND_2G; | ||
5226 | err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &band); | ||
5227 | if (!err) { | ||
5228 | bw_cap[IEEE80211_BAND_2GHZ] = band; | ||
5229 | band = WLC_BAND_5G; | ||
5230 | err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &band); | ||
5231 | if (!err) { | ||
5232 | bw_cap[IEEE80211_BAND_5GHZ] = band; | ||
5233 | return; | ||
5234 | } | ||
5235 | WARN_ON(1); | ||
5236 | return; | ||
5237 | } | ||
5238 | brcmf_dbg(INFO, "fallback to mimo_bw_cap info\n"); | ||
5239 | mimo_bwcap = 0; | ||
5240 | err = brcmf_fil_iovar_int_get(ifp, "mimo_bw_cap", &mimo_bwcap); | ||
5241 | if (err) | ||
5242 | /* assume 20MHz if firmware does not give a clue */ | ||
5243 | mimo_bwcap = WLC_N_BW_20ALL; | ||
5244 | |||
5245 | switch (mimo_bwcap) { | ||
5246 | case WLC_N_BW_40ALL: | ||
5247 | bw_cap[IEEE80211_BAND_2GHZ] |= WLC_BW_40MHZ_BIT; | ||
5248 | /* fall-thru */ | ||
5249 | case WLC_N_BW_20IN2G_40IN5G: | ||
5250 | bw_cap[IEEE80211_BAND_5GHZ] |= WLC_BW_40MHZ_BIT; | ||
5251 | /* fall-thru */ | ||
5252 | case WLC_N_BW_20ALL: | ||
5253 | bw_cap[IEEE80211_BAND_2GHZ] |= WLC_BW_20MHZ_BIT; | ||
5254 | bw_cap[IEEE80211_BAND_5GHZ] |= WLC_BW_20MHZ_BIT; | ||
5255 | break; | ||
5256 | default: | ||
5257 | brcmf_err("invalid mimo_bw_cap value\n"); | ||
5258 | } | ||
5259 | } | ||
5216 | 5260 | ||
5217 | static s32 brcmf_update_wiphybands(struct brcmf_cfg80211_info *cfg) | 5261 | static s32 brcmf_update_wiphybands(struct brcmf_cfg80211_info *cfg) |
5218 | { | 5262 | { |
@@ -5221,13 +5265,13 @@ static s32 brcmf_update_wiphybands(struct brcmf_cfg80211_info *cfg) | |||
5221 | s32 phy_list; | 5265 | s32 phy_list; |
5222 | u32 band_list[3]; | 5266 | u32 band_list[3]; |
5223 | u32 nmode; | 5267 | u32 nmode; |
5224 | u32 bw_cap = 0; | 5268 | u32 bw_cap[2] = { 0, 0 }; |
5225 | s8 phy; | 5269 | s8 phy; |
5226 | s32 err; | 5270 | s32 err; |
5227 | u32 nband; | 5271 | u32 nband; |
5228 | s32 i; | 5272 | s32 i; |
5229 | struct ieee80211_supported_band *bands[IEEE80211_NUM_BANDS]; | 5273 | struct ieee80211_supported_band *bands[2] = { NULL, NULL }; |
5230 | s32 index; | 5274 | struct ieee80211_supported_band *band; |
5231 | 5275 | ||
5232 | err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_PHYLIST, | 5276 | err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_PHYLIST, |
5233 | &phy_list, sizeof(phy_list)); | 5277 | &phy_list, sizeof(phy_list)); |
@@ -5253,11 +5297,10 @@ static s32 brcmf_update_wiphybands(struct brcmf_cfg80211_info *cfg) | |||
5253 | if (err) { | 5297 | if (err) { |
5254 | brcmf_err("nmode error (%d)\n", err); | 5298 | brcmf_err("nmode error (%d)\n", err); |
5255 | } else { | 5299 | } else { |
5256 | err = brcmf_fil_iovar_int_get(ifp, "mimo_bw_cap", &bw_cap); | 5300 | brcmf_get_bwcap(ifp, bw_cap); |
5257 | if (err) | ||
5258 | brcmf_err("mimo_bw_cap error (%d)\n", err); | ||
5259 | } | 5301 | } |
5260 | brcmf_dbg(INFO, "nmode=%d, mimo_bw_cap=%d\n", nmode, bw_cap); | 5302 | brcmf_dbg(INFO, "nmode=%d, bw_cap=(%d, %d)\n", nmode, |
5303 | bw_cap[IEEE80211_BAND_2GHZ], bw_cap[IEEE80211_BAND_5GHZ]); | ||
5261 | 5304 | ||
5262 | err = brcmf_construct_reginfo(cfg, bw_cap); | 5305 | err = brcmf_construct_reginfo(cfg, bw_cap); |
5263 | if (err) { | 5306 | if (err) { |
@@ -5266,40 +5309,33 @@ static s32 brcmf_update_wiphybands(struct brcmf_cfg80211_info *cfg) | |||
5266 | } | 5309 | } |
5267 | 5310 | ||
5268 | nband = band_list[0]; | 5311 | nband = band_list[0]; |
5269 | memset(bands, 0, sizeof(bands)); | ||
5270 | 5312 | ||
5271 | for (i = 1; i <= nband && i < ARRAY_SIZE(band_list); i++) { | 5313 | for (i = 1; i <= nband && i < ARRAY_SIZE(band_list); i++) { |
5272 | index = -1; | 5314 | band = NULL; |
5273 | if ((band_list[i] == WLC_BAND_5G) && | 5315 | if ((band_list[i] == WLC_BAND_5G) && |
5274 | (__wl_band_5ghz_a.n_channels > 0)) { | 5316 | (__wl_band_5ghz_a.n_channels > 0)) |
5275 | index = IEEE80211_BAND_5GHZ; | 5317 | band = &__wl_band_5ghz_a; |
5276 | bands[index] = &__wl_band_5ghz_a; | 5318 | else if ((band_list[i] == WLC_BAND_2G) && |
5277 | if ((bw_cap == WLC_N_BW_40ALL) || | 5319 | (__wl_band_2ghz.n_channels > 0)) |
5278 | (bw_cap == WLC_N_BW_20IN2G_40IN5G)) | 5320 | band = &__wl_band_2ghz; |
5279 | bands[index]->ht_cap.cap |= | 5321 | else |
5280 | IEEE80211_HT_CAP_SGI_40; | 5322 | continue; |
5281 | } else if ((band_list[i] == WLC_BAND_2G) && | ||
5282 | (__wl_band_2ghz.n_channels > 0)) { | ||
5283 | index = IEEE80211_BAND_2GHZ; | ||
5284 | bands[index] = &__wl_band_2ghz; | ||
5285 | if (bw_cap == WLC_N_BW_40ALL) | ||
5286 | bands[index]->ht_cap.cap |= | ||
5287 | IEEE80211_HT_CAP_SGI_40; | ||
5288 | } | ||
5289 | 5323 | ||
5290 | if ((index >= 0) && nmode) { | 5324 | if (bw_cap[band->band] & WLC_BW_40MHZ_BIT) { |
5291 | bands[index]->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20; | 5325 | band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40; |
5292 | bands[index]->ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40; | 5326 | band->ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40; |
5293 | bands[index]->ht_cap.ht_supported = true; | ||
5294 | bands[index]->ht_cap.ampdu_factor = | ||
5295 | IEEE80211_HT_MAX_AMPDU_64K; | ||
5296 | bands[index]->ht_cap.ampdu_density = | ||
5297 | IEEE80211_HT_MPDU_DENSITY_16; | ||
5298 | /* An HT shall support all EQM rates for one spatial | ||
5299 | * stream | ||
5300 | */ | ||
5301 | bands[index]->ht_cap.mcs.rx_mask[0] = 0xff; | ||
5302 | } | 5327 | } |
5328 | band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20; | ||
5329 | band->ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40; | ||
5330 | band->ht_cap.ht_supported = true; | ||
5331 | band->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; | ||
5332 | band->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16; | ||
5333 | /* An HT shall support all EQM rates for one spatial | ||
5334 | * stream | ||
5335 | */ | ||
5336 | band->ht_cap.mcs.rx_mask[0] = 0xff; | ||
5337 | band->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; | ||
5338 | bands[band->band] = band; | ||
5303 | } | 5339 | } |
5304 | 5340 | ||
5305 | wiphy = cfg_to_wiphy(cfg); | 5341 | wiphy = cfg_to_wiphy(cfg); |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h index d9bdaf9a72d0..2dc6a074e8ed 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h | |||
@@ -412,7 +412,6 @@ struct brcmf_cfg80211_info { | |||
412 | struct work_struct escan_timeout_work; | 412 | struct work_struct escan_timeout_work; |
413 | u8 *escan_ioctl_buf; | 413 | u8 *escan_ioctl_buf; |
414 | struct list_head vif_list; | 414 | struct list_head vif_list; |
415 | u8 vif_cnt; | ||
416 | struct brcmf_cfg80211_vif_event vif_event; | 415 | struct brcmf_cfg80211_vif_event vif_event; |
417 | struct completion vif_disabled; | 416 | struct completion vif_disabled; |
418 | struct brcmu_d11inf d11inf; | 417 | struct brcmu_d11inf d11inf; |
@@ -487,8 +486,7 @@ enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp); | |||
487 | struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg, | 486 | struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg, |
488 | enum nl80211_iftype type, | 487 | enum nl80211_iftype type, |
489 | bool pm_block); | 488 | bool pm_block); |
490 | void brcmf_free_vif(struct brcmf_cfg80211_info *cfg, | 489 | void brcmf_free_vif(struct brcmf_cfg80211_vif *vif); |
491 | struct brcmf_cfg80211_vif *vif); | ||
492 | 490 | ||
493 | s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag, | 491 | s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag, |
494 | const u8 *vndr_ie_buf, u32 vndr_ie_len); | 492 | const u8 *vndr_ie_buf, u32 vndr_ie_len); |
@@ -507,5 +505,6 @@ s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg, | |||
507 | bool fw_abort); | 505 | bool fw_abort); |
508 | void brcmf_set_mpc(struct brcmf_if *ndev, int mpc); | 506 | void brcmf_set_mpc(struct brcmf_if *ndev, int mpc); |
509 | void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg); | 507 | void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg); |
508 | void brcmf_cfg80211_free_netdev(struct net_device *ndev); | ||
510 | 509 | ||
511 | #endif /* _wl_cfg80211_h_ */ | 510 | #endif /* _wl_cfg80211_h_ */ |
diff --git a/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h index 84113ea16f84..6fa5d4863782 100644 --- a/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h +++ b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h | |||
@@ -41,6 +41,7 @@ | |||
41 | #define BCM4331_CHIP_ID 0x4331 | 41 | #define BCM4331_CHIP_ID 0x4331 |
42 | #define BCM4334_CHIP_ID 0x4334 | 42 | #define BCM4334_CHIP_ID 0x4334 |
43 | #define BCM4335_CHIP_ID 0x4335 | 43 | #define BCM4335_CHIP_ID 0x4335 |
44 | #define BCM43362_CHIP_ID 43362 | ||
44 | #define BCM4339_CHIP_ID 0x4339 | 45 | #define BCM4339_CHIP_ID 0x4339 |
45 | 46 | ||
46 | #endif /* _BRCM_HW_IDS_H_ */ | 47 | #endif /* _BRCM_HW_IDS_H_ */ |
diff --git a/drivers/net/wireless/brcm80211/include/brcmu_wifi.h b/drivers/net/wireless/brcm80211/include/brcmu_wifi.h index 0505cc065e0d..7ca2aa1035b2 100644 --- a/drivers/net/wireless/brcm80211/include/brcmu_wifi.h +++ b/drivers/net/wireless/brcm80211/include/brcmu_wifi.h | |||
@@ -82,6 +82,20 @@ | |||
82 | #define WLC_N_BW_40ALL 1 | 82 | #define WLC_N_BW_40ALL 1 |
83 | #define WLC_N_BW_20IN2G_40IN5G 2 | 83 | #define WLC_N_BW_20IN2G_40IN5G 2 |
84 | 84 | ||
85 | #define WLC_BW_20MHZ_BIT BIT(0) | ||
86 | #define WLC_BW_40MHZ_BIT BIT(1) | ||
87 | #define WLC_BW_80MHZ_BIT BIT(2) | ||
88 | #define WLC_BW_160MHZ_BIT BIT(3) | ||
89 | |||
90 | /* Bandwidth capabilities */ | ||
91 | #define WLC_BW_CAP_20MHZ (WLC_BW_20MHZ_BIT) | ||
92 | #define WLC_BW_CAP_40MHZ (WLC_BW_40MHZ_BIT|WLC_BW_20MHZ_BIT) | ||
93 | #define WLC_BW_CAP_80MHZ (WLC_BW_80MHZ_BIT|WLC_BW_40MHZ_BIT| \ | ||
94 | WLC_BW_20MHZ_BIT) | ||
95 | #define WLC_BW_CAP_160MHZ (WLC_BW_160MHZ_BIT|WLC_BW_80MHZ_BIT| \ | ||
96 | WLC_BW_40MHZ_BIT|WLC_BW_20MHZ_BIT) | ||
97 | #define WLC_BW_CAP_UNRESTRICTED 0xFF | ||
98 | |||
85 | /* band types */ | 99 | /* band types */ |
86 | #define WLC_BAND_AUTO 0 /* auto-select */ | 100 | #define WLC_BAND_AUTO 0 /* auto-select */ |
87 | #define WLC_BAND_5G 1 /* 5 Ghz */ | 101 | #define WLC_BAND_5G 1 /* 5 Ghz */ |
diff --git a/drivers/net/wireless/cw1200/fwio.c b/drivers/net/wireless/cw1200/fwio.c index acdff0f7f952..5a9ffd3a6a6c 100644 --- a/drivers/net/wireless/cw1200/fwio.c +++ b/drivers/net/wireless/cw1200/fwio.c | |||
@@ -14,7 +14,6 @@ | |||
14 | * published by the Free Software Foundation. | 14 | * published by the Free Software Foundation. |
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/vmalloc.h> | 17 | #include <linux/vmalloc.h> |
19 | #include <linux/sched.h> | 18 | #include <linux/sched.h> |
20 | #include <linux/firmware.h> | 19 | #include <linux/firmware.h> |
diff --git a/drivers/net/wireless/cw1200/main.c b/drivers/net/wireless/cw1200/main.c index 090f01577dd2..d1270da4dfea 100644 --- a/drivers/net/wireless/cw1200/main.c +++ b/drivers/net/wireless/cw1200/main.c | |||
@@ -21,7 +21,6 @@ | |||
21 | */ | 21 | */ |
22 | 22 | ||
23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
24 | #include <linux/init.h> | ||
25 | #include <linux/firmware.h> | 24 | #include <linux/firmware.h> |
26 | #include <linux/etherdevice.h> | 25 | #include <linux/etherdevice.h> |
27 | #include <linux/vmalloc.h> | 26 | #include <linux/vmalloc.h> |
diff --git a/drivers/net/wireless/cw1200/pm.c b/drivers/net/wireless/cw1200/pm.c index b37abb9f0453..6907c8fd4578 100644 --- a/drivers/net/wireless/cw1200/pm.c +++ b/drivers/net/wireless/cw1200/pm.c | |||
@@ -225,7 +225,7 @@ int cw1200_wow_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) | |||
225 | cw1200_set_pm(priv, &priv->powersave_mode); | 225 | cw1200_set_pm(priv, &priv->powersave_mode); |
226 | if (wait_event_interruptible_timeout(priv->ps_mode_switch_done, | 226 | if (wait_event_interruptible_timeout(priv->ps_mode_switch_done, |
227 | !priv->ps_mode_switch_in_progress, 1*HZ) <= 0) { | 227 | !priv->ps_mode_switch_in_progress, 1*HZ) <= 0) { |
228 | goto revert3; | 228 | goto revert4; |
229 | } | 229 | } |
230 | } | 230 | } |
231 | 231 | ||
@@ -254,11 +254,11 @@ int cw1200_wow_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) | |||
254 | 254 | ||
255 | /* Stop serving thread */ | 255 | /* Stop serving thread */ |
256 | if (cw1200_bh_suspend(priv)) | 256 | if (cw1200_bh_suspend(priv)) |
257 | goto revert4; | 257 | goto revert5; |
258 | 258 | ||
259 | ret = timer_pending(&priv->mcast_timeout); | 259 | ret = timer_pending(&priv->mcast_timeout); |
260 | if (ret) | 260 | if (ret) |
261 | goto revert5; | 261 | goto revert6; |
262 | 262 | ||
263 | /* Store suspend state */ | 263 | /* Store suspend state */ |
264 | pm_state->suspend_state = state; | 264 | pm_state->suspend_state = state; |
@@ -280,9 +280,9 @@ int cw1200_wow_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) | |||
280 | 280 | ||
281 | return 0; | 281 | return 0; |
282 | 282 | ||
283 | revert5: | 283 | revert6: |
284 | WARN_ON(cw1200_bh_resume(priv)); | 284 | WARN_ON(cw1200_bh_resume(priv)); |
285 | revert4: | 285 | revert5: |
286 | cw1200_resume_work(priv, &priv->bss_loss_work, | 286 | cw1200_resume_work(priv, &priv->bss_loss_work, |
287 | state->bss_loss_tmo); | 287 | state->bss_loss_tmo); |
288 | cw1200_resume_work(priv, &priv->join_timeout, | 288 | cw1200_resume_work(priv, &priv->join_timeout, |
@@ -291,6 +291,7 @@ revert4: | |||
291 | state->direct_probe); | 291 | state->direct_probe); |
292 | cw1200_resume_work(priv, &priv->link_id_gc_work, | 292 | cw1200_resume_work(priv, &priv->link_id_gc_work, |
293 | state->link_id_gc); | 293 | state->link_id_gc); |
294 | revert4: | ||
294 | kfree(state); | 295 | kfree(state); |
295 | revert3: | 296 | revert3: |
296 | wsm_set_udp_port_filter(priv, &cw1200_udp_port_filter_off); | 297 | wsm_set_udp_port_filter(priv, &cw1200_udp_port_filter_off); |
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c index 56cd01ca8ad0..9f825f2620da 100644 --- a/drivers/net/wireless/hostap/hostap_cs.c +++ b/drivers/net/wireless/hostap/hostap_cs.c | |||
@@ -1,7 +1,6 @@ | |||
1 | #define PRISM2_PCCARD | 1 | #define PRISM2_PCCARD |
2 | 2 | ||
3 | #include <linux/module.h> | 3 | #include <linux/module.h> |
4 | #include <linux/init.h> | ||
5 | #include <linux/if.h> | 4 | #include <linux/if.h> |
6 | #include <linux/slab.h> | 5 | #include <linux/slab.h> |
7 | #include <linux/wait.h> | 6 | #include <linux/wait.h> |
diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c index 2454a740ea50..3e5fa7872b64 100644 --- a/drivers/net/wireless/hostap/hostap_ioctl.c +++ b/drivers/net/wireless/hostap/hostap_ioctl.c | |||
@@ -2567,7 +2567,7 @@ static int prism2_ioctl_priv_prism2_param(struct net_device *dev, | |||
2567 | local->passive_scan_interval = value; | 2567 | local->passive_scan_interval = value; |
2568 | if (timer_pending(&local->passive_scan_timer)) | 2568 | if (timer_pending(&local->passive_scan_timer)) |
2569 | del_timer(&local->passive_scan_timer); | 2569 | del_timer(&local->passive_scan_timer); |
2570 | if (value > 0) { | 2570 | if (value > 0 && value < INT_MAX / HZ) { |
2571 | local->passive_scan_timer.expires = jiffies + | 2571 | local->passive_scan_timer.expires = jiffies + |
2572 | local->passive_scan_interval * HZ; | 2572 | local->passive_scan_interval * HZ; |
2573 | add_timer(&local->passive_scan_timer); | 2573 | add_timer(&local->passive_scan_timer); |
diff --git a/drivers/net/wireless/hostap/hostap_pci.c b/drivers/net/wireless/hostap/hostap_pci.c index 05ca3402dca7..91158e2e961c 100644 --- a/drivers/net/wireless/hostap/hostap_pci.c +++ b/drivers/net/wireless/hostap/hostap_pci.c | |||
@@ -5,7 +5,6 @@ | |||
5 | * Andy Warner <andyw@pobox.com> */ | 5 | * Andy Warner <andyw@pobox.com> */ |
6 | 6 | ||
7 | #include <linux/module.h> | 7 | #include <linux/module.h> |
8 | #include <linux/init.h> | ||
9 | #include <linux/if.h> | 8 | #include <linux/if.h> |
10 | #include <linux/skbuff.h> | 9 | #include <linux/skbuff.h> |
11 | #include <linux/netdevice.h> | 10 | #include <linux/netdevice.h> |
diff --git a/drivers/net/wireless/hostap/hostap_plx.c b/drivers/net/wireless/hostap/hostap_plx.c index c3d067ee4db9..3bf530d9a40f 100644 --- a/drivers/net/wireless/hostap/hostap_plx.c +++ b/drivers/net/wireless/hostap/hostap_plx.c | |||
@@ -8,7 +8,6 @@ | |||
8 | 8 | ||
9 | 9 | ||
10 | #include <linux/module.h> | 10 | #include <linux/module.h> |
11 | #include <linux/init.h> | ||
12 | #include <linux/if.h> | 11 | #include <linux/if.h> |
13 | #include <linux/skbuff.h> | 12 | #include <linux/skbuff.h> |
14 | #include <linux/netdevice.h> | 13 | #include <linux/netdevice.h> |
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.h b/drivers/net/wireless/ipw2x00/ipw2200.h index 570d6fb88967..aa301d1eee3c 100644 --- a/drivers/net/wireless/ipw2x00/ipw2200.h +++ b/drivers/net/wireless/ipw2x00/ipw2200.h | |||
@@ -29,7 +29,6 @@ | |||
29 | 29 | ||
30 | #include <linux/module.h> | 30 | #include <linux/module.h> |
31 | #include <linux/moduleparam.h> | 31 | #include <linux/moduleparam.h> |
32 | #include <linux/init.h> | ||
33 | #include <linux/interrupt.h> | 32 | #include <linux/interrupt.h> |
34 | #include <linux/mutex.h> | 33 | #include <linux/mutex.h> |
35 | 34 | ||
diff --git a/drivers/net/wireless/ipw2x00/libipw_rx.c b/drivers/net/wireless/ipw2x00/libipw_rx.c index 5c6253811c52..a586a85bfcfe 100644 --- a/drivers/net/wireless/ipw2x00/libipw_rx.c +++ b/drivers/net/wireless/ipw2x00/libipw_rx.c | |||
@@ -1468,7 +1468,7 @@ static inline int is_same_network(struct libipw_network *src, | |||
1468 | * as one network */ | 1468 | * as one network */ |
1469 | return ((src->ssid_len == dst->ssid_len) && | 1469 | return ((src->ssid_len == dst->ssid_len) && |
1470 | (src->channel == dst->channel) && | 1470 | (src->channel == dst->channel) && |
1471 | ether_addr_equal(src->bssid, dst->bssid) && | 1471 | ether_addr_equal_64bits(src->bssid, dst->bssid) && |
1472 | !memcmp(src->ssid, dst->ssid, src->ssid_len)); | 1472 | !memcmp(src->ssid, dst->ssid, src->ssid_len)); |
1473 | } | 1473 | } |
1474 | 1474 | ||
diff --git a/drivers/net/wireless/iwlegacy/3945-rs.c b/drivers/net/wireless/iwlegacy/3945-rs.c index aea667b430c3..9a45f6f626f6 100644 --- a/drivers/net/wireless/iwlegacy/3945-rs.c +++ b/drivers/net/wireless/iwlegacy/3945-rs.c | |||
@@ -25,7 +25,6 @@ | |||
25 | *****************************************************************************/ | 25 | *****************************************************************************/ |
26 | 26 | ||
27 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
28 | #include <linux/init.h> | ||
29 | #include <linux/skbuff.h> | 28 | #include <linux/skbuff.h> |
30 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
31 | #include <net/mac80211.h> | 30 | #include <net/mac80211.h> |
diff --git a/drivers/net/wireless/iwlegacy/3945.c b/drivers/net/wireless/iwlegacy/3945.c index f09e257759d5..d37a6fd90d40 100644 --- a/drivers/net/wireless/iwlegacy/3945.c +++ b/drivers/net/wireless/iwlegacy/3945.c | |||
@@ -26,7 +26,6 @@ | |||
26 | 26 | ||
27 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
28 | #include <linux/module.h> | 28 | #include <linux/module.h> |
29 | #include <linux/init.h> | ||
30 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
31 | #include <linux/pci.h> | 30 | #include <linux/pci.h> |
32 | #include <linux/dma-mapping.h> | 31 | #include <linux/dma-mapping.h> |
@@ -466,10 +465,10 @@ il3945_is_network_packet(struct il_priv *il, struct ieee80211_hdr *header) | |||
466 | switch (il->iw_mode) { | 465 | switch (il->iw_mode) { |
467 | case NL80211_IFTYPE_ADHOC: /* Header: Dest. | Source | BSSID */ | 466 | case NL80211_IFTYPE_ADHOC: /* Header: Dest. | Source | BSSID */ |
468 | /* packets to our IBSS update information */ | 467 | /* packets to our IBSS update information */ |
469 | return ether_addr_equal(header->addr3, il->bssid); | 468 | return ether_addr_equal_64bits(header->addr3, il->bssid); |
470 | case NL80211_IFTYPE_STATION: /* Header: Dest. | AP{BSSID} | Source */ | 469 | case NL80211_IFTYPE_STATION: /* Header: Dest. | AP{BSSID} | Source */ |
471 | /* packets to our IBSS update information */ | 470 | /* packets to our IBSS update information */ |
472 | return ether_addr_equal(header->addr2, il->bssid); | 471 | return ether_addr_equal_64bits(header->addr2, il->bssid); |
473 | default: | 472 | default: |
474 | return 1; | 473 | return 1; |
475 | } | 474 | } |
diff --git a/drivers/net/wireless/iwlegacy/4965-rs.c b/drivers/net/wireless/iwlegacy/4965-rs.c index 3ccbaf791b48..4d5e33259ca8 100644 --- a/drivers/net/wireless/iwlegacy/4965-rs.c +++ b/drivers/net/wireless/iwlegacy/4965-rs.c | |||
@@ -24,7 +24,6 @@ | |||
24 | * | 24 | * |
25 | *****************************************************************************/ | 25 | *****************************************************************************/ |
26 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
27 | #include <linux/init.h> | ||
28 | #include <linux/skbuff.h> | 27 | #include <linux/skbuff.h> |
29 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
30 | #include <net/mac80211.h> | 29 | #include <net/mac80211.h> |
diff --git a/drivers/net/wireless/iwlegacy/4965.c b/drivers/net/wireless/iwlegacy/4965.c index 777a578294bd..fe47db9c20cd 100644 --- a/drivers/net/wireless/iwlegacy/4965.c +++ b/drivers/net/wireless/iwlegacy/4965.c | |||
@@ -26,7 +26,6 @@ | |||
26 | 26 | ||
27 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
28 | #include <linux/module.h> | 28 | #include <linux/module.h> |
29 | #include <linux/init.h> | ||
30 | #include <linux/pci.h> | 29 | #include <linux/pci.h> |
31 | #include <linux/dma-mapping.h> | 30 | #include <linux/dma-mapping.h> |
32 | #include <linux/delay.h> | 31 | #include <linux/delay.h> |
diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c index a27b14cfeaec..02e8233ccf29 100644 --- a/drivers/net/wireless/iwlegacy/common.c +++ b/drivers/net/wireless/iwlegacy/common.c | |||
@@ -33,7 +33,6 @@ | |||
33 | #include <linux/slab.h> | 33 | #include <linux/slab.h> |
34 | #include <linux/types.h> | 34 | #include <linux/types.h> |
35 | #include <linux/lockdep.h> | 35 | #include <linux/lockdep.h> |
36 | #include <linux/init.h> | ||
37 | #include <linux/pci.h> | 36 | #include <linux/pci.h> |
38 | #include <linux/dma-mapping.h> | 37 | #include <linux/dma-mapping.h> |
39 | #include <linux/delay.h> | 38 | #include <linux/delay.h> |
@@ -3746,10 +3745,10 @@ il_full_rxon_required(struct il_priv *il) | |||
3746 | 3745 | ||
3747 | /* These items are only settable from the full RXON command */ | 3746 | /* These items are only settable from the full RXON command */ |
3748 | CHK(!il_is_associated(il)); | 3747 | CHK(!il_is_associated(il)); |
3749 | CHK(!ether_addr_equal(staging->bssid_addr, active->bssid_addr)); | 3748 | CHK(!ether_addr_equal_64bits(staging->bssid_addr, active->bssid_addr)); |
3750 | CHK(!ether_addr_equal(staging->node_addr, active->node_addr)); | 3749 | CHK(!ether_addr_equal_64bits(staging->node_addr, active->node_addr)); |
3751 | CHK(!ether_addr_equal(staging->wlap_bssid_addr, | 3750 | CHK(!ether_addr_equal_64bits(staging->wlap_bssid_addr, |
3752 | active->wlap_bssid_addr)); | 3751 | active->wlap_bssid_addr)); |
3753 | CHK_NEQ(staging->dev_type, active->dev_type); | 3752 | CHK_NEQ(staging->dev_type, active->dev_type); |
3754 | CHK_NEQ(staging->channel, active->channel); | 3753 | CHK_NEQ(staging->channel, active->channel); |
3755 | CHK_NEQ(staging->air_propagation, active->air_propagation); | 3754 | CHK_NEQ(staging->air_propagation, active->air_propagation); |
diff --git a/drivers/net/wireless/iwlwifi/dvm/agn.h b/drivers/net/wireless/iwlwifi/dvm/agn.h index 23d5f0275ce9..562772d85102 100644 --- a/drivers/net/wireless/iwlwifi/dvm/agn.h +++ b/drivers/net/wireless/iwlwifi/dvm/agn.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/dvm/calib.c b/drivers/net/wireless/iwlwifi/dvm/calib.c index 1b0f0d502568..be1086c87157 100644 --- a/drivers/net/wireless/iwlwifi/dvm/calib.c +++ b/drivers/net/wireless/iwlwifi/dvm/calib.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/dvm/calib.h b/drivers/net/wireless/iwlwifi/dvm/calib.h index cfddde194940..aeae4e80ea40 100644 --- a/drivers/net/wireless/iwlwifi/dvm/calib.h +++ b/drivers/net/wireless/iwlwifi/dvm/calib.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/dvm/commands.h b/drivers/net/wireless/iwlwifi/dvm/commands.h index ebdac909f0cd..751ae1d10b7f 100644 --- a/drivers/net/wireless/iwlwifi/dvm/commands.h +++ b/drivers/net/wireless/iwlwifi/dvm/commands.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/dvm/debugfs.c b/drivers/net/wireless/iwlwifi/dvm/debugfs.c index f69301e505ee..d2fe2596d54e 100644 --- a/drivers/net/wireless/iwlwifi/dvm/debugfs.c +++ b/drivers/net/wireless/iwlwifi/dvm/debugfs.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * | 2 | * |
3 | * GPL LICENSE SUMMARY | 3 | * GPL LICENSE SUMMARY |
4 | * | 4 | * |
5 | * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved. | 5 | * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of version 2 of the GNU General Public License as | 8 | * it under the terms of version 2 of the GNU General Public License as |
diff --git a/drivers/net/wireless/iwlwifi/dvm/dev.h b/drivers/net/wireless/iwlwifi/dvm/dev.h index 7434d9edf3b7..3441f70d0ff9 100644 --- a/drivers/net/wireless/iwlwifi/dvm/dev.h +++ b/drivers/net/wireless/iwlwifi/dvm/dev.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2003 - 2013 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify it | 5 | * This program is free software; you can redistribute it and/or modify it |
6 | * under the terms of version 2 of the GNU General Public License as | 6 | * under the terms of version 2 of the GNU General Public License as |
diff --git a/drivers/net/wireless/iwlwifi/dvm/devices.c b/drivers/net/wireless/iwlwifi/dvm/devices.c index 352c6cb7b4f1..7b140e487deb 100644 --- a/drivers/net/wireless/iwlwifi/dvm/devices.c +++ b/drivers/net/wireless/iwlwifi/dvm/devices.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify it | 5 | * This program is free software; you can redistribute it and/or modify it |
6 | * under the terms of version 2 of the GNU General Public License as | 6 | * under the terms of version 2 of the GNU General Public License as |
diff --git a/drivers/net/wireless/iwlwifi/dvm/led.c b/drivers/net/wireless/iwlwifi/dvm/led.c index 33c7e15d24f5..ca4d6692cc4e 100644 --- a/drivers/net/wireless/iwlwifi/dvm/led.c +++ b/drivers/net/wireless/iwlwifi/dvm/led.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2003 - 2013 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify it | 5 | * This program is free software; you can redistribute it and/or modify it |
6 | * under the terms of version 2 of the GNU General Public License as | 6 | * under the terms of version 2 of the GNU General Public License as |
@@ -27,7 +27,6 @@ | |||
27 | 27 | ||
28 | #include <linux/kernel.h> | 28 | #include <linux/kernel.h> |
29 | #include <linux/module.h> | 29 | #include <linux/module.h> |
30 | #include <linux/init.h> | ||
31 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
32 | #include <linux/skbuff.h> | 31 | #include <linux/skbuff.h> |
33 | #include <linux/netdevice.h> | 32 | #include <linux/netdevice.h> |
diff --git a/drivers/net/wireless/iwlwifi/dvm/led.h b/drivers/net/wireless/iwlwifi/dvm/led.h index 8749dcfe695f..6a0817d9c4fa 100644 --- a/drivers/net/wireless/iwlwifi/dvm/led.h +++ b/drivers/net/wireless/iwlwifi/dvm/led.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2003 - 2013 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify it | 5 | * This program is free software; you can redistribute it and/or modify it |
6 | * under the terms of version 2 of the GNU General Public License as | 6 | * under the terms of version 2 of the GNU General Public License as |
diff --git a/drivers/net/wireless/iwlwifi/dvm/lib.c b/drivers/net/wireless/iwlwifi/dvm/lib.c index 3d5bdc4217a8..576f7ee38ca5 100644 --- a/drivers/net/wireless/iwlwifi/dvm/lib.c +++ b/drivers/net/wireless/iwlwifi/dvm/lib.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * | 2 | * |
3 | * GPL LICENSE SUMMARY | 3 | * GPL LICENSE SUMMARY |
4 | * | 4 | * |
5 | * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved. | 5 | * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of version 2 of the GNU General Public License as | 8 | * it under the terms of version 2 of the GNU General Public License as |
@@ -29,7 +29,6 @@ | |||
29 | #include <linux/etherdevice.h> | 29 | #include <linux/etherdevice.h> |
30 | #include <linux/kernel.h> | 30 | #include <linux/kernel.h> |
31 | #include <linux/module.h> | 31 | #include <linux/module.h> |
32 | #include <linux/init.h> | ||
33 | #include <linux/sched.h> | 32 | #include <linux/sched.h> |
34 | #include <net/mac80211.h> | 33 | #include <net/mac80211.h> |
35 | 34 | ||
diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c index 9f4239d31c08..40eb5e691475 100644 --- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2003 - 2013 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * Portions of this file are derived from the ipw3945 project, as well | 5 | * Portions of this file are derived from the ipw3945 project, as well |
6 | * as portions of the ieee80211 subsystem header files. | 6 | * as portions of the ieee80211 subsystem header files. |
@@ -28,7 +28,6 @@ | |||
28 | *****************************************************************************/ | 28 | *****************************************************************************/ |
29 | #include <linux/kernel.h> | 29 | #include <linux/kernel.h> |
30 | #include <linux/module.h> | 30 | #include <linux/module.h> |
31 | #include <linux/init.h> | ||
32 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
33 | #include <linux/dma-mapping.h> | 32 | #include <linux/dma-mapping.h> |
34 | #include <linux/delay.h> | 33 | #include <linux/delay.h> |
diff --git a/drivers/net/wireless/iwlwifi/dvm/main.c b/drivers/net/wireless/iwlwifi/dvm/main.c index fd9f6cf96cfd..ba1b1ea54252 100644 --- a/drivers/net/wireless/iwlwifi/dvm/main.c +++ b/drivers/net/wireless/iwlwifi/dvm/main.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2003 - 2013 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * Portions of this file are derived from the ipw3945 project, as well | 5 | * Portions of this file are derived from the ipw3945 project, as well |
6 | * as portions of the ieee80211 subsystem header files. | 6 | * as portions of the ieee80211 subsystem header files. |
diff --git a/drivers/net/wireless/iwlwifi/dvm/power.c b/drivers/net/wireless/iwlwifi/dvm/power.c index 77cb59712235..b4e61417013a 100644 --- a/drivers/net/wireless/iwlwifi/dvm/power.c +++ b/drivers/net/wireless/iwlwifi/dvm/power.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * Portions of this file are derived from the ipw3945 project, as well | 5 | * Portions of this file are derived from the ipw3945 project, as well |
6 | * as portions of the ieee80211 subsystem header files. | 6 | * as portions of the ieee80211 subsystem header files. |
@@ -30,7 +30,6 @@ | |||
30 | #include <linux/kernel.h> | 30 | #include <linux/kernel.h> |
31 | #include <linux/module.h> | 31 | #include <linux/module.h> |
32 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
33 | #include <linux/init.h> | ||
34 | #include <net/mac80211.h> | 33 | #include <net/mac80211.h> |
35 | #include "iwl-io.h" | 34 | #include "iwl-io.h" |
36 | #include "iwl-debug.h" | 35 | #include "iwl-debug.h" |
diff --git a/drivers/net/wireless/iwlwifi/dvm/power.h b/drivers/net/wireless/iwlwifi/dvm/power.h index 7b03e1342d47..570d3a5e4670 100644 --- a/drivers/net/wireless/iwlwifi/dvm/power.h +++ b/drivers/net/wireless/iwlwifi/dvm/power.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * Portions of this file are derived from the ipw3945 project, as well | 5 | * Portions of this file are derived from the ipw3945 project, as well |
6 | * as portions of the ieee80211 subsystem header files. | 6 | * as portions of the ieee80211 subsystem header files. |
diff --git a/drivers/net/wireless/iwlwifi/dvm/rs.c b/drivers/net/wireless/iwlwifi/dvm/rs.c index b647e506564c..0977d93b529d 100644 --- a/drivers/net/wireless/iwlwifi/dvm/rs.c +++ b/drivers/net/wireless/iwlwifi/dvm/rs.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify it | 5 | * This program is free software; you can redistribute it and/or modify it |
6 | * under the terms of version 2 of the GNU General Public License as | 6 | * under the terms of version 2 of the GNU General Public License as |
@@ -24,7 +24,6 @@ | |||
24 | * | 24 | * |
25 | *****************************************************************************/ | 25 | *****************************************************************************/ |
26 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
27 | #include <linux/init.h> | ||
28 | #include <linux/skbuff.h> | 27 | #include <linux/skbuff.h> |
29 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
30 | #include <net/mac80211.h> | 29 | #include <net/mac80211.h> |
diff --git a/drivers/net/wireless/iwlwifi/dvm/rs.h b/drivers/net/wireless/iwlwifi/dvm/rs.h index 41988f4b8a5a..bdd5644a400b 100644 --- a/drivers/net/wireless/iwlwifi/dvm/rs.h +++ b/drivers/net/wireless/iwlwifi/dvm/rs.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2003 - 2013 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify it | 5 | * This program is free software; you can redistribute it and/or modify it |
6 | * under the terms of version 2 of the GNU General Public License as | 6 | * under the terms of version 2 of the GNU General Public License as |
diff --git a/drivers/net/wireless/iwlwifi/dvm/rx.c b/drivers/net/wireless/iwlwifi/dvm/rx.c index d71776dd1e6a..b68bb2f4d2c2 100644 --- a/drivers/net/wireless/iwlwifi/dvm/rx.c +++ b/drivers/net/wireless/iwlwifi/dvm/rx.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2003 - 2013 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * Portions of this file are derived from the ipw3945 project, as well | 5 | * Portions of this file are derived from the ipw3945 project, as well |
6 | * as portionhelp of the ieee80211 subsystem header files. | 6 | * as portionhelp of the ieee80211 subsystem header files. |
diff --git a/drivers/net/wireless/iwlwifi/dvm/rxon.c b/drivers/net/wireless/iwlwifi/dvm/rxon.c index d7ce2f12a907..503a81e58185 100644 --- a/drivers/net/wireless/iwlwifi/dvm/rxon.c +++ b/drivers/net/wireless/iwlwifi/dvm/rxon.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2003 - 2013 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify it | 5 | * This program is free software; you can redistribute it and/or modify it |
6 | * under the terms of version 2 of the GNU General Public License as | 6 | * under the terms of version 2 of the GNU General Public License as |
diff --git a/drivers/net/wireless/iwlwifi/dvm/scan.c b/drivers/net/wireless/iwlwifi/dvm/scan.c index 928f8640a0a7..be98b913ed58 100644 --- a/drivers/net/wireless/iwlwifi/dvm/scan.c +++ b/drivers/net/wireless/iwlwifi/dvm/scan.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * | 2 | * |
3 | * GPL LICENSE SUMMARY | 3 | * GPL LICENSE SUMMARY |
4 | * | 4 | * |
5 | * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved. | 5 | * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of version 2 of the GNU General Public License as | 8 | * it under the terms of version 2 of the GNU General Public License as |
diff --git a/drivers/net/wireless/iwlwifi/dvm/sta.c b/drivers/net/wireless/iwlwifi/dvm/sta.c index c3c13ce96eb0..c0d070c5df5e 100644 --- a/drivers/net/wireless/iwlwifi/dvm/sta.c +++ b/drivers/net/wireless/iwlwifi/dvm/sta.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2003 - 2013 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * Portions of this file are derived from the ipw3945 project, as well | 5 | * Portions of this file are derived from the ipw3945 project, as well |
6 | * as portions of the ieee80211 subsystem header files. | 6 | * as portions of the ieee80211 subsystem header files. |
diff --git a/drivers/net/wireless/iwlwifi/dvm/tt.c b/drivers/net/wireless/iwlwifi/dvm/tt.c index fbeee081ee2f..058c5892c427 100644 --- a/drivers/net/wireless/iwlwifi/dvm/tt.c +++ b/drivers/net/wireless/iwlwifi/dvm/tt.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * Portions of this file are derived from the ipw3945 project, as well | 5 | * Portions of this file are derived from the ipw3945 project, as well |
6 | * as portions of the ieee80211 subsystem header files. | 6 | * as portions of the ieee80211 subsystem header files. |
@@ -30,7 +30,6 @@ | |||
30 | #include <linux/kernel.h> | 30 | #include <linux/kernel.h> |
31 | #include <linux/module.h> | 31 | #include <linux/module.h> |
32 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
33 | #include <linux/init.h> | ||
34 | #include <net/mac80211.h> | 33 | #include <net/mac80211.h> |
35 | #include "iwl-io.h" | 34 | #include "iwl-io.h" |
36 | #include "iwl-modparams.h" | 35 | #include "iwl-modparams.h" |
diff --git a/drivers/net/wireless/iwlwifi/dvm/tt.h b/drivers/net/wireless/iwlwifi/dvm/tt.h index 9356c4b908ca..507726534b84 100644 --- a/drivers/net/wireless/iwlwifi/dvm/tt.h +++ b/drivers/net/wireless/iwlwifi/dvm/tt.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * Portions of this file are derived from the ipw3945 project, as well | 5 | * Portions of this file are derived from the ipw3945 project, as well |
6 | * as portions of the ieee80211 subsystem header files. | 6 | * as portions of the ieee80211 subsystem header files. |
diff --git a/drivers/net/wireless/iwlwifi/dvm/tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c index e12b1a63c484..a6839dfcb82d 100644 --- a/drivers/net/wireless/iwlwifi/dvm/tx.c +++ b/drivers/net/wireless/iwlwifi/dvm/tx.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * | 2 | * |
3 | * GPL LICENSE SUMMARY | 3 | * GPL LICENSE SUMMARY |
4 | * | 4 | * |
5 | * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved. | 5 | * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of version 2 of the GNU General Public License as | 8 | * it under the terms of version 2 of the GNU General Public License as |
@@ -29,7 +29,6 @@ | |||
29 | 29 | ||
30 | #include <linux/kernel.h> | 30 | #include <linux/kernel.h> |
31 | #include <linux/module.h> | 31 | #include <linux/module.h> |
32 | #include <linux/init.h> | ||
33 | #include <linux/sched.h> | 32 | #include <linux/sched.h> |
34 | #include <linux/ieee80211.h> | 33 | #include <linux/ieee80211.h> |
35 | #include "iwl-io.h" | 34 | #include "iwl-io.h" |
diff --git a/drivers/net/wireless/iwlwifi/dvm/ucode.c b/drivers/net/wireless/iwlwifi/dvm/ucode.c index 63637949a146..f59709a9b79d 100644 --- a/drivers/net/wireless/iwlwifi/dvm/ucode.c +++ b/drivers/net/wireless/iwlwifi/dvm/ucode.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * | 2 | * |
3 | * GPL LICENSE SUMMARY | 3 | * GPL LICENSE SUMMARY |
4 | * | 4 | * |
5 | * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved. | 5 | * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of version 2 of the GNU General Public License as | 8 | * it under the terms of version 2 of the GNU General Public License as |
@@ -28,7 +28,6 @@ | |||
28 | *****************************************************************************/ | 28 | *****************************************************************************/ |
29 | 29 | ||
30 | #include <linux/kernel.h> | 30 | #include <linux/kernel.h> |
31 | #include <linux/init.h> | ||
32 | 31 | ||
33 | #include "iwl-io.h" | 32 | #include "iwl-io.h" |
34 | #include "iwl-agn-hw.h" | 33 | #include "iwl-agn-hw.h" |
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 0d2afe098afc..854ba84ccb73 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify it | 5 | * This program is free software; you can redistribute it and/or modify it |
6 | * under the terms of version 2 of the GNU General Public License as | 6 | * under the terms of version 2 of the GNU General Public License as |
diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index c727ec7c90a6..3e63323637f3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify it | 5 | * This program is free software; you can redistribute it and/or modify it |
6 | * under the terms of version 2 of the GNU General Public License as | 6 | * under the terms of version 2 of the GNU General Public License as |
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index ecc01e1a61a1..6674f2c4541c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify it | 5 | * This program is free software; you can redistribute it and/or modify it |
6 | * under the terms of version 2 of the GNU General Public License as | 6 | * under the terms of version 2 of the GNU General Public License as |
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 8ac305be68f4..8048de90233f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify it | 5 | * This program is free software; you can redistribute it and/or modify it |
6 | * under the terms of version 2 of the GNU General Public License as | 6 | * under the terms of version 2 of the GNU General Public License as |
diff --git a/drivers/net/wireless/iwlwifi/iwl-7000.c b/drivers/net/wireless/iwlwifi/iwl-7000.c index 5fb37724c096..2a59da2ff87a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-7000.c +++ b/drivers/net/wireless/iwlwifi/iwl-7000.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hw.h b/drivers/net/wireless/iwlwifi/iwl-agn-hw.h index 6d73f943cefa..7f37fb86837b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-hw.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn-hw.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/iwl-config.h b/drivers/net/wireless/iwlwifi/iwl-config.h index e05440ff5cd4..1ced525157dc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/iwlwifi/iwl-config.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h index da4eca8b3007..9d325516c42d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-csr.h +++ b/drivers/net/wireless/iwlwifi/iwl-csr.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
@@ -198,7 +198,8 @@ | |||
198 | CSR_INT_BIT_RF_KILL | \ | 198 | CSR_INT_BIT_RF_KILL | \ |
199 | CSR_INT_BIT_SW_RX | \ | 199 | CSR_INT_BIT_SW_RX | \ |
200 | CSR_INT_BIT_WAKEUP | \ | 200 | CSR_INT_BIT_WAKEUP | \ |
201 | CSR_INT_BIT_ALIVE) | 201 | CSR_INT_BIT_ALIVE | \ |
202 | CSR_INT_BIT_RX_PERIODIC) | ||
202 | 203 | ||
203 | /* interrupt flags in FH (flow handler) (PCI busmaster DMA) */ | 204 | /* interrupt flags in FH (flow handler) (PCI busmaster DMA) */ |
204 | #define CSR_FH_INT_BIT_ERR (1 << 31) /* Error */ | 205 | #define CSR_FH_INT_BIT_ERR (1 << 31) /* Error */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h index b2bb32a781dd..a75aac986a23 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.h +++ b/drivers/net/wireless/iwlwifi/iwl-debug.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2003 - 2013 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * Portions of this file are derived from the ipw3945 project. | 5 | * Portions of this file are derived from the ipw3945 project. |
6 | * | 6 | * |
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.c b/drivers/net/wireless/iwlwifi/iwl-devtrace.c index 8f61c717f619..23e7351e02de 100644 --- a/drivers/net/wireless/iwlwifi/iwl-devtrace.c +++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2009 - 2013 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2009 - 2014 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify it | 5 | * This program is free software; you can redistribute it and/or modify it |
6 | * under the terms of version 2 of the GNU General Public License as | 6 | * under the terms of version 2 of the GNU General Public License as |
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h index 684c416d3493..78bd41bf34b0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h +++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2009 - 2013 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2009 - 2014 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify it | 5 | * This program is free software; you can redistribute it and/or modify it |
6 | * under the terms of version 2 of the GNU General Public License as | 6 | * under the terms of version 2 of the GNU General Public License as |
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index 4bebfb58fc7b..c3728163be46 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.h b/drivers/net/wireless/iwlwifi/iwl-drv.h index 429337a2b9a1..592c01e11013 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.h +++ b/drivers/net/wireless/iwlwifi/iwl-drv.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
@@ -67,7 +67,7 @@ | |||
67 | /* for all modules */ | 67 | /* for all modules */ |
68 | #define DRV_NAME "iwlwifi" | 68 | #define DRV_NAME "iwlwifi" |
69 | #define IWLWIFI_VERSION "in-tree:" | 69 | #define IWLWIFI_VERSION "in-tree:" |
70 | #define DRV_COPYRIGHT "Copyright(c) 2003-2013 Intel Corporation" | 70 | #define DRV_COPYRIGHT "Copyright(c) 2003- 2014 Intel Corporation" |
71 | #define DRV_AUTHOR "<ilw@linux.intel.com>" | 71 | #define DRV_AUTHOR "<ilw@linux.intel.com>" |
72 | 72 | ||
73 | 73 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c index 4380c16580eb..c44cf1149648 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h index d73304a23ec2..e3c7deafabe6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-read.c b/drivers/net/wireless/iwlwifi/iwl-eeprom-read.c index e5f2e362ab0b..25d0105741db 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom-read.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-read.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-read.h b/drivers/net/wireless/iwlwifi/iwl-eeprom-read.h index 8e941f8bd7d6..a6d3bdf82cdd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom-read.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-read.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/iwl-fh.h b/drivers/net/wireless/iwlwifi/iwl-fh.h index 484d318245fb..9564ae173d06 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fh.h +++ b/drivers/net/wireless/iwlwifi/iwl-fh.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-file.h b/drivers/net/wireless/iwlwifi/iwl-fw-file.h index 4f95734b2811..88e2d6eb569f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw-file.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw-file.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h index 8704e3042ca1..5f1493c44097 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.c b/drivers/net/wireless/iwlwifi/iwl-io.c index ad8e19a56eca..f98175a0d35b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.c +++ b/drivers/net/wireless/iwlwifi/iwl-io.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2003 - 2013 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * Portions of this file are derived from the ipw3945 project. | 5 | * Portions of this file are derived from the ipw3945 project. |
6 | * | 6 | * |
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h index 63d10ec08dbc..c339c1bed080 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.h +++ b/drivers/net/wireless/iwlwifi/iwl-io.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2003 - 2013 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * Portions of this file are derived from the ipw3945 project. | 5 | * Portions of this file are derived from the ipw3945 project. |
6 | * | 6 | * |
diff --git a/drivers/net/wireless/iwlwifi/iwl-modparams.h b/drivers/net/wireless/iwlwifi/iwl-modparams.h index a1f580c0c6c6..0a84ade7edac 100644 --- a/drivers/net/wireless/iwlwifi/iwl-modparams.h +++ b/drivers/net/wireless/iwlwifi/iwl-modparams.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/iwl-notif-wait.c b/drivers/net/wireless/iwlwifi/iwl-notif-wait.c index 940b8a9d5285..b5bc959b1dfe 100644 --- a/drivers/net/wireless/iwlwifi/iwl-notif-wait.c +++ b/drivers/net/wireless/iwlwifi/iwl-notif-wait.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/iwl-notif-wait.h b/drivers/net/wireless/iwlwifi/iwl-notif-wait.h index 2e2f1c8c99f9..95af97a6c2cf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-notif-wait.h +++ b/drivers/net/wireless/iwlwifi/iwl-notif-wait.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c index a48decc6c68f..1b61cb529948 100644 --- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c +++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h index 3325059c52d4..0c4399aba8c6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h +++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/iwl-op-mode.h b/drivers/net/wireless/iwlwifi/iwl-op-mode.h index f50e6c62ebc5..b5be51f3cd3d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-op-mode.h +++ b/drivers/net/wireless/iwlwifi/iwl-op-mode.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/iwl-phy-db.c b/drivers/net/wireless/iwlwifi/iwl-phy-db.c index 1a405ae6a9c5..fa77d63a277a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-phy-db.c +++ b/drivers/net/wireless/iwlwifi/iwl-phy-db.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/iwl-phy-db.h b/drivers/net/wireless/iwlwifi/iwl-phy-db.h index ce983af79644..9ee18d0d2d01 100644 --- a/drivers/net/wireless/iwlwifi/iwl-phy-db.h +++ b/drivers/net/wireless/iwlwifi/iwl-phy-db.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h index f6412dae2659..d69b0fb0a434 100644 --- a/drivers/net/wireless/iwlwifi/iwl-prph.h +++ b/drivers/net/wireless/iwlwifi/iwl-prph.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 0c3647858909..8d1b5ed3502a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
@@ -622,6 +622,10 @@ static inline int iwl_trans_send_cmd(struct iwl_trans *trans, | |||
622 | { | 622 | { |
623 | int ret; | 623 | int ret; |
624 | 624 | ||
625 | if (unlikely(!(cmd->flags & CMD_SEND_IN_RFKILL) && | ||
626 | test_bit(STATUS_RFKILL, &trans->status))) | ||
627 | return -ERFKILL; | ||
628 | |||
625 | if (unlikely(test_bit(STATUS_FW_ERROR, &trans->status))) | 629 | if (unlikely(test_bit(STATUS_FW_ERROR, &trans->status))) |
626 | return -EIO; | 630 | return -EIO; |
627 | 631 | ||
@@ -684,9 +688,6 @@ static inline void iwl_trans_reclaim(struct iwl_trans *trans, int queue, | |||
684 | 688 | ||
685 | static inline void iwl_trans_txq_disable(struct iwl_trans *trans, int queue) | 689 | static inline void iwl_trans_txq_disable(struct iwl_trans *trans, int queue) |
686 | { | 690 | { |
687 | if (unlikely(trans->state != IWL_TRANS_FW_ALIVE)) | ||
688 | IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); | ||
689 | |||
690 | trans->ops->txq_disable(trans, queue); | 691 | trans->ops->txq_disable(trans, queue); |
691 | } | 692 | } |
692 | 693 | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/binding.c b/drivers/net/wireless/iwlwifi/mvm/binding.c index 57d3eed86efa..a1376539d2dc 100644 --- a/drivers/net/wireless/iwlwifi/mvm/binding.c +++ b/drivers/net/wireless/iwlwifi/mvm/binding.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c index d126245c48de..76cde6ce6551 100644 --- a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c +++ b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
@@ -294,9 +294,9 @@ static const __le64 iwl_ci_mask[][3] = { | |||
294 | cpu_to_le64(0x0) | 294 | cpu_to_le64(0x0) |
295 | }, | 295 | }, |
296 | { | 296 | { |
297 | cpu_to_le64(0xFE00000000ULL), | 297 | cpu_to_le64(0xFFC0000000ULL), |
298 | cpu_to_le64(0x0ULL), | 298 | cpu_to_le64(0x0ULL), |
299 | cpu_to_le64(0x0) | 299 | cpu_to_le64(0x0ULL) |
300 | }, | 300 | }, |
301 | }; | 301 | }; |
302 | 302 | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/constants.h b/drivers/net/wireless/iwlwifi/mvm/constants.h index 4b6d670c3509..036857698565 100644 --- a/drivers/net/wireless/iwlwifi/mvm/constants.h +++ b/drivers/net/wireless/iwlwifi/mvm/constants.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c index 665f87e788d6..f04d2f4d80cd 100644 --- a/drivers/net/wireless/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/iwlwifi/mvm/d3.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c b/drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c index b8667575bc10..0e29cd83a06a 100644 --- a/drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c +++ b/drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c index e8f62a6a1b57..76cdce9edf55 100644 --- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
@@ -123,51 +123,31 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, char __user *user_buf, | |||
123 | { | 123 | { |
124 | struct iwl_mvm *mvm = file->private_data; | 124 | struct iwl_mvm *mvm = file->private_data; |
125 | const struct fw_img *img; | 125 | const struct fw_img *img; |
126 | int ofs, len, pos = 0; | 126 | unsigned int ofs, len; |
127 | size_t bufsz, ret; | 127 | size_t ret; |
128 | char *buf; | ||
129 | u8 *ptr; | 128 | u8 *ptr; |
130 | 129 | ||
131 | if (!mvm->ucode_loaded) | 130 | if (!mvm->ucode_loaded) |
132 | return -EINVAL; | 131 | return -EINVAL; |
133 | 132 | ||
134 | /* default is to dump the entire data segment */ | 133 | /* default is to dump the entire data segment */ |
134 | img = &mvm->fw->img[mvm->cur_ucode]; | ||
135 | ofs = img->sec[IWL_UCODE_SECTION_DATA].offset; | ||
136 | len = img->sec[IWL_UCODE_SECTION_DATA].len; | ||
137 | |||
135 | if (!mvm->dbgfs_sram_offset && !mvm->dbgfs_sram_len) { | 138 | if (!mvm->dbgfs_sram_offset && !mvm->dbgfs_sram_len) { |
136 | img = &mvm->fw->img[mvm->cur_ucode]; | ||
137 | ofs = img->sec[IWL_UCODE_SECTION_DATA].offset; | ||
138 | len = img->sec[IWL_UCODE_SECTION_DATA].len; | ||
139 | } else { | ||
140 | ofs = mvm->dbgfs_sram_offset; | 139 | ofs = mvm->dbgfs_sram_offset; |
141 | len = mvm->dbgfs_sram_len; | 140 | len = mvm->dbgfs_sram_len; |
142 | } | 141 | } |
143 | 142 | ||
144 | bufsz = len * 4 + 256; | ||
145 | buf = kzalloc(bufsz, GFP_KERNEL); | ||
146 | if (!buf) | ||
147 | return -ENOMEM; | ||
148 | |||
149 | ptr = kzalloc(len, GFP_KERNEL); | 143 | ptr = kzalloc(len, GFP_KERNEL); |
150 | if (!ptr) { | 144 | if (!ptr) |
151 | kfree(buf); | ||
152 | return -ENOMEM; | 145 | return -ENOMEM; |
153 | } | ||
154 | |||
155 | pos += scnprintf(buf + pos, bufsz - pos, "sram_len: 0x%x\n", len); | ||
156 | pos += scnprintf(buf + pos, bufsz - pos, "sram_offset: 0x%x\n", ofs); | ||
157 | 146 | ||
158 | iwl_trans_read_mem_bytes(mvm->trans, ofs, ptr, len); | 147 | iwl_trans_read_mem_bytes(mvm->trans, ofs, ptr, len); |
159 | for (ofs = 0; ofs < len; ofs += 16) { | ||
160 | pos += scnprintf(buf + pos, bufsz - pos, "0x%.4x ", ofs); | ||
161 | hex_dump_to_buffer(ptr + ofs, 16, 16, 1, buf + pos, | ||
162 | bufsz - pos, false); | ||
163 | pos += strlen(buf + pos); | ||
164 | if (bufsz - pos > 0) | ||
165 | buf[pos++] = '\n'; | ||
166 | } | ||
167 | 148 | ||
168 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); | 149 | ret = simple_read_from_buffer(user_buf, count, ppos, ptr, len); |
169 | 150 | ||
170 | kfree(buf); | ||
171 | kfree(ptr); | 151 | kfree(ptr); |
172 | 152 | ||
173 | return ret; | 153 | return ret; |
@@ -176,11 +156,24 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, char __user *user_buf, | |||
176 | static ssize_t iwl_dbgfs_sram_write(struct iwl_mvm *mvm, char *buf, | 156 | static ssize_t iwl_dbgfs_sram_write(struct iwl_mvm *mvm, char *buf, |
177 | size_t count, loff_t *ppos) | 157 | size_t count, loff_t *ppos) |
178 | { | 158 | { |
159 | const struct fw_img *img; | ||
179 | u32 offset, len; | 160 | u32 offset, len; |
161 | u32 img_offset, img_len; | ||
162 | |||
163 | if (!mvm->ucode_loaded) | ||
164 | return -EINVAL; | ||
165 | |||
166 | img = &mvm->fw->img[mvm->cur_ucode]; | ||
167 | img_offset = img->sec[IWL_UCODE_SECTION_DATA].offset; | ||
168 | img_len = img->sec[IWL_UCODE_SECTION_DATA].len; | ||
180 | 169 | ||
181 | if (sscanf(buf, "%x,%x", &offset, &len) == 2) { | 170 | if (sscanf(buf, "%x,%x", &offset, &len) == 2) { |
182 | if ((offset & 0x3) || (len & 0x3)) | 171 | if ((offset & 0x3) || (len & 0x3)) |
183 | return -EINVAL; | 172 | return -EINVAL; |
173 | |||
174 | if (offset + len > img_offset + img_len) | ||
175 | return -EINVAL; | ||
176 | |||
184 | mvm->dbgfs_sram_offset = offset; | 177 | mvm->dbgfs_sram_offset = offset; |
185 | mvm->dbgfs_sram_len = len; | 178 | mvm->dbgfs_sram_len = len; |
186 | } else { | 179 | } else { |
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.h b/drivers/net/wireless/iwlwifi/mvm/debugfs.h index 85f9f958bfd2..e3a9774af495 100644 --- a/drivers/net/wireless/iwlwifi/mvm/debugfs.h +++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h index af500996bbf1..1b4e54d416b0 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h index 4e7dd8cf87dc..8415ff312d0e 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h index 39c3148bdfa8..c405cda1025f 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h index cb78e5539357..884c08725308 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h index 532312c7b937..85057219cc43 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h index b3ed59237cba..73cbba7424f2 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h index 8c73ba74b6fd..6bbbad453a3b 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h index 22864671d66c..b674c2a2b51c 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h index 1c3079714c2b..989d7dbdca6c 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c index 27ba104a3540..c03d39541f9e 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/iwlwifi/mvm/fw.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/mvm/led.c b/drivers/net/wireless/iwlwifi/mvm/led.c index 2269a9e5cc67..6b4ea6bf8ffe 100644 --- a/drivers/net/wireless/iwlwifi/mvm/led.c +++ b/drivers/net/wireless/iwlwifi/mvm/led.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
@@ -103,7 +103,7 @@ int iwl_mvm_leds_init(struct iwl_mvm *mvm) | |||
103 | return 0; | 103 | return 0; |
104 | default: | 104 | default: |
105 | return -EINVAL; | 105 | return -EINVAL; |
106 | }; | 106 | } |
107 | 107 | ||
108 | mvm->led.name = kasprintf(GFP_KERNEL, "%s-led", | 108 | mvm->led.name = kasprintf(GFP_KERNEL, "%s-led", |
109 | wiphy_name(mvm->hw->wiphy)); | 109 | wiphy_name(mvm->hw->wiphy)); |
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c index fb93961da750..ba723d50939a 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
@@ -69,10 +69,10 @@ | |||
69 | #include "mvm.h" | 69 | #include "mvm.h" |
70 | 70 | ||
71 | const u8 iwl_mvm_ac_to_tx_fifo[] = { | 71 | const u8 iwl_mvm_ac_to_tx_fifo[] = { |
72 | IWL_MVM_TX_FIFO_BK, | ||
73 | IWL_MVM_TX_FIFO_BE, | ||
74 | IWL_MVM_TX_FIFO_VI, | ||
75 | IWL_MVM_TX_FIFO_VO, | 72 | IWL_MVM_TX_FIFO_VO, |
73 | IWL_MVM_TX_FIFO_VI, | ||
74 | IWL_MVM_TX_FIFO_BE, | ||
75 | IWL_MVM_TX_FIFO_BK, | ||
76 | }; | 76 | }; |
77 | 77 | ||
78 | struct iwl_mvm_mac_iface_iterator_data { | 78 | struct iwl_mvm_mac_iface_iterator_data { |
@@ -85,35 +85,15 @@ struct iwl_mvm_mac_iface_iterator_data { | |||
85 | bool found_vif; | 85 | bool found_vif; |
86 | }; | 86 | }; |
87 | 87 | ||
88 | static void iwl_mvm_mac_iface_iterator(void *_data, u8 *mac, | 88 | static void iwl_mvm_mac_tsf_id_iter(void *_data, u8 *mac, |
89 | struct ieee80211_vif *vif) | 89 | struct ieee80211_vif *vif) |
90 | { | 90 | { |
91 | struct iwl_mvm_mac_iface_iterator_data *data = _data; | 91 | struct iwl_mvm_mac_iface_iterator_data *data = _data; |
92 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | 92 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); |
93 | u32 ac; | ||
94 | 93 | ||
95 | /* Iterator may already find the interface being added -- skip it */ | 94 | /* Skip the interface for which we are trying to assign a tsf_id */ |
96 | if (vif == data->vif) { | 95 | if (vif == data->vif) |
97 | data->found_vif = true; | ||
98 | return; | 96 | return; |
99 | } | ||
100 | |||
101 | /* Mark the queues used by the vif */ | ||
102 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) | ||
103 | if (vif->hw_queue[ac] != IEEE80211_INVAL_HW_QUEUE) | ||
104 | __set_bit(vif->hw_queue[ac], data->used_hw_queues); | ||
105 | |||
106 | if (vif->cab_queue != IEEE80211_INVAL_HW_QUEUE) | ||
107 | __set_bit(vif->cab_queue, data->used_hw_queues); | ||
108 | |||
109 | /* | ||
110 | * Mark MAC IDs as used by clearing the available bit, and | ||
111 | * (below) mark TSFs as used if their existing use is not | ||
112 | * compatible with the new interface type. | ||
113 | * No locking or atomic bit operations are needed since the | ||
114 | * data is on the stack of the caller function. | ||
115 | */ | ||
116 | __clear_bit(mvmvif->id, data->available_mac_ids); | ||
117 | 97 | ||
118 | /* | 98 | /* |
119 | * The TSF is a hardware/firmware resource, there are 4 and | 99 | * The TSF is a hardware/firmware resource, there are 4 and |
@@ -135,21 +115,26 @@ static void iwl_mvm_mac_iface_iterator(void *_data, u8 *mac, | |||
135 | case NL80211_IFTYPE_STATION: | 115 | case NL80211_IFTYPE_STATION: |
136 | /* | 116 | /* |
137 | * The new interface is client, so if the existing one | 117 | * The new interface is client, so if the existing one |
138 | * we're iterating is an AP, the TSF should be used to | 118 | * we're iterating is an AP, and both interfaces have the |
119 | * same beacon interval, the same TSF should be used to | ||
139 | * avoid drift between the new client and existing AP, | 120 | * avoid drift between the new client and existing AP, |
140 | * the existing AP will get drift updates from the new | 121 | * the existing AP will get drift updates from the new |
141 | * client context in this case | 122 | * client context in this case |
142 | */ | 123 | */ |
143 | if (vif->type == NL80211_IFTYPE_AP) { | 124 | if (vif->type == NL80211_IFTYPE_AP) { |
144 | if (data->preferred_tsf == NUM_TSF_IDS && | 125 | if (data->preferred_tsf == NUM_TSF_IDS && |
145 | test_bit(mvmvif->tsf_id, data->available_tsf_ids)) | 126 | test_bit(mvmvif->tsf_id, data->available_tsf_ids) && |
127 | (vif->bss_conf.beacon_int == | ||
128 | data->vif->bss_conf.beacon_int)) { | ||
146 | data->preferred_tsf = mvmvif->tsf_id; | 129 | data->preferred_tsf = mvmvif->tsf_id; |
147 | return; | 130 | return; |
131 | } | ||
148 | } | 132 | } |
149 | break; | 133 | break; |
150 | case NL80211_IFTYPE_AP: | 134 | case NL80211_IFTYPE_AP: |
151 | /* | 135 | /* |
152 | * The new interface is AP/GO, so should get drift | 136 | * The new interface is AP/GO, so in case both interfaces |
137 | * have the same beacon interval, it should get drift | ||
153 | * updates from an existing client or use the same | 138 | * updates from an existing client or use the same |
154 | * TSF as an existing GO. There's no drift between | 139 | * TSF as an existing GO. There's no drift between |
155 | * TSFs internally but if they used different TSFs | 140 | * TSFs internally but if they used different TSFs |
@@ -159,9 +144,12 @@ static void iwl_mvm_mac_iface_iterator(void *_data, u8 *mac, | |||
159 | if (vif->type == NL80211_IFTYPE_STATION || | 144 | if (vif->type == NL80211_IFTYPE_STATION || |
160 | vif->type == NL80211_IFTYPE_AP) { | 145 | vif->type == NL80211_IFTYPE_AP) { |
161 | if (data->preferred_tsf == NUM_TSF_IDS && | 146 | if (data->preferred_tsf == NUM_TSF_IDS && |
162 | test_bit(mvmvif->tsf_id, data->available_tsf_ids)) | 147 | test_bit(mvmvif->tsf_id, data->available_tsf_ids) && |
148 | (vif->bss_conf.beacon_int == | ||
149 | data->vif->bss_conf.beacon_int)) { | ||
163 | data->preferred_tsf = mvmvif->tsf_id; | 150 | data->preferred_tsf = mvmvif->tsf_id; |
164 | return; | 151 | return; |
152 | } | ||
165 | } | 153 | } |
166 | break; | 154 | break; |
167 | default: | 155 | default: |
@@ -187,6 +175,39 @@ static void iwl_mvm_mac_iface_iterator(void *_data, u8 *mac, | |||
187 | data->preferred_tsf = NUM_TSF_IDS; | 175 | data->preferred_tsf = NUM_TSF_IDS; |
188 | } | 176 | } |
189 | 177 | ||
178 | static void iwl_mvm_mac_iface_iterator(void *_data, u8 *mac, | ||
179 | struct ieee80211_vif *vif) | ||
180 | { | ||
181 | struct iwl_mvm_mac_iface_iterator_data *data = _data; | ||
182 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | ||
183 | u32 ac; | ||
184 | |||
185 | /* Iterator may already find the interface being added -- skip it */ | ||
186 | if (vif == data->vif) { | ||
187 | data->found_vif = true; | ||
188 | return; | ||
189 | } | ||
190 | |||
191 | /* Mark the queues used by the vif */ | ||
192 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) | ||
193 | if (vif->hw_queue[ac] != IEEE80211_INVAL_HW_QUEUE) | ||
194 | __set_bit(vif->hw_queue[ac], data->used_hw_queues); | ||
195 | |||
196 | if (vif->cab_queue != IEEE80211_INVAL_HW_QUEUE) | ||
197 | __set_bit(vif->cab_queue, data->used_hw_queues); | ||
198 | |||
199 | /* Mark MAC IDs as used by clearing the available bit, and | ||
200 | * (below) mark TSFs as used if their existing use is not | ||
201 | * compatible with the new interface type. | ||
202 | * No locking or atomic bit operations are needed since the | ||
203 | * data is on the stack of the caller function. | ||
204 | */ | ||
205 | __clear_bit(mvmvif->id, data->available_mac_ids); | ||
206 | |||
207 | /* find a suitable tsf_id */ | ||
208 | iwl_mvm_mac_tsf_id_iter(_data, mac, vif); | ||
209 | } | ||
210 | |||
190 | /* | 211 | /* |
191 | * Get the mask of the queus used by the vif | 212 | * Get the mask of the queus used by the vif |
192 | */ | 213 | */ |
@@ -205,6 +226,29 @@ u32 iwl_mvm_mac_get_queues_mask(struct iwl_mvm *mvm, | |||
205 | return qmask; | 226 | return qmask; |
206 | } | 227 | } |
207 | 228 | ||
229 | void iwl_mvm_mac_ctxt_recalc_tsf_id(struct iwl_mvm *mvm, | ||
230 | struct ieee80211_vif *vif) | ||
231 | { | ||
232 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | ||
233 | struct iwl_mvm_mac_iface_iterator_data data = { | ||
234 | .mvm = mvm, | ||
235 | .vif = vif, | ||
236 | .available_tsf_ids = { (1 << NUM_TSF_IDS) - 1 }, | ||
237 | /* no preference yet */ | ||
238 | .preferred_tsf = NUM_TSF_IDS, | ||
239 | }; | ||
240 | |||
241 | ieee80211_iterate_active_interfaces_atomic( | ||
242 | mvm->hw, IEEE80211_IFACE_ITER_RESUME_ALL, | ||
243 | iwl_mvm_mac_tsf_id_iter, &data); | ||
244 | |||
245 | if (data.preferred_tsf != NUM_TSF_IDS) | ||
246 | mvmvif->tsf_id = data.preferred_tsf; | ||
247 | else if (!test_bit(mvmvif->tsf_id, data.available_tsf_ids)) | ||
248 | mvmvif->tsf_id = find_first_bit(data.available_tsf_ids, | ||
249 | NUM_TSF_IDS); | ||
250 | } | ||
251 | |||
208 | static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm, | 252 | static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm, |
209 | struct ieee80211_vif *vif) | 253 | struct ieee80211_vif *vif) |
210 | { | 254 | { |
@@ -586,18 +630,23 @@ static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm, | |||
586 | cpu_to_le32(vif->bss_conf.use_short_slot ? | 630 | cpu_to_le32(vif->bss_conf.use_short_slot ? |
587 | MAC_FLG_SHORT_SLOT : 0); | 631 | MAC_FLG_SHORT_SLOT : 0); |
588 | 632 | ||
589 | for (i = 0; i < AC_NUM; i++) { | 633 | for (i = 0; i < IEEE80211_NUM_ACS; i++) { |
590 | cmd->ac[i].cw_min = cpu_to_le16(mvmvif->queue_params[i].cw_min); | 634 | u8 txf = iwl_mvm_ac_to_tx_fifo[i]; |
591 | cmd->ac[i].cw_max = cpu_to_le16(mvmvif->queue_params[i].cw_max); | 635 | |
592 | cmd->ac[i].aifsn = mvmvif->queue_params[i].aifs; | 636 | cmd->ac[txf].cw_min = |
593 | cmd->ac[i].edca_txop = | 637 | cpu_to_le16(mvmvif->queue_params[i].cw_min); |
638 | cmd->ac[txf].cw_max = | ||
639 | cpu_to_le16(mvmvif->queue_params[i].cw_max); | ||
640 | cmd->ac[txf].edca_txop = | ||
594 | cpu_to_le16(mvmvif->queue_params[i].txop * 32); | 641 | cpu_to_le16(mvmvif->queue_params[i].txop * 32); |
595 | cmd->ac[i].fifos_mask = BIT(iwl_mvm_ac_to_tx_fifo[i]); | 642 | cmd->ac[txf].aifsn = mvmvif->queue_params[i].aifs; |
643 | cmd->ac[txf].fifos_mask = BIT(txf); | ||
596 | } | 644 | } |
597 | 645 | ||
598 | /* in AP mode, the MCAST FIFO takes the EDCA params from VO */ | 646 | /* in AP mode, the MCAST FIFO takes the EDCA params from VO */ |
599 | if (vif->type == NL80211_IFTYPE_AP) | 647 | if (vif->type == NL80211_IFTYPE_AP) |
600 | cmd->ac[AC_VO].fifos_mask |= BIT(IWL_MVM_TX_FIFO_MCAST); | 648 | cmd->ac[IWL_MVM_TX_FIFO_VO].fifos_mask |= |
649 | BIT(IWL_MVM_TX_FIFO_MCAST); | ||
601 | 650 | ||
602 | if (vif->bss_conf.qos) | 651 | if (vif->bss_conf.qos) |
603 | cmd->qos_flags |= cpu_to_le32(MAC_QOS_FLG_UPDATE_EDCA); | 652 | cmd->qos_flags |= cpu_to_le32(MAC_QOS_FLG_UPDATE_EDCA); |
@@ -1007,7 +1056,7 @@ static void iwl_mvm_mac_ctxt_cmd_fill_ap(struct iwl_mvm *mvm, | |||
1007 | iwl_mvm_mac_ap_iterator, &data); | 1056 | iwl_mvm_mac_ap_iterator, &data); |
1008 | 1057 | ||
1009 | if (data.beacon_device_ts) { | 1058 | if (data.beacon_device_ts) { |
1010 | u32 rand = (prandom_u32() % (80 - 20)) + 20; | 1059 | u32 rand = (prandom_u32() % (64 - 36)) + 36; |
1011 | mvmvif->ap_beacon_time = data.beacon_device_ts + | 1060 | mvmvif->ap_beacon_time = data.beacon_device_ts + |
1012 | ieee80211_tu_to_usec(data.beacon_int * rand / | 1061 | ieee80211_tu_to_usec(data.beacon_int * rand / |
1013 | 100); | 1062 | 100); |
@@ -1186,10 +1235,18 @@ int iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm, | |||
1186 | static void iwl_mvm_beacon_loss_iterator(void *_data, u8 *mac, | 1235 | static void iwl_mvm_beacon_loss_iterator(void *_data, u8 *mac, |
1187 | struct ieee80211_vif *vif) | 1236 | struct ieee80211_vif *vif) |
1188 | { | 1237 | { |
1189 | u16 *id = _data; | 1238 | struct iwl_missed_beacons_notif *missed_beacons = _data; |
1190 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | 1239 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); |
1191 | 1240 | ||
1192 | if (mvmvif->id == *id) | 1241 | if (mvmvif->id != (u16)le32_to_cpu(missed_beacons->mac_id)) |
1242 | return; | ||
1243 | |||
1244 | /* | ||
1245 | * TODO: the threshold should be adjusted based on latency conditions, | ||
1246 | * and/or in case of a CS flow on one of the other AP vifs. | ||
1247 | */ | ||
1248 | if (le32_to_cpu(missed_beacons->consec_missed_beacons_since_last_rx) > | ||
1249 | IWL_MVM_MISSED_BEACONS_THRESHOLD) | ||
1193 | ieee80211_beacon_loss(vif); | 1250 | ieee80211_beacon_loss(vif); |
1194 | } | 1251 | } |
1195 | 1252 | ||
@@ -1198,12 +1255,19 @@ int iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm, | |||
1198 | struct iwl_device_cmd *cmd) | 1255 | struct iwl_device_cmd *cmd) |
1199 | { | 1256 | { |
1200 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 1257 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
1201 | struct iwl_missed_beacons_notif *missed_beacons = (void *)pkt->data; | 1258 | struct iwl_missed_beacons_notif *mb = (void *)pkt->data; |
1202 | u16 id = (u16)le32_to_cpu(missed_beacons->mac_id); | 1259 | |
1260 | IWL_DEBUG_INFO(mvm, | ||
1261 | "missed bcn mac_id=%u, consecutive=%u (%u, %u, %u)\n", | ||
1262 | le32_to_cpu(mb->mac_id), | ||
1263 | le32_to_cpu(mb->consec_missed_beacons), | ||
1264 | le32_to_cpu(mb->consec_missed_beacons_since_last_rx), | ||
1265 | le32_to_cpu(mb->num_recvd_beacons), | ||
1266 | le32_to_cpu(mb->num_expected_beacons)); | ||
1203 | 1267 | ||
1204 | ieee80211_iterate_active_interfaces_atomic(mvm->hw, | 1268 | ieee80211_iterate_active_interfaces_atomic(mvm->hw, |
1205 | IEEE80211_IFACE_ITER_NORMAL, | 1269 | IEEE80211_IFACE_ITER_NORMAL, |
1206 | iwl_mvm_beacon_loss_iterator, | 1270 | iwl_mvm_beacon_loss_iterator, |
1207 | &id); | 1271 | mb); |
1208 | return 0; | 1272 | return 0; |
1209 | } | 1273 | } |
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 2f5269359dce..b41177eb4888 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
@@ -262,7 +262,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) | |||
262 | mvm->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; | 262 | mvm->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; |
263 | 263 | ||
264 | /* currently FW API supports only one optional cipher scheme */ | 264 | /* currently FW API supports only one optional cipher scheme */ |
265 | if (mvm->fw->cs && mvm->fw->cs->cipher) { | 265 | if (mvm->fw->cs->cipher) { |
266 | mvm->hw->n_cipher_schemes = 1; | 266 | mvm->hw->n_cipher_schemes = 1; |
267 | mvm->hw->cipher_schemes = mvm->fw->cs; | 267 | mvm->hw->cipher_schemes = mvm->fw->cs; |
268 | } | 268 | } |
@@ -866,6 +866,14 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm, | |||
866 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | 866 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); |
867 | int ret; | 867 | int ret; |
868 | 868 | ||
869 | /* | ||
870 | * Re-calculate the tsf id, as the master-slave relations depend on the | ||
871 | * beacon interval, which was not known when the station interface was | ||
872 | * added. | ||
873 | */ | ||
874 | if (changes & BSS_CHANGED_ASSOC && bss_conf->assoc) | ||
875 | iwl_mvm_mac_ctxt_recalc_tsf_id(mvm, vif); | ||
876 | |||
869 | ret = iwl_mvm_mac_ctxt_changed(mvm, vif); | 877 | ret = iwl_mvm_mac_ctxt_changed(mvm, vif); |
870 | if (ret) | 878 | if (ret) |
871 | IWL_ERR(mvm, "failed to update MAC %pM\n", vif->addr); | 879 | IWL_ERR(mvm, "failed to update MAC %pM\n", vif->addr); |
@@ -979,6 +987,13 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw, | |||
979 | if (ret) | 987 | if (ret) |
980 | goto out_unlock; | 988 | goto out_unlock; |
981 | 989 | ||
990 | /* | ||
991 | * Re-calculate the tsf id, as the master-slave relations depend on the | ||
992 | * beacon interval, which was not known when the AP interface was added. | ||
993 | */ | ||
994 | if (vif->type == NL80211_IFTYPE_AP) | ||
995 | iwl_mvm_mac_ctxt_recalc_tsf_id(mvm, vif); | ||
996 | |||
982 | /* Add the mac context */ | 997 | /* Add the mac context */ |
983 | ret = iwl_mvm_mac_ctxt_add(mvm, vif); | 998 | ret = iwl_mvm_mac_ctxt_add(mvm, vif); |
984 | if (ret) | 999 | if (ret) |
@@ -1671,7 +1686,8 @@ static void iwl_mvm_change_chanctx(struct ieee80211_hw *hw, | |||
1671 | if (WARN_ONCE((phy_ctxt->ref > 1) && | 1686 | if (WARN_ONCE((phy_ctxt->ref > 1) && |
1672 | (changed & ~(IEEE80211_CHANCTX_CHANGE_WIDTH | | 1687 | (changed & ~(IEEE80211_CHANCTX_CHANGE_WIDTH | |
1673 | IEEE80211_CHANCTX_CHANGE_RX_CHAINS | | 1688 | IEEE80211_CHANCTX_CHANGE_RX_CHAINS | |
1674 | IEEE80211_CHANCTX_CHANGE_RADAR)), | 1689 | IEEE80211_CHANCTX_CHANGE_RADAR | |
1690 | IEEE80211_CHANCTX_CHANGE_MIN_WIDTH)), | ||
1675 | "Cannot change PHY. Ref=%d, changed=0x%X\n", | 1691 | "Cannot change PHY. Ref=%d, changed=0x%X\n", |
1676 | phy_ctxt->ref, changed)) | 1692 | phy_ctxt->ref, changed)) |
1677 | return; | 1693 | return; |
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index 84edf3649ad2..e4ead86f06d6 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
@@ -81,6 +81,7 @@ | |||
81 | #define IWL_MVM_MAX_ADDRESSES 5 | 81 | #define IWL_MVM_MAX_ADDRESSES 5 |
82 | /* RSSI offset for WkP */ | 82 | /* RSSI offset for WkP */ |
83 | #define IWL_RSSI_OFFSET 50 | 83 | #define IWL_RSSI_OFFSET 50 |
84 | #define IWL_MVM_MISSED_BEACONS_THRESHOLD 8 | ||
84 | 85 | ||
85 | enum iwl_mvm_tx_fifo { | 86 | enum iwl_mvm_tx_fifo { |
86 | IWL_MVM_TX_FIFO_BK = 0, | 87 | IWL_MVM_TX_FIFO_BK = 0, |
@@ -711,6 +712,8 @@ int iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm, | |||
711 | int iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm, | 712 | int iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm, |
712 | struct iwl_rx_cmd_buffer *rxb, | 713 | struct iwl_rx_cmd_buffer *rxb, |
713 | struct iwl_device_cmd *cmd); | 714 | struct iwl_device_cmd *cmd); |
715 | void iwl_mvm_mac_ctxt_recalc_tsf_id(struct iwl_mvm *mvm, | ||
716 | struct ieee80211_vif *vif); | ||
714 | 717 | ||
715 | /* Bindings */ | 718 | /* Bindings */ |
716 | int iwl_mvm_binding_add_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif); | 719 | int iwl_mvm_binding_add_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif); |
diff --git a/drivers/net/wireless/iwlwifi/mvm/nvm.c b/drivers/net/wireless/iwlwifi/mvm/nvm.c index 48089b1625ff..c6beb0f842d5 100644 --- a/drivers/net/wireless/iwlwifi/mvm/nvm.c +++ b/drivers/net/wireless/iwlwifi/mvm/nvm.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
@@ -367,16 +367,17 @@ static int iwl_mvm_read_external_nvm(struct iwl_mvm *mvm) | |||
367 | break; | 367 | break; |
368 | } | 368 | } |
369 | 369 | ||
370 | if (WARN(section_id >= NVM_NUM_OF_SECTIONS, | ||
371 | "Invalid NVM section ID %d\n", section_id)) { | ||
372 | ret = -EINVAL; | ||
373 | break; | ||
374 | } | ||
375 | |||
370 | temp = kmemdup(file_sec->data, section_size, GFP_KERNEL); | 376 | temp = kmemdup(file_sec->data, section_size, GFP_KERNEL); |
371 | if (!temp) { | 377 | if (!temp) { |
372 | ret = -ENOMEM; | 378 | ret = -ENOMEM; |
373 | break; | 379 | break; |
374 | } | 380 | } |
375 | if (WARN_ON(section_id >= NVM_NUM_OF_SECTIONS)) { | ||
376 | IWL_ERR(mvm, "Invalid NVM section ID\n"); | ||
377 | ret = -EINVAL; | ||
378 | break; | ||
379 | } | ||
380 | mvm->nvm_sections[section_id].data = temp; | 381 | mvm->nvm_sections[section_id].data = temp; |
381 | mvm->nvm_sections[section_id].length = section_size; | 382 | mvm->nvm_sections[section_id].length = section_size; |
382 | 383 | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c index a362430477a0..552c76a926ed 100644 --- a/drivers/net/wireless/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/iwlwifi/mvm/ops.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
@@ -665,6 +665,8 @@ static void iwl_mvm_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state) | |||
665 | else | 665 | else |
666 | clear_bit(IWL_MVM_STATUS_HW_RFKILL, &mvm->status); | 666 | clear_bit(IWL_MVM_STATUS_HW_RFKILL, &mvm->status); |
667 | 667 | ||
668 | if (state && mvm->cur_ucode != IWL_UCODE_INIT) | ||
669 | iwl_trans_stop_device(mvm->trans); | ||
668 | wiphy_rfkill_set_hw_state(mvm->hw->wiphy, iwl_mvm_is_radio_killed(mvm)); | 670 | wiphy_rfkill_set_hw_state(mvm->hw->wiphy, iwl_mvm_is_radio_killed(mvm)); |
669 | } | 671 | } |
670 | 672 | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c index a8652ddd6bed..b7268c0b3333 100644 --- a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c +++ b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/mvm/power.c b/drivers/net/wireless/iwlwifi/mvm/power.c index 483ecc67501f..d9eab3b7bb9f 100644 --- a/drivers/net/wireless/iwlwifi/mvm/power.c +++ b/drivers/net/wireless/iwlwifi/mvm/power.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
@@ -64,7 +64,6 @@ | |||
64 | #include <linux/kernel.h> | 64 | #include <linux/kernel.h> |
65 | #include <linux/module.h> | 65 | #include <linux/module.h> |
66 | #include <linux/slab.h> | 66 | #include <linux/slab.h> |
67 | #include <linux/init.h> | ||
68 | 67 | ||
69 | #include <net/mac80211.h> | 68 | #include <net/mac80211.h> |
70 | 69 | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/power_legacy.c b/drivers/net/wireless/iwlwifi/mvm/power_legacy.c index 2ce79bad5845..ef712ae5bc62 100644 --- a/drivers/net/wireless/iwlwifi/mvm/power_legacy.c +++ b/drivers/net/wireless/iwlwifi/mvm/power_legacy.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/mvm/quota.c b/drivers/net/wireless/iwlwifi/mvm/quota.c index 38165eba2a17..ce5db6c4ef7e 100644 --- a/drivers/net/wireless/iwlwifi/mvm/quota.c +++ b/drivers/net/wireless/iwlwifi/mvm/quota.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c index d6d28d7b442b..ba078a3322b8 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/iwlwifi/mvm/rs.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify it | 5 | * This program is free software; you can redistribute it and/or modify it |
6 | * under the terms of version 2 of the GNU General Public License as | 6 | * under the terms of version 2 of the GNU General Public License as |
@@ -24,7 +24,6 @@ | |||
24 | * | 24 | * |
25 | *****************************************************************************/ | 25 | *****************************************************************************/ |
26 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
27 | #include <linux/init.h> | ||
28 | #include <linux/skbuff.h> | 27 | #include <linux/skbuff.h> |
29 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
30 | #include <net/mac80211.h> | 29 | #include <net/mac80211.h> |
@@ -700,7 +699,7 @@ static int rs_rate_from_ucode_rate(const u32 ucode_rate, | |||
700 | u8 num_of_ant = get_num_of_ant_from_rate(ucode_rate); | 699 | u8 num_of_ant = get_num_of_ant_from_rate(ucode_rate); |
701 | u8 nss; | 700 | u8 nss; |
702 | 701 | ||
703 | memset(rate, 0, sizeof(struct rs_rate)); | 702 | memset(rate, 0, sizeof(*rate)); |
704 | rate->index = iwl_hwrate_to_plcp_idx(ucode_rate); | 703 | rate->index = iwl_hwrate_to_plcp_idx(ucode_rate); |
705 | 704 | ||
706 | if (rate->index == IWL_RATE_INVALID) { | 705 | if (rate->index == IWL_RATE_INVALID) { |
@@ -2121,7 +2120,7 @@ static void rs_initialize_lq(struct iwl_mvm *mvm, | |||
2121 | tbl->column = RS_COLUMN_LEGACY_ANT_B; | 2120 | tbl->column = RS_COLUMN_LEGACY_ANT_B; |
2122 | 2121 | ||
2123 | rs_set_expected_tpt_table(lq_sta, tbl); | 2122 | rs_set_expected_tpt_table(lq_sta, tbl); |
2124 | rs_fill_lq_cmd(NULL, NULL, lq_sta, rate); | 2123 | rs_fill_lq_cmd(mvm, sta, lq_sta, rate); |
2125 | /* TODO restore station should remember the lq cmd */ | 2124 | /* TODO restore station should remember the lq cmd */ |
2126 | iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, init); | 2125 | iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, init); |
2127 | } | 2126 | } |
@@ -2446,10 +2445,9 @@ static void rs_build_rates_table(struct iwl_mvm *mvm, | |||
2446 | struct iwl_lq_cmd *lq_cmd = &lq_sta->lq; | 2445 | struct iwl_lq_cmd *lq_cmd = &lq_sta->lq; |
2447 | bool toggle_ant = false; | 2446 | bool toggle_ant = false; |
2448 | 2447 | ||
2449 | memcpy(&rate, initial_rate, sizeof(struct rs_rate)); | 2448 | memcpy(&rate, initial_rate, sizeof(rate)); |
2450 | 2449 | ||
2451 | if (mvm) | 2450 | valid_tx_ant = iwl_fw_valid_tx_ant(mvm->fw); |
2452 | valid_tx_ant = iwl_fw_valid_tx_ant(mvm->fw); | ||
2453 | 2451 | ||
2454 | if (is_siso(&rate)) { | 2452 | if (is_siso(&rate)) { |
2455 | num_rates = RS_INITIAL_SISO_NUM_RATES; | 2453 | num_rates = RS_INITIAL_SISO_NUM_RATES; |
@@ -2623,7 +2621,7 @@ static void rs_program_fix_rate(struct iwl_mvm *mvm, | |||
2623 | struct rs_rate rate; | 2621 | struct rs_rate rate; |
2624 | rs_rate_from_ucode_rate(lq_sta->dbg_fixed_rate, | 2622 | rs_rate_from_ucode_rate(lq_sta->dbg_fixed_rate, |
2625 | lq_sta->band, &rate); | 2623 | lq_sta->band, &rate); |
2626 | rs_fill_lq_cmd(NULL, NULL, lq_sta, &rate); | 2624 | rs_fill_lq_cmd(mvm, NULL, lq_sta, &rate); |
2627 | iwl_mvm_send_lq_cmd(lq_sta->drv, &lq_sta->lq, false); | 2625 | iwl_mvm_send_lq_cmd(lq_sta->drv, &lq_sta->lq, false); |
2628 | } | 2626 | } |
2629 | } | 2627 | } |
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.h b/drivers/net/wireless/iwlwifi/mvm/rs.h index c31aa59728ea..7bc6404f6986 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rs.h +++ b/drivers/net/wireless/iwlwifi/mvm/rs.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2003 - 2013 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify it | 5 | * This program is free software; you can redistribute it and/or modify it |
6 | * under the terms of version 2 of the GNU General Public License as | 6 | * under the terms of version 2 of the GNU General Public License as |
diff --git a/drivers/net/wireless/iwlwifi/mvm/rx.c b/drivers/net/wireless/iwlwifi/mvm/rx.c index 454341cc3b27..a85b60f7e67e 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rx.c +++ b/drivers/net/wireless/iwlwifi/mvm/rx.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c index 4ce9bb581144..0e0007960612 100644 --- a/drivers/net/wireless/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/iwlwifi/mvm/scan.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
@@ -473,13 +473,18 @@ void iwl_mvm_cancel_scan(struct iwl_mvm *mvm) | |||
473 | if (mvm->scan_status == IWL_MVM_SCAN_NONE) | 473 | if (mvm->scan_status == IWL_MVM_SCAN_NONE) |
474 | return; | 474 | return; |
475 | 475 | ||
476 | if (iwl_mvm_is_radio_killed(mvm)) { | ||
477 | ieee80211_scan_completed(mvm->hw, true); | ||
478 | mvm->scan_status = IWL_MVM_SCAN_NONE; | ||
479 | return; | ||
480 | } | ||
481 | |||
476 | iwl_init_notification_wait(&mvm->notif_wait, &wait_scan_abort, | 482 | iwl_init_notification_wait(&mvm->notif_wait, &wait_scan_abort, |
477 | scan_abort_notif, | 483 | scan_abort_notif, |
478 | ARRAY_SIZE(scan_abort_notif), | 484 | ARRAY_SIZE(scan_abort_notif), |
479 | iwl_mvm_scan_abort_notif, NULL); | 485 | iwl_mvm_scan_abort_notif, NULL); |
480 | 486 | ||
481 | ret = iwl_mvm_send_cmd_pdu(mvm, SCAN_ABORT_CMD, | 487 | ret = iwl_mvm_send_cmd_pdu(mvm, SCAN_ABORT_CMD, CMD_SYNC, 0, NULL); |
482 | CMD_SYNC | CMD_SEND_IN_RFKILL, 0, NULL); | ||
483 | if (ret) { | 488 | if (ret) { |
484 | IWL_ERR(mvm, "Couldn't send SCAN_ABORT_CMD: %d\n", ret); | 489 | IWL_ERR(mvm, "Couldn't send SCAN_ABORT_CMD: %d\n", ret); |
485 | /* mac80211's state will be cleaned in the fw_restart flow */ | 490 | /* mac80211's state will be cleaned in the fw_restart flow */ |
diff --git a/drivers/net/wireless/iwlwifi/mvm/sf.c b/drivers/net/wireless/iwlwifi/mvm/sf.c index 97bb3c3e75ce..8401627c0030 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sf.c +++ b/drivers/net/wireless/iwlwifi/mvm/sf.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c index 0a8af2083ddc..ec1812133235 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/iwlwifi/mvm/sta.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.h b/drivers/net/wireless/iwlwifi/mvm/sta.h index b34941148a98..4968d0237dc5 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.h +++ b/drivers/net/wireless/iwlwifi/mvm/sta.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/mvm/testmode.h b/drivers/net/wireless/iwlwifi/mvm/testmode.h index eb74391d91ca..0241665925f7 100644 --- a/drivers/net/wireless/iwlwifi/mvm/testmode.h +++ b/drivers/net/wireless/iwlwifi/mvm/testmode.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.c b/drivers/net/wireless/iwlwifi/mvm/time-event.c index 95ce4b601fef..50f3d7f560bc 100644 --- a/drivers/net/wireless/iwlwifi/mvm/time-event.c +++ b/drivers/net/wireless/iwlwifi/mvm/time-event.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.h b/drivers/net/wireless/iwlwifi/mvm/time-event.h index d9c8d6cfa2db..4a61c8c02372 100644 --- a/drivers/net/wireless/iwlwifi/mvm/time-event.h +++ b/drivers/net/wireless/iwlwifi/mvm/time-event.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/mvm/tt.c b/drivers/net/wireless/iwlwifi/mvm/tt.c index a0ec7b3473bd..3afa6b6bf835 100644 --- a/drivers/net/wireless/iwlwifi/mvm/tt.c +++ b/drivers/net/wireless/iwlwifi/mvm/tt.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c index 735f86da7985..3c575a39987b 100644 --- a/drivers/net/wireless/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/iwlwifi/mvm/tx.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c index f4aff56a36da..487d61b25359 100644 --- a/drivers/net/wireless/iwlwifi/mvm/utils.c +++ b/drivers/net/wireless/iwlwifi/mvm/utils.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c index 2e97a3995333..e58b8af56c04 100644 --- a/drivers/net/wireless/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/iwlwifi/pcie/drv.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/pcie/internal.h b/drivers/net/wireless/iwlwifi/pcie/internal.h index 674c75b0d002..e851f26fd44c 100644 --- a/drivers/net/wireless/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/iwlwifi/pcie/internal.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2003 - 2013 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * Portions of this file are derived from the ipw3945 project, as well | 5 | * Portions of this file are derived from the ipw3945 project, as well |
6 | * as portions of the ieee80211 subsystem header files. | 6 | * as portions of the ieee80211 subsystem header files. |
@@ -262,6 +262,7 @@ iwl_pcie_get_scratchbuf_dma(struct iwl_txq *txq, int idx) | |||
262 | * @rx_page_order: page order for receive buffer size | 262 | * @rx_page_order: page order for receive buffer size |
263 | * @wd_timeout: queue watchdog timeout (jiffies) | 263 | * @wd_timeout: queue watchdog timeout (jiffies) |
264 | * @reg_lock: protect hw register access | 264 | * @reg_lock: protect hw register access |
265 | * @cmd_in_flight: true when we have a host command in flight | ||
265 | */ | 266 | */ |
266 | struct iwl_trans_pcie { | 267 | struct iwl_trans_pcie { |
267 | struct iwl_rxq rxq; | 268 | struct iwl_rxq rxq; |
@@ -273,7 +274,6 @@ struct iwl_trans_pcie { | |||
273 | __le32 *ict_tbl; | 274 | __le32 *ict_tbl; |
274 | dma_addr_t ict_tbl_dma; | 275 | dma_addr_t ict_tbl_dma; |
275 | int ict_index; | 276 | int ict_index; |
276 | u32 inta; | ||
277 | bool use_ict; | 277 | bool use_ict; |
278 | struct isr_statistics isr_stats; | 278 | struct isr_statistics isr_stats; |
279 | 279 | ||
@@ -311,6 +311,7 @@ struct iwl_trans_pcie { | |||
311 | 311 | ||
312 | /*protect hw register */ | 312 | /*protect hw register */ |
313 | spinlock_t reg_lock; | 313 | spinlock_t reg_lock; |
314 | bool cmd_in_flight; | ||
314 | }; | 315 | }; |
315 | 316 | ||
316 | #define IWL_TRANS_GET_PCIE_TRANS(_iwl_trans) \ | 317 | #define IWL_TRANS_GET_PCIE_TRANS(_iwl_trans) \ |
@@ -343,7 +344,7 @@ void iwl_pcie_rx_free(struct iwl_trans *trans); | |||
343 | /***************************************************** | 344 | /***************************************************** |
344 | * ICT - interrupt handling | 345 | * ICT - interrupt handling |
345 | ******************************************************/ | 346 | ******************************************************/ |
346 | irqreturn_t iwl_pcie_isr_ict(int irq, void *data); | 347 | irqreturn_t iwl_pcie_isr(int irq, void *data); |
347 | int iwl_pcie_alloc_ict(struct iwl_trans *trans); | 348 | int iwl_pcie_alloc_ict(struct iwl_trans *trans); |
348 | void iwl_pcie_free_ict(struct iwl_trans *trans); | 349 | void iwl_pcie_free_ict(struct iwl_trans *trans); |
349 | void iwl_pcie_reset_ict(struct iwl_trans *trans); | 350 | void iwl_pcie_reset_ict(struct iwl_trans *trans); |
@@ -397,13 +398,17 @@ static inline void iwl_enable_interrupts(struct iwl_trans *trans) | |||
397 | 398 | ||
398 | IWL_DEBUG_ISR(trans, "Enabling interrupts\n"); | 399 | IWL_DEBUG_ISR(trans, "Enabling interrupts\n"); |
399 | set_bit(STATUS_INT_ENABLED, &trans->status); | 400 | set_bit(STATUS_INT_ENABLED, &trans->status); |
401 | trans_pcie->inta_mask = CSR_INI_SET_MASK; | ||
400 | iwl_write32(trans, CSR_INT_MASK, trans_pcie->inta_mask); | 402 | iwl_write32(trans, CSR_INT_MASK, trans_pcie->inta_mask); |
401 | } | 403 | } |
402 | 404 | ||
403 | static inline void iwl_enable_rfkill_int(struct iwl_trans *trans) | 405 | static inline void iwl_enable_rfkill_int(struct iwl_trans *trans) |
404 | { | 406 | { |
407 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
408 | |||
405 | IWL_DEBUG_ISR(trans, "Enabling rfkill interrupt\n"); | 409 | IWL_DEBUG_ISR(trans, "Enabling rfkill interrupt\n"); |
406 | iwl_write32(trans, CSR_INT_MASK, CSR_INT_BIT_RF_KILL); | 410 | trans_pcie->inta_mask = CSR_INT_BIT_RF_KILL; |
411 | iwl_write32(trans, CSR_INT_MASK, trans_pcie->inta_mask); | ||
407 | } | 412 | } |
408 | 413 | ||
409 | static inline void iwl_wake_queue(struct iwl_trans *trans, | 414 | static inline void iwl_wake_queue(struct iwl_trans *trans, |
@@ -456,4 +461,31 @@ static inline bool iwl_is_rfkill_set(struct iwl_trans *trans) | |||
456 | CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW); | 461 | CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW); |
457 | } | 462 | } |
458 | 463 | ||
464 | static inline void __iwl_trans_pcie_set_bits_mask(struct iwl_trans *trans, | ||
465 | u32 reg, u32 mask, u32 value) | ||
466 | { | ||
467 | u32 v; | ||
468 | |||
469 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
470 | WARN_ON_ONCE(value & ~mask); | ||
471 | #endif | ||
472 | |||
473 | v = iwl_read32(trans, reg); | ||
474 | v &= ~mask; | ||
475 | v |= value; | ||
476 | iwl_write32(trans, reg, v); | ||
477 | } | ||
478 | |||
479 | static inline void __iwl_trans_pcie_clear_bit(struct iwl_trans *trans, | ||
480 | u32 reg, u32 mask) | ||
481 | { | ||
482 | __iwl_trans_pcie_set_bits_mask(trans, reg, mask, 0); | ||
483 | } | ||
484 | |||
485 | static inline void __iwl_trans_pcie_set_bit(struct iwl_trans *trans, | ||
486 | u32 reg, u32 mask) | ||
487 | { | ||
488 | __iwl_trans_pcie_set_bits_mask(trans, reg, mask, mask); | ||
489 | } | ||
490 | |||
459 | #endif /* __iwl_trans_int_pcie_h__ */ | 491 | #endif /* __iwl_trans_int_pcie_h__ */ |
diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c index 7aeec5ccefa5..1890ea29c264 100644 --- a/drivers/net/wireless/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/iwlwifi/pcie/rx.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2003 - 2013 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * Portions of this file are derived from the ipw3945 project, as well | 5 | * Portions of this file are derived from the ipw3945 project, as well |
6 | * as portions of the ieee80211 subsystem header files. | 6 | * as portions of the ieee80211 subsystem header files. |
@@ -148,10 +148,9 @@ int iwl_pcie_rx_stop(struct iwl_trans *trans) | |||
148 | static void iwl_pcie_rxq_inc_wr_ptr(struct iwl_trans *trans, | 148 | static void iwl_pcie_rxq_inc_wr_ptr(struct iwl_trans *trans, |
149 | struct iwl_rxq *rxq) | 149 | struct iwl_rxq *rxq) |
150 | { | 150 | { |
151 | unsigned long flags; | ||
152 | u32 reg; | 151 | u32 reg; |
153 | 152 | ||
154 | spin_lock_irqsave(&rxq->lock, flags); | 153 | spin_lock(&rxq->lock); |
155 | 154 | ||
156 | if (rxq->need_update == 0) | 155 | if (rxq->need_update == 0) |
157 | goto exit_unlock; | 156 | goto exit_unlock; |
@@ -190,7 +189,7 @@ static void iwl_pcie_rxq_inc_wr_ptr(struct iwl_trans *trans, | |||
190 | rxq->need_update = 0; | 189 | rxq->need_update = 0; |
191 | 190 | ||
192 | exit_unlock: | 191 | exit_unlock: |
193 | spin_unlock_irqrestore(&rxq->lock, flags); | 192 | spin_unlock(&rxq->lock); |
194 | } | 193 | } |
195 | 194 | ||
196 | /* | 195 | /* |
@@ -209,7 +208,6 @@ static void iwl_pcie_rxq_restock(struct iwl_trans *trans) | |||
209 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 208 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
210 | struct iwl_rxq *rxq = &trans_pcie->rxq; | 209 | struct iwl_rxq *rxq = &trans_pcie->rxq; |
211 | struct iwl_rx_mem_buffer *rxb; | 210 | struct iwl_rx_mem_buffer *rxb; |
212 | unsigned long flags; | ||
213 | 211 | ||
214 | /* | 212 | /* |
215 | * If the device isn't enabled - not need to try to add buffers... | 213 | * If the device isn't enabled - not need to try to add buffers... |
@@ -222,7 +220,7 @@ static void iwl_pcie_rxq_restock(struct iwl_trans *trans) | |||
222 | if (!test_bit(STATUS_DEVICE_ENABLED, &trans->status)) | 220 | if (!test_bit(STATUS_DEVICE_ENABLED, &trans->status)) |
223 | return; | 221 | return; |
224 | 222 | ||
225 | spin_lock_irqsave(&rxq->lock, flags); | 223 | spin_lock(&rxq->lock); |
226 | while ((iwl_rxq_space(rxq) > 0) && (rxq->free_count)) { | 224 | while ((iwl_rxq_space(rxq) > 0) && (rxq->free_count)) { |
227 | /* The overwritten rxb must be a used one */ | 225 | /* The overwritten rxb must be a used one */ |
228 | rxb = rxq->queue[rxq->write]; | 226 | rxb = rxq->queue[rxq->write]; |
@@ -239,7 +237,7 @@ static void iwl_pcie_rxq_restock(struct iwl_trans *trans) | |||
239 | rxq->write = (rxq->write + 1) & RX_QUEUE_MASK; | 237 | rxq->write = (rxq->write + 1) & RX_QUEUE_MASK; |
240 | rxq->free_count--; | 238 | rxq->free_count--; |
241 | } | 239 | } |
242 | spin_unlock_irqrestore(&rxq->lock, flags); | 240 | spin_unlock(&rxq->lock); |
243 | /* If the pre-allocated buffer pool is dropping low, schedule to | 241 | /* If the pre-allocated buffer pool is dropping low, schedule to |
244 | * refill it */ | 242 | * refill it */ |
245 | if (rxq->free_count <= RX_LOW_WATERMARK) | 243 | if (rxq->free_count <= RX_LOW_WATERMARK) |
@@ -248,9 +246,9 @@ static void iwl_pcie_rxq_restock(struct iwl_trans *trans) | |||
248 | /* If we've added more space for the firmware to place data, tell it. | 246 | /* If we've added more space for the firmware to place data, tell it. |
249 | * Increment device's write pointer in multiples of 8. */ | 247 | * Increment device's write pointer in multiples of 8. */ |
250 | if (rxq->write_actual != (rxq->write & ~0x7)) { | 248 | if (rxq->write_actual != (rxq->write & ~0x7)) { |
251 | spin_lock_irqsave(&rxq->lock, flags); | 249 | spin_lock(&rxq->lock); |
252 | rxq->need_update = 1; | 250 | rxq->need_update = 1; |
253 | spin_unlock_irqrestore(&rxq->lock, flags); | 251 | spin_unlock(&rxq->lock); |
254 | iwl_pcie_rxq_inc_wr_ptr(trans, rxq); | 252 | iwl_pcie_rxq_inc_wr_ptr(trans, rxq); |
255 | } | 253 | } |
256 | } | 254 | } |
@@ -270,16 +268,15 @@ static void iwl_pcie_rxq_alloc_rbs(struct iwl_trans *trans, gfp_t priority) | |||
270 | struct iwl_rxq *rxq = &trans_pcie->rxq; | 268 | struct iwl_rxq *rxq = &trans_pcie->rxq; |
271 | struct iwl_rx_mem_buffer *rxb; | 269 | struct iwl_rx_mem_buffer *rxb; |
272 | struct page *page; | 270 | struct page *page; |
273 | unsigned long flags; | ||
274 | gfp_t gfp_mask = priority; | 271 | gfp_t gfp_mask = priority; |
275 | 272 | ||
276 | while (1) { | 273 | while (1) { |
277 | spin_lock_irqsave(&rxq->lock, flags); | 274 | spin_lock(&rxq->lock); |
278 | if (list_empty(&rxq->rx_used)) { | 275 | if (list_empty(&rxq->rx_used)) { |
279 | spin_unlock_irqrestore(&rxq->lock, flags); | 276 | spin_unlock(&rxq->lock); |
280 | return; | 277 | return; |
281 | } | 278 | } |
282 | spin_unlock_irqrestore(&rxq->lock, flags); | 279 | spin_unlock(&rxq->lock); |
283 | 280 | ||
284 | if (rxq->free_count > RX_LOW_WATERMARK) | 281 | if (rxq->free_count > RX_LOW_WATERMARK) |
285 | gfp_mask |= __GFP_NOWARN; | 282 | gfp_mask |= __GFP_NOWARN; |
@@ -308,17 +305,17 @@ static void iwl_pcie_rxq_alloc_rbs(struct iwl_trans *trans, gfp_t priority) | |||
308 | return; | 305 | return; |
309 | } | 306 | } |
310 | 307 | ||
311 | spin_lock_irqsave(&rxq->lock, flags); | 308 | spin_lock(&rxq->lock); |
312 | 309 | ||
313 | if (list_empty(&rxq->rx_used)) { | 310 | if (list_empty(&rxq->rx_used)) { |
314 | spin_unlock_irqrestore(&rxq->lock, flags); | 311 | spin_unlock(&rxq->lock); |
315 | __free_pages(page, trans_pcie->rx_page_order); | 312 | __free_pages(page, trans_pcie->rx_page_order); |
316 | return; | 313 | return; |
317 | } | 314 | } |
318 | rxb = list_first_entry(&rxq->rx_used, struct iwl_rx_mem_buffer, | 315 | rxb = list_first_entry(&rxq->rx_used, struct iwl_rx_mem_buffer, |
319 | list); | 316 | list); |
320 | list_del(&rxb->list); | 317 | list_del(&rxb->list); |
321 | spin_unlock_irqrestore(&rxq->lock, flags); | 318 | spin_unlock(&rxq->lock); |
322 | 319 | ||
323 | BUG_ON(rxb->page); | 320 | BUG_ON(rxb->page); |
324 | rxb->page = page; | 321 | rxb->page = page; |
@@ -329,9 +326,9 @@ static void iwl_pcie_rxq_alloc_rbs(struct iwl_trans *trans, gfp_t priority) | |||
329 | DMA_FROM_DEVICE); | 326 | DMA_FROM_DEVICE); |
330 | if (dma_mapping_error(trans->dev, rxb->page_dma)) { | 327 | if (dma_mapping_error(trans->dev, rxb->page_dma)) { |
331 | rxb->page = NULL; | 328 | rxb->page = NULL; |
332 | spin_lock_irqsave(&rxq->lock, flags); | 329 | spin_lock(&rxq->lock); |
333 | list_add(&rxb->list, &rxq->rx_used); | 330 | list_add(&rxb->list, &rxq->rx_used); |
334 | spin_unlock_irqrestore(&rxq->lock, flags); | 331 | spin_unlock(&rxq->lock); |
335 | __free_pages(page, trans_pcie->rx_page_order); | 332 | __free_pages(page, trans_pcie->rx_page_order); |
336 | return; | 333 | return; |
337 | } | 334 | } |
@@ -340,12 +337,12 @@ static void iwl_pcie_rxq_alloc_rbs(struct iwl_trans *trans, gfp_t priority) | |||
340 | /* and also 256 byte aligned! */ | 337 | /* and also 256 byte aligned! */ |
341 | BUG_ON(rxb->page_dma & DMA_BIT_MASK(8)); | 338 | BUG_ON(rxb->page_dma & DMA_BIT_MASK(8)); |
342 | 339 | ||
343 | spin_lock_irqsave(&rxq->lock, flags); | 340 | spin_lock(&rxq->lock); |
344 | 341 | ||
345 | list_add_tail(&rxb->list, &rxq->rx_free); | 342 | list_add_tail(&rxb->list, &rxq->rx_free); |
346 | rxq->free_count++; | 343 | rxq->free_count++; |
347 | 344 | ||
348 | spin_unlock_irqrestore(&rxq->lock, flags); | 345 | spin_unlock(&rxq->lock); |
349 | } | 346 | } |
350 | } | 347 | } |
351 | 348 | ||
@@ -379,13 +376,12 @@ static void iwl_pcie_rxq_free_rbs(struct iwl_trans *trans) | |||
379 | static void iwl_pcie_rx_replenish(struct iwl_trans *trans) | 376 | static void iwl_pcie_rx_replenish(struct iwl_trans *trans) |
380 | { | 377 | { |
381 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 378 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
382 | unsigned long flags; | ||
383 | 379 | ||
384 | iwl_pcie_rxq_alloc_rbs(trans, GFP_KERNEL); | 380 | iwl_pcie_rxq_alloc_rbs(trans, GFP_KERNEL); |
385 | 381 | ||
386 | spin_lock_irqsave(&trans_pcie->irq_lock, flags); | 382 | spin_lock(&trans_pcie->irq_lock); |
387 | iwl_pcie_rxq_restock(trans); | 383 | iwl_pcie_rxq_restock(trans); |
388 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); | 384 | spin_unlock(&trans_pcie->irq_lock); |
389 | } | 385 | } |
390 | 386 | ||
391 | static void iwl_pcie_rx_replenish_now(struct iwl_trans *trans) | 387 | static void iwl_pcie_rx_replenish_now(struct iwl_trans *trans) |
@@ -511,7 +507,6 @@ int iwl_pcie_rx_init(struct iwl_trans *trans) | |||
511 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 507 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
512 | struct iwl_rxq *rxq = &trans_pcie->rxq; | 508 | struct iwl_rxq *rxq = &trans_pcie->rxq; |
513 | int i, err; | 509 | int i, err; |
514 | unsigned long flags; | ||
515 | 510 | ||
516 | if (!rxq->bd) { | 511 | if (!rxq->bd) { |
517 | err = iwl_pcie_rx_alloc(trans); | 512 | err = iwl_pcie_rx_alloc(trans); |
@@ -519,7 +514,7 @@ int iwl_pcie_rx_init(struct iwl_trans *trans) | |||
519 | return err; | 514 | return err; |
520 | } | 515 | } |
521 | 516 | ||
522 | spin_lock_irqsave(&rxq->lock, flags); | 517 | spin_lock(&rxq->lock); |
523 | 518 | ||
524 | INIT_WORK(&trans_pcie->rx_replenish, iwl_pcie_rx_replenish_work); | 519 | INIT_WORK(&trans_pcie->rx_replenish, iwl_pcie_rx_replenish_work); |
525 | 520 | ||
@@ -535,16 +530,16 @@ int iwl_pcie_rx_init(struct iwl_trans *trans) | |||
535 | rxq->read = rxq->write = 0; | 530 | rxq->read = rxq->write = 0; |
536 | rxq->write_actual = 0; | 531 | rxq->write_actual = 0; |
537 | memset(rxq->rb_stts, 0, sizeof(*rxq->rb_stts)); | 532 | memset(rxq->rb_stts, 0, sizeof(*rxq->rb_stts)); |
538 | spin_unlock_irqrestore(&rxq->lock, flags); | 533 | spin_unlock(&rxq->lock); |
539 | 534 | ||
540 | iwl_pcie_rx_replenish(trans); | 535 | iwl_pcie_rx_replenish(trans); |
541 | 536 | ||
542 | iwl_pcie_rx_hw_init(trans, rxq); | 537 | iwl_pcie_rx_hw_init(trans, rxq); |
543 | 538 | ||
544 | spin_lock_irqsave(&trans_pcie->irq_lock, flags); | 539 | spin_lock(&trans_pcie->irq_lock); |
545 | rxq->need_update = 1; | 540 | rxq->need_update = 1; |
546 | iwl_pcie_rxq_inc_wr_ptr(trans, rxq); | 541 | iwl_pcie_rxq_inc_wr_ptr(trans, rxq); |
547 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); | 542 | spin_unlock(&trans_pcie->irq_lock); |
548 | 543 | ||
549 | return 0; | 544 | return 0; |
550 | } | 545 | } |
@@ -553,7 +548,6 @@ void iwl_pcie_rx_free(struct iwl_trans *trans) | |||
553 | { | 548 | { |
554 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 549 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
555 | struct iwl_rxq *rxq = &trans_pcie->rxq; | 550 | struct iwl_rxq *rxq = &trans_pcie->rxq; |
556 | unsigned long flags; | ||
557 | 551 | ||
558 | /*if rxq->bd is NULL, it means that nothing has been allocated, | 552 | /*if rxq->bd is NULL, it means that nothing has been allocated, |
559 | * exit now */ | 553 | * exit now */ |
@@ -564,9 +558,9 @@ void iwl_pcie_rx_free(struct iwl_trans *trans) | |||
564 | 558 | ||
565 | cancel_work_sync(&trans_pcie->rx_replenish); | 559 | cancel_work_sync(&trans_pcie->rx_replenish); |
566 | 560 | ||
567 | spin_lock_irqsave(&rxq->lock, flags); | 561 | spin_lock(&rxq->lock); |
568 | iwl_pcie_rxq_free_rbs(trans); | 562 | iwl_pcie_rxq_free_rbs(trans); |
569 | spin_unlock_irqrestore(&rxq->lock, flags); | 563 | spin_unlock(&rxq->lock); |
570 | 564 | ||
571 | dma_free_coherent(trans->dev, sizeof(__le32) * RX_QUEUE_SIZE, | 565 | dma_free_coherent(trans->dev, sizeof(__le32) * RX_QUEUE_SIZE, |
572 | rxq->bd, rxq->bd_dma); | 566 | rxq->bd, rxq->bd_dma); |
@@ -589,7 +583,6 @@ static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans, | |||
589 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 583 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
590 | struct iwl_rxq *rxq = &trans_pcie->rxq; | 584 | struct iwl_rxq *rxq = &trans_pcie->rxq; |
591 | struct iwl_txq *txq = &trans_pcie->txq[trans_pcie->cmd_queue]; | 585 | struct iwl_txq *txq = &trans_pcie->txq[trans_pcie->cmd_queue]; |
592 | unsigned long flags; | ||
593 | bool page_stolen = false; | 586 | bool page_stolen = false; |
594 | int max_len = PAGE_SIZE << trans_pcie->rx_page_order; | 587 | int max_len = PAGE_SIZE << trans_pcie->rx_page_order; |
595 | u32 offset = 0; | 588 | u32 offset = 0; |
@@ -691,7 +684,7 @@ static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans, | |||
691 | /* Reuse the page if possible. For notification packets and | 684 | /* Reuse the page if possible. For notification packets and |
692 | * SKBs that fail to Rx correctly, add them back into the | 685 | * SKBs that fail to Rx correctly, add them back into the |
693 | * rx_free list for reuse later. */ | 686 | * rx_free list for reuse later. */ |
694 | spin_lock_irqsave(&rxq->lock, flags); | 687 | spin_lock(&rxq->lock); |
695 | if (rxb->page != NULL) { | 688 | if (rxb->page != NULL) { |
696 | rxb->page_dma = | 689 | rxb->page_dma = |
697 | dma_map_page(trans->dev, rxb->page, 0, | 690 | dma_map_page(trans->dev, rxb->page, 0, |
@@ -712,7 +705,7 @@ static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans, | |||
712 | } | 705 | } |
713 | } else | 706 | } else |
714 | list_add_tail(&rxb->list, &rxq->rx_used); | 707 | list_add_tail(&rxb->list, &rxq->rx_used); |
715 | spin_unlock_irqrestore(&rxq->lock, flags); | 708 | spin_unlock(&rxq->lock); |
716 | } | 709 | } |
717 | 710 | ||
718 | /* | 711 | /* |
@@ -807,6 +800,87 @@ static void iwl_pcie_irq_handle_error(struct iwl_trans *trans) | |||
807 | wake_up(&trans_pcie->wait_command_queue); | 800 | wake_up(&trans_pcie->wait_command_queue); |
808 | } | 801 | } |
809 | 802 | ||
803 | static u32 iwl_pcie_int_cause_non_ict(struct iwl_trans *trans) | ||
804 | { | ||
805 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
806 | u32 inta; | ||
807 | |||
808 | lockdep_assert_held(&trans_pcie->irq_lock); | ||
809 | |||
810 | trace_iwlwifi_dev_irq(trans->dev); | ||
811 | |||
812 | /* Discover which interrupts are active/pending */ | ||
813 | inta = iwl_read32(trans, CSR_INT); | ||
814 | |||
815 | /* the thread will service interrupts and re-enable them */ | ||
816 | return inta; | ||
817 | } | ||
818 | |||
819 | /* a device (PCI-E) page is 4096 bytes long */ | ||
820 | #define ICT_SHIFT 12 | ||
821 | #define ICT_SIZE (1 << ICT_SHIFT) | ||
822 | #define ICT_COUNT (ICT_SIZE / sizeof(u32)) | ||
823 | |||
824 | /* interrupt handler using ict table, with this interrupt driver will | ||
825 | * stop using INTA register to get device's interrupt, reading this register | ||
826 | * is expensive, device will write interrupts in ICT dram table, increment | ||
827 | * index then will fire interrupt to driver, driver will OR all ICT table | ||
828 | * entries from current index up to table entry with 0 value. the result is | ||
829 | * the interrupt we need to service, driver will set the entries back to 0 and | ||
830 | * set index. | ||
831 | */ | ||
832 | static u32 iwl_pcie_int_cause_ict(struct iwl_trans *trans) | ||
833 | { | ||
834 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
835 | u32 inta; | ||
836 | u32 val = 0; | ||
837 | u32 read; | ||
838 | |||
839 | trace_iwlwifi_dev_irq(trans->dev); | ||
840 | |||
841 | /* Ignore interrupt if there's nothing in NIC to service. | ||
842 | * This may be due to IRQ shared with another device, | ||
843 | * or due to sporadic interrupts thrown from our NIC. */ | ||
844 | read = le32_to_cpu(trans_pcie->ict_tbl[trans_pcie->ict_index]); | ||
845 | trace_iwlwifi_dev_ict_read(trans->dev, trans_pcie->ict_index, read); | ||
846 | if (!read) | ||
847 | return 0; | ||
848 | |||
849 | /* | ||
850 | * Collect all entries up to the first 0, starting from ict_index; | ||
851 | * note we already read at ict_index. | ||
852 | */ | ||
853 | do { | ||
854 | val |= read; | ||
855 | IWL_DEBUG_ISR(trans, "ICT index %d value 0x%08X\n", | ||
856 | trans_pcie->ict_index, read); | ||
857 | trans_pcie->ict_tbl[trans_pcie->ict_index] = 0; | ||
858 | trans_pcie->ict_index = | ||
859 | iwl_queue_inc_wrap(trans_pcie->ict_index, ICT_COUNT); | ||
860 | |||
861 | read = le32_to_cpu(trans_pcie->ict_tbl[trans_pcie->ict_index]); | ||
862 | trace_iwlwifi_dev_ict_read(trans->dev, trans_pcie->ict_index, | ||
863 | read); | ||
864 | } while (read); | ||
865 | |||
866 | /* We should not get this value, just ignore it. */ | ||
867 | if (val == 0xffffffff) | ||
868 | val = 0; | ||
869 | |||
870 | /* | ||
871 | * this is a w/a for a h/w bug. the h/w bug may cause the Rx bit | ||
872 | * (bit 15 before shifting it to 31) to clear when using interrupt | ||
873 | * coalescing. fortunately, bits 18 and 19 stay set when this happens | ||
874 | * so we use them to decide on the real state of the Rx bit. | ||
875 | * In order words, bit 15 is set if bit 18 or bit 19 are set. | ||
876 | */ | ||
877 | if (val & 0xC0000) | ||
878 | val |= 0x8000; | ||
879 | |||
880 | inta = (0xff & val) | ((0xff00 & val) << 16); | ||
881 | return inta; | ||
882 | } | ||
883 | |||
810 | irqreturn_t iwl_pcie_irq_handler(int irq, void *dev_id) | 884 | irqreturn_t iwl_pcie_irq_handler(int irq, void *dev_id) |
811 | { | 885 | { |
812 | struct iwl_trans *trans = dev_id; | 886 | struct iwl_trans *trans = dev_id; |
@@ -814,12 +888,61 @@ irqreturn_t iwl_pcie_irq_handler(int irq, void *dev_id) | |||
814 | struct isr_statistics *isr_stats = &trans_pcie->isr_stats; | 888 | struct isr_statistics *isr_stats = &trans_pcie->isr_stats; |
815 | u32 inta = 0; | 889 | u32 inta = 0; |
816 | u32 handled = 0; | 890 | u32 handled = 0; |
817 | unsigned long flags; | ||
818 | u32 i; | 891 | u32 i; |
819 | 892 | ||
820 | lock_map_acquire(&trans->sync_cmd_lockdep_map); | 893 | lock_map_acquire(&trans->sync_cmd_lockdep_map); |
821 | 894 | ||
822 | spin_lock_irqsave(&trans_pcie->irq_lock, flags); | 895 | spin_lock(&trans_pcie->irq_lock); |
896 | |||
897 | /* dram interrupt table not set yet, | ||
898 | * use legacy interrupt. | ||
899 | */ | ||
900 | if (likely(trans_pcie->use_ict)) | ||
901 | inta = iwl_pcie_int_cause_ict(trans); | ||
902 | else | ||
903 | inta = iwl_pcie_int_cause_non_ict(trans); | ||
904 | |||
905 | if (iwl_have_debug_level(IWL_DL_ISR)) { | ||
906 | IWL_DEBUG_ISR(trans, | ||
907 | "ISR inta 0x%08x, enabled 0x%08x(sw), enabled(hw) 0x%08x, fh 0x%08x\n", | ||
908 | inta, trans_pcie->inta_mask, | ||
909 | iwl_read32(trans, CSR_INT_MASK), | ||
910 | iwl_read32(trans, CSR_FH_INT_STATUS)); | ||
911 | if (inta & (~trans_pcie->inta_mask)) | ||
912 | IWL_DEBUG_ISR(trans, | ||
913 | "We got a masked interrupt (0x%08x)\n", | ||
914 | inta & (~trans_pcie->inta_mask)); | ||
915 | } | ||
916 | |||
917 | inta &= trans_pcie->inta_mask; | ||
918 | |||
919 | /* | ||
920 | * Ignore interrupt if there's nothing in NIC to service. | ||
921 | * This may be due to IRQ shared with another device, | ||
922 | * or due to sporadic interrupts thrown from our NIC. | ||
923 | */ | ||
924 | if (unlikely(!inta)) { | ||
925 | IWL_DEBUG_ISR(trans, "Ignore interrupt, inta == 0\n"); | ||
926 | /* | ||
927 | * Re-enable interrupts here since we don't | ||
928 | * have anything to service | ||
929 | */ | ||
930 | if (test_bit(STATUS_INT_ENABLED, &trans->status)) | ||
931 | iwl_enable_interrupts(trans); | ||
932 | spin_unlock(&trans_pcie->irq_lock); | ||
933 | lock_map_release(&trans->sync_cmd_lockdep_map); | ||
934 | return IRQ_NONE; | ||
935 | } | ||
936 | |||
937 | if (unlikely(inta == 0xFFFFFFFF || (inta & 0xFFFFFFF0) == 0xa5a5a5a0)) { | ||
938 | /* | ||
939 | * Hardware disappeared. It might have | ||
940 | * already raised an interrupt. | ||
941 | */ | ||
942 | IWL_WARN(trans, "HARDWARE GONE?? INTA == 0x%08x\n", inta); | ||
943 | spin_unlock(&trans_pcie->irq_lock); | ||
944 | goto out; | ||
945 | } | ||
823 | 946 | ||
824 | /* Ack/clear/reset pending uCode interrupts. | 947 | /* Ack/clear/reset pending uCode interrupts. |
825 | * Note: Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS, | 948 | * Note: Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS, |
@@ -832,19 +955,13 @@ irqreturn_t iwl_pcie_irq_handler(int irq, void *dev_id) | |||
832 | * hardware bugs here by ACKing all the possible interrupts so that | 955 | * hardware bugs here by ACKing all the possible interrupts so that |
833 | * interrupt coalescing can still be achieved. | 956 | * interrupt coalescing can still be achieved. |
834 | */ | 957 | */ |
835 | iwl_write32(trans, CSR_INT, | 958 | iwl_write32(trans, CSR_INT, inta | ~trans_pcie->inta_mask); |
836 | trans_pcie->inta | ~trans_pcie->inta_mask); | ||
837 | |||
838 | inta = trans_pcie->inta; | ||
839 | 959 | ||
840 | if (iwl_have_debug_level(IWL_DL_ISR)) | 960 | if (iwl_have_debug_level(IWL_DL_ISR)) |
841 | IWL_DEBUG_ISR(trans, "inta 0x%08x, enabled 0x%08x\n", | 961 | IWL_DEBUG_ISR(trans, "inta 0x%08x, enabled 0x%08x\n", |
842 | inta, iwl_read32(trans, CSR_INT_MASK)); | 962 | inta, iwl_read32(trans, CSR_INT_MASK)); |
843 | 963 | ||
844 | /* saved interrupt in inta variable now we can reset trans_pcie->inta */ | 964 | spin_unlock(&trans_pcie->irq_lock); |
845 | trans_pcie->inta = 0; | ||
846 | |||
847 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); | ||
848 | 965 | ||
849 | /* Now service all interrupt bits discovered above. */ | 966 | /* Now service all interrupt bits discovered above. */ |
850 | if (inta & CSR_INT_BIT_HW_ERR) { | 967 | if (inta & CSR_INT_BIT_HW_ERR) { |
@@ -1019,11 +1136,6 @@ out: | |||
1019 | * | 1136 | * |
1020 | ******************************************************************************/ | 1137 | ******************************************************************************/ |
1021 | 1138 | ||
1022 | /* a device (PCI-E) page is 4096 bytes long */ | ||
1023 | #define ICT_SHIFT 12 | ||
1024 | #define ICT_SIZE (1 << ICT_SHIFT) | ||
1025 | #define ICT_COUNT (ICT_SIZE / sizeof(u32)) | ||
1026 | |||
1027 | /* Free dram table */ | 1139 | /* Free dram table */ |
1028 | void iwl_pcie_free_ict(struct iwl_trans *trans) | 1140 | void iwl_pcie_free_ict(struct iwl_trans *trans) |
1029 | { | 1141 | { |
@@ -1048,7 +1160,7 @@ int iwl_pcie_alloc_ict(struct iwl_trans *trans) | |||
1048 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 1160 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
1049 | 1161 | ||
1050 | trans_pcie->ict_tbl = | 1162 | trans_pcie->ict_tbl = |
1051 | dma_alloc_coherent(trans->dev, ICT_SIZE, | 1163 | dma_zalloc_coherent(trans->dev, ICT_SIZE, |
1052 | &trans_pcie->ict_tbl_dma, | 1164 | &trans_pcie->ict_tbl_dma, |
1053 | GFP_KERNEL); | 1165 | GFP_KERNEL); |
1054 | if (!trans_pcie->ict_tbl) | 1166 | if (!trans_pcie->ict_tbl) |
@@ -1060,17 +1172,10 @@ int iwl_pcie_alloc_ict(struct iwl_trans *trans) | |||
1060 | return -EINVAL; | 1172 | return -EINVAL; |
1061 | } | 1173 | } |
1062 | 1174 | ||
1063 | IWL_DEBUG_ISR(trans, "ict dma addr %Lx\n", | 1175 | IWL_DEBUG_ISR(trans, "ict dma addr %Lx ict vir addr %p\n", |
1064 | (unsigned long long)trans_pcie->ict_tbl_dma); | 1176 | (unsigned long long)trans_pcie->ict_tbl_dma, |
1065 | 1177 | trans_pcie->ict_tbl); | |
1066 | IWL_DEBUG_ISR(trans, "ict vir addr %p\n", trans_pcie->ict_tbl); | ||
1067 | 1178 | ||
1068 | /* reset table and index to all 0 */ | ||
1069 | memset(trans_pcie->ict_tbl, 0, ICT_SIZE); | ||
1070 | trans_pcie->ict_index = 0; | ||
1071 | |||
1072 | /* add periodic RX interrupt */ | ||
1073 | trans_pcie->inta_mask |= CSR_INT_BIT_RX_PERIODIC; | ||
1074 | return 0; | 1179 | return 0; |
1075 | } | 1180 | } |
1076 | 1181 | ||
@@ -1081,12 +1186,11 @@ void iwl_pcie_reset_ict(struct iwl_trans *trans) | |||
1081 | { | 1186 | { |
1082 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 1187 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
1083 | u32 val; | 1188 | u32 val; |
1084 | unsigned long flags; | ||
1085 | 1189 | ||
1086 | if (!trans_pcie->ict_tbl) | 1190 | if (!trans_pcie->ict_tbl) |
1087 | return; | 1191 | return; |
1088 | 1192 | ||
1089 | spin_lock_irqsave(&trans_pcie->irq_lock, flags); | 1193 | spin_lock(&trans_pcie->irq_lock); |
1090 | iwl_disable_interrupts(trans); | 1194 | iwl_disable_interrupts(trans); |
1091 | 1195 | ||
1092 | memset(trans_pcie->ict_tbl, 0, ICT_SIZE); | 1196 | memset(trans_pcie->ict_tbl, 0, ICT_SIZE); |
@@ -1103,120 +1207,26 @@ void iwl_pcie_reset_ict(struct iwl_trans *trans) | |||
1103 | trans_pcie->ict_index = 0; | 1207 | trans_pcie->ict_index = 0; |
1104 | iwl_write32(trans, CSR_INT, trans_pcie->inta_mask); | 1208 | iwl_write32(trans, CSR_INT, trans_pcie->inta_mask); |
1105 | iwl_enable_interrupts(trans); | 1209 | iwl_enable_interrupts(trans); |
1106 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); | 1210 | spin_unlock(&trans_pcie->irq_lock); |
1107 | } | 1211 | } |
1108 | 1212 | ||
1109 | /* Device is going down disable ict interrupt usage */ | 1213 | /* Device is going down disable ict interrupt usage */ |
1110 | void iwl_pcie_disable_ict(struct iwl_trans *trans) | 1214 | void iwl_pcie_disable_ict(struct iwl_trans *trans) |
1111 | { | 1215 | { |
1112 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 1216 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
1113 | unsigned long flags; | ||
1114 | 1217 | ||
1115 | spin_lock_irqsave(&trans_pcie->irq_lock, flags); | 1218 | spin_lock(&trans_pcie->irq_lock); |
1116 | trans_pcie->use_ict = false; | 1219 | trans_pcie->use_ict = false; |
1117 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); | 1220 | spin_unlock(&trans_pcie->irq_lock); |
1118 | } | ||
1119 | |||
1120 | /* legacy (non-ICT) ISR. Assumes that trans_pcie->irq_lock is held */ | ||
1121 | static irqreturn_t iwl_pcie_isr(int irq, void *data) | ||
1122 | { | ||
1123 | struct iwl_trans *trans = data; | ||
1124 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
1125 | u32 inta, inta_mask; | ||
1126 | |||
1127 | lockdep_assert_held(&trans_pcie->irq_lock); | ||
1128 | |||
1129 | trace_iwlwifi_dev_irq(trans->dev); | ||
1130 | |||
1131 | /* Disable (but don't clear!) interrupts here to avoid | ||
1132 | * back-to-back ISRs and sporadic interrupts from our NIC. | ||
1133 | * If we have something to service, the irq thread will re-enable ints. | ||
1134 | * If we *don't* have something, we'll re-enable before leaving here. */ | ||
1135 | inta_mask = iwl_read32(trans, CSR_INT_MASK); | ||
1136 | iwl_write32(trans, CSR_INT_MASK, 0x00000000); | ||
1137 | |||
1138 | /* Discover which interrupts are active/pending */ | ||
1139 | inta = iwl_read32(trans, CSR_INT); | ||
1140 | |||
1141 | if (inta & (~inta_mask)) { | ||
1142 | IWL_DEBUG_ISR(trans, | ||
1143 | "We got a masked interrupt (0x%08x)...Ack and ignore\n", | ||
1144 | inta & (~inta_mask)); | ||
1145 | iwl_write32(trans, CSR_INT, inta & (~inta_mask)); | ||
1146 | inta &= inta_mask; | ||
1147 | } | ||
1148 | |||
1149 | /* Ignore interrupt if there's nothing in NIC to service. | ||
1150 | * This may be due to IRQ shared with another device, | ||
1151 | * or due to sporadic interrupts thrown from our NIC. */ | ||
1152 | if (!inta) { | ||
1153 | IWL_DEBUG_ISR(trans, "Ignore interrupt, inta == 0\n"); | ||
1154 | /* | ||
1155 | * Re-enable interrupts here since we don't have anything to | ||
1156 | * service, but only in case the handler won't run. Note that | ||
1157 | * the handler can be scheduled because of a previous | ||
1158 | * interrupt. | ||
1159 | */ | ||
1160 | if (test_bit(STATUS_INT_ENABLED, &trans->status) && | ||
1161 | !trans_pcie->inta) | ||
1162 | iwl_enable_interrupts(trans); | ||
1163 | return IRQ_NONE; | ||
1164 | } | ||
1165 | |||
1166 | if ((inta == 0xFFFFFFFF) || ((inta & 0xFFFFFFF0) == 0xa5a5a5a0)) { | ||
1167 | /* Hardware disappeared. It might have already raised | ||
1168 | * an interrupt */ | ||
1169 | IWL_WARN(trans, "HARDWARE GONE?? INTA == 0x%08x\n", inta); | ||
1170 | return IRQ_HANDLED; | ||
1171 | } | ||
1172 | |||
1173 | if (iwl_have_debug_level(IWL_DL_ISR)) | ||
1174 | IWL_DEBUG_ISR(trans, | ||
1175 | "ISR inta 0x%08x, enabled 0x%08x, fh 0x%08x\n", | ||
1176 | inta, inta_mask, | ||
1177 | iwl_read32(trans, CSR_FH_INT_STATUS)); | ||
1178 | |||
1179 | trans_pcie->inta |= inta; | ||
1180 | /* the thread will service interrupts and re-enable them */ | ||
1181 | return IRQ_WAKE_THREAD; | ||
1182 | } | 1221 | } |
1183 | 1222 | ||
1184 | /* interrupt handler using ict table, with this interrupt driver will | 1223 | irqreturn_t iwl_pcie_isr(int irq, void *data) |
1185 | * stop using INTA register to get device's interrupt, reading this register | ||
1186 | * is expensive, device will write interrupts in ICT dram table, increment | ||
1187 | * index then will fire interrupt to driver, driver will OR all ICT table | ||
1188 | * entries from current index up to table entry with 0 value. the result is | ||
1189 | * the interrupt we need to service, driver will set the entries back to 0 and | ||
1190 | * set index. | ||
1191 | */ | ||
1192 | irqreturn_t iwl_pcie_isr_ict(int irq, void *data) | ||
1193 | { | 1224 | { |
1194 | struct iwl_trans *trans = data; | 1225 | struct iwl_trans *trans = data; |
1195 | struct iwl_trans_pcie *trans_pcie; | ||
1196 | u32 inta; | ||
1197 | u32 val = 0; | ||
1198 | u32 read; | ||
1199 | unsigned long flags; | ||
1200 | irqreturn_t ret = IRQ_NONE; | ||
1201 | 1226 | ||
1202 | if (!trans) | 1227 | if (!trans) |
1203 | return IRQ_NONE; | 1228 | return IRQ_NONE; |
1204 | 1229 | ||
1205 | trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
1206 | |||
1207 | spin_lock_irqsave(&trans_pcie->irq_lock, flags); | ||
1208 | |||
1209 | /* dram interrupt table not set yet, | ||
1210 | * use legacy interrupt. | ||
1211 | */ | ||
1212 | if (unlikely(!trans_pcie->use_ict)) { | ||
1213 | ret = iwl_pcie_isr(irq, data); | ||
1214 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); | ||
1215 | return ret; | ||
1216 | } | ||
1217 | |||
1218 | trace_iwlwifi_dev_irq(trans->dev); | ||
1219 | |||
1220 | /* Disable (but don't clear!) interrupts here to avoid | 1230 | /* Disable (but don't clear!) interrupts here to avoid |
1221 | * back-to-back ISRs and sporadic interrupts from our NIC. | 1231 | * back-to-back ISRs and sporadic interrupts from our NIC. |
1222 | * If we have something to service, the tasklet will re-enable ints. | 1232 | * If we have something to service, the tasklet will re-enable ints. |
@@ -1224,73 +1234,5 @@ irqreturn_t iwl_pcie_isr_ict(int irq, void *data) | |||
1224 | */ | 1234 | */ |
1225 | iwl_write32(trans, CSR_INT_MASK, 0x00000000); | 1235 | iwl_write32(trans, CSR_INT_MASK, 0x00000000); |
1226 | 1236 | ||
1227 | /* Ignore interrupt if there's nothing in NIC to service. | 1237 | return IRQ_WAKE_THREAD; |
1228 | * This may be due to IRQ shared with another device, | ||
1229 | * or due to sporadic interrupts thrown from our NIC. */ | ||
1230 | read = le32_to_cpu(trans_pcie->ict_tbl[trans_pcie->ict_index]); | ||
1231 | trace_iwlwifi_dev_ict_read(trans->dev, trans_pcie->ict_index, read); | ||
1232 | if (!read) { | ||
1233 | IWL_DEBUG_ISR(trans, "Ignore interrupt, inta == 0\n"); | ||
1234 | goto none; | ||
1235 | } | ||
1236 | |||
1237 | /* | ||
1238 | * Collect all entries up to the first 0, starting from ict_index; | ||
1239 | * note we already read at ict_index. | ||
1240 | */ | ||
1241 | do { | ||
1242 | val |= read; | ||
1243 | IWL_DEBUG_ISR(trans, "ICT index %d value 0x%08X\n", | ||
1244 | trans_pcie->ict_index, read); | ||
1245 | trans_pcie->ict_tbl[trans_pcie->ict_index] = 0; | ||
1246 | trans_pcie->ict_index = | ||
1247 | iwl_queue_inc_wrap(trans_pcie->ict_index, ICT_COUNT); | ||
1248 | |||
1249 | read = le32_to_cpu(trans_pcie->ict_tbl[trans_pcie->ict_index]); | ||
1250 | trace_iwlwifi_dev_ict_read(trans->dev, trans_pcie->ict_index, | ||
1251 | read); | ||
1252 | } while (read); | ||
1253 | |||
1254 | /* We should not get this value, just ignore it. */ | ||
1255 | if (val == 0xffffffff) | ||
1256 | val = 0; | ||
1257 | |||
1258 | /* | ||
1259 | * this is a w/a for a h/w bug. the h/w bug may cause the Rx bit | ||
1260 | * (bit 15 before shifting it to 31) to clear when using interrupt | ||
1261 | * coalescing. fortunately, bits 18 and 19 stay set when this happens | ||
1262 | * so we use them to decide on the real state of the Rx bit. | ||
1263 | * In order words, bit 15 is set if bit 18 or bit 19 are set. | ||
1264 | */ | ||
1265 | if (val & 0xC0000) | ||
1266 | val |= 0x8000; | ||
1267 | |||
1268 | inta = (0xff & val) | ((0xff00 & val) << 16); | ||
1269 | IWL_DEBUG_ISR(trans, "ISR inta 0x%08x, enabled(sw) 0x%08x ict 0x%08x\n", | ||
1270 | inta, trans_pcie->inta_mask, val); | ||
1271 | if (iwl_have_debug_level(IWL_DL_ISR)) | ||
1272 | IWL_DEBUG_ISR(trans, "enabled(hw) 0x%08x\n", | ||
1273 | iwl_read32(trans, CSR_INT_MASK)); | ||
1274 | |||
1275 | inta &= trans_pcie->inta_mask; | ||
1276 | trans_pcie->inta |= inta; | ||
1277 | |||
1278 | /* iwl_pcie_tasklet() will service interrupts and re-enable them */ | ||
1279 | if (likely(inta)) { | ||
1280 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); | ||
1281 | return IRQ_WAKE_THREAD; | ||
1282 | } | ||
1283 | |||
1284 | ret = IRQ_HANDLED; | ||
1285 | |||
1286 | none: | ||
1287 | /* re-enable interrupts here since we don't have anything to service. | ||
1288 | * only Re-enable if disabled by irq. | ||
1289 | */ | ||
1290 | if (test_bit(STATUS_INT_ENABLED, &trans->status) && | ||
1291 | !trans_pcie->inta) | ||
1292 | iwl_enable_interrupts(trans); | ||
1293 | |||
1294 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); | ||
1295 | return ret; | ||
1296 | } | 1238 | } |
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index eecd38e3f15f..16f66c1a23de 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
@@ -75,33 +75,6 @@ | |||
75 | #include "iwl-agn-hw.h" | 75 | #include "iwl-agn-hw.h" |
76 | #include "internal.h" | 76 | #include "internal.h" |
77 | 77 | ||
78 | static void __iwl_trans_pcie_set_bits_mask(struct iwl_trans *trans, | ||
79 | u32 reg, u32 mask, u32 value) | ||
80 | { | ||
81 | u32 v; | ||
82 | |||
83 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
84 | WARN_ON_ONCE(value & ~mask); | ||
85 | #endif | ||
86 | |||
87 | v = iwl_read32(trans, reg); | ||
88 | v &= ~mask; | ||
89 | v |= value; | ||
90 | iwl_write32(trans, reg, v); | ||
91 | } | ||
92 | |||
93 | static inline void __iwl_trans_pcie_clear_bit(struct iwl_trans *trans, | ||
94 | u32 reg, u32 mask) | ||
95 | { | ||
96 | __iwl_trans_pcie_set_bits_mask(trans, reg, mask, 0); | ||
97 | } | ||
98 | |||
99 | static inline void __iwl_trans_pcie_set_bit(struct iwl_trans *trans, | ||
100 | u32 reg, u32 mask) | ||
101 | { | ||
102 | __iwl_trans_pcie_set_bits_mask(trans, reg, mask, mask); | ||
103 | } | ||
104 | |||
105 | static void iwl_pcie_set_pwr(struct iwl_trans *trans, bool vaux) | 78 | static void iwl_pcie_set_pwr(struct iwl_trans *trans, bool vaux) |
106 | { | 79 | { |
107 | if (vaux && pci_pme_capable(to_pci_dev(trans->dev), PCI_D3cold)) | 80 | if (vaux && pci_pme_capable(to_pci_dev(trans->dev), PCI_D3cold)) |
@@ -271,13 +244,12 @@ static void iwl_pcie_apm_stop(struct iwl_trans *trans) | |||
271 | static int iwl_pcie_nic_init(struct iwl_trans *trans) | 244 | static int iwl_pcie_nic_init(struct iwl_trans *trans) |
272 | { | 245 | { |
273 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 246 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
274 | unsigned long flags; | ||
275 | 247 | ||
276 | /* nic_init */ | 248 | /* nic_init */ |
277 | spin_lock_irqsave(&trans_pcie->irq_lock, flags); | 249 | spin_lock(&trans_pcie->irq_lock); |
278 | iwl_pcie_apm_init(trans); | 250 | iwl_pcie_apm_init(trans); |
279 | 251 | ||
280 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); | 252 | spin_unlock(&trans_pcie->irq_lock); |
281 | 253 | ||
282 | iwl_pcie_set_pwr(trans, false); | 254 | iwl_pcie_set_pwr(trans, false); |
283 | 255 | ||
@@ -635,13 +607,14 @@ static void iwl_trans_pcie_fw_alive(struct iwl_trans *trans, u32 scd_addr) | |||
635 | static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) | 607 | static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) |
636 | { | 608 | { |
637 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 609 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
638 | unsigned long flags; | 610 | bool hw_rfkill, was_hw_rfkill; |
639 | bool hw_rfkill; | 611 | |
612 | was_hw_rfkill = iwl_is_rfkill_set(trans); | ||
640 | 613 | ||
641 | /* tell the device to stop sending interrupts */ | 614 | /* tell the device to stop sending interrupts */ |
642 | spin_lock_irqsave(&trans_pcie->irq_lock, flags); | 615 | spin_lock(&trans_pcie->irq_lock); |
643 | iwl_disable_interrupts(trans); | 616 | iwl_disable_interrupts(trans); |
644 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); | 617 | spin_unlock(&trans_pcie->irq_lock); |
645 | 618 | ||
646 | /* device going down, Stop using ICT table */ | 619 | /* device going down, Stop using ICT table */ |
647 | iwl_pcie_disable_ict(trans); | 620 | iwl_pcie_disable_ict(trans); |
@@ -673,9 +646,9 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) | |||
673 | /* Upon stop, the APM issues an interrupt if HW RF kill is set. | 646 | /* Upon stop, the APM issues an interrupt if HW RF kill is set. |
674 | * Clean again the interrupt here | 647 | * Clean again the interrupt here |
675 | */ | 648 | */ |
676 | spin_lock_irqsave(&trans_pcie->irq_lock, flags); | 649 | spin_lock(&trans_pcie->irq_lock); |
677 | iwl_disable_interrupts(trans); | 650 | iwl_disable_interrupts(trans); |
678 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); | 651 | spin_unlock(&trans_pcie->irq_lock); |
679 | 652 | ||
680 | /* stop and reset the on-board processor */ | 653 | /* stop and reset the on-board processor */ |
681 | iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); | 654 | iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); |
@@ -698,13 +671,20 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) | |||
698 | * all the interrupts were disabled, in this case we couldn't | 671 | * all the interrupts were disabled, in this case we couldn't |
699 | * receive the RF kill interrupt and update the state in the | 672 | * receive the RF kill interrupt and update the state in the |
700 | * op_mode. | 673 | * op_mode. |
674 | * Don't call the op_mode if the rkfill state hasn't changed. | ||
675 | * This allows the op_mode to call stop_device from the rfkill | ||
676 | * notification without endless recursion. Under very rare | ||
677 | * circumstances, we might have a small recursion if the rfkill | ||
678 | * state changed exactly now while we were called from stop_device. | ||
679 | * This is very unlikely but can happen and is supported. | ||
701 | */ | 680 | */ |
702 | hw_rfkill = iwl_is_rfkill_set(trans); | 681 | hw_rfkill = iwl_is_rfkill_set(trans); |
703 | if (hw_rfkill) | 682 | if (hw_rfkill) |
704 | set_bit(STATUS_RFKILL, &trans->status); | 683 | set_bit(STATUS_RFKILL, &trans->status); |
705 | else | 684 | else |
706 | clear_bit(STATUS_RFKILL, &trans->status); | 685 | clear_bit(STATUS_RFKILL, &trans->status); |
707 | iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); | 686 | if (hw_rfkill != was_hw_rfkill) |
687 | iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); | ||
708 | } | 688 | } |
709 | 689 | ||
710 | static void iwl_trans_pcie_d3_suspend(struct iwl_trans *trans, bool test) | 690 | static void iwl_trans_pcie_d3_suspend(struct iwl_trans *trans, bool test) |
@@ -799,7 +779,7 @@ static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) | |||
799 | } | 779 | } |
800 | 780 | ||
801 | /* Reset the entire device */ | 781 | /* Reset the entire device */ |
802 | iwl_set_bit(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); | 782 | iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); |
803 | 783 | ||
804 | usleep_range(10, 15); | 784 | usleep_range(10, 15); |
805 | 785 | ||
@@ -821,18 +801,17 @@ static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) | |||
821 | static void iwl_trans_pcie_op_mode_leave(struct iwl_trans *trans) | 801 | static void iwl_trans_pcie_op_mode_leave(struct iwl_trans *trans) |
822 | { | 802 | { |
823 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 803 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
824 | unsigned long flags; | ||
825 | 804 | ||
826 | /* disable interrupts - don't enable HW RF kill interrupt */ | 805 | /* disable interrupts - don't enable HW RF kill interrupt */ |
827 | spin_lock_irqsave(&trans_pcie->irq_lock, flags); | 806 | spin_lock(&trans_pcie->irq_lock); |
828 | iwl_disable_interrupts(trans); | 807 | iwl_disable_interrupts(trans); |
829 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); | 808 | spin_unlock(&trans_pcie->irq_lock); |
830 | 809 | ||
831 | iwl_pcie_apm_stop(trans); | 810 | iwl_pcie_apm_stop(trans); |
832 | 811 | ||
833 | spin_lock_irqsave(&trans_pcie->irq_lock, flags); | 812 | spin_lock(&trans_pcie->irq_lock); |
834 | iwl_disable_interrupts(trans); | 813 | iwl_disable_interrupts(trans); |
835 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); | 814 | spin_unlock(&trans_pcie->irq_lock); |
836 | 815 | ||
837 | iwl_pcie_disable_ict(trans); | 816 | iwl_pcie_disable_ict(trans); |
838 | } | 817 | } |
@@ -932,6 +911,9 @@ static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans, bool silent, | |||
932 | 911 | ||
933 | spin_lock_irqsave(&trans_pcie->reg_lock, *flags); | 912 | spin_lock_irqsave(&trans_pcie->reg_lock, *flags); |
934 | 913 | ||
914 | if (trans_pcie->cmd_in_flight) | ||
915 | goto out; | ||
916 | |||
935 | /* this bit wakes up the NIC */ | 917 | /* this bit wakes up the NIC */ |
936 | __iwl_trans_pcie_set_bit(trans, CSR_GP_CNTRL, | 918 | __iwl_trans_pcie_set_bit(trans, CSR_GP_CNTRL, |
937 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | 919 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); |
@@ -971,6 +953,7 @@ static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans, bool silent, | |||
971 | } | 953 | } |
972 | } | 954 | } |
973 | 955 | ||
956 | out: | ||
974 | /* | 957 | /* |
975 | * Fool sparse by faking we release the lock - sparse will | 958 | * Fool sparse by faking we release the lock - sparse will |
976 | * track nic_access anyway. | 959 | * track nic_access anyway. |
@@ -992,6 +975,9 @@ static void iwl_trans_pcie_release_nic_access(struct iwl_trans *trans, | |||
992 | */ | 975 | */ |
993 | __acquire(&trans_pcie->reg_lock); | 976 | __acquire(&trans_pcie->reg_lock); |
994 | 977 | ||
978 | if (trans_pcie->cmd_in_flight) | ||
979 | goto out; | ||
980 | |||
995 | __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL, | 981 | __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL, |
996 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | 982 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); |
997 | /* | 983 | /* |
@@ -1001,6 +987,7 @@ static void iwl_trans_pcie_release_nic_access(struct iwl_trans *trans, | |||
1001 | * scheduled on different CPUs (after we drop reg_lock). | 987 | * scheduled on different CPUs (after we drop reg_lock). |
1002 | */ | 988 | */ |
1003 | mmiowb(); | 989 | mmiowb(); |
990 | out: | ||
1004 | spin_unlock_irqrestore(&trans_pcie->reg_lock, *flags); | 991 | spin_unlock_irqrestore(&trans_pcie->reg_lock, *flags); |
1005 | } | 992 | } |
1006 | 993 | ||
@@ -1597,7 +1584,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, | |||
1597 | if (iwl_pcie_alloc_ict(trans)) | 1584 | if (iwl_pcie_alloc_ict(trans)) |
1598 | goto out_free_cmd_pool; | 1585 | goto out_free_cmd_pool; |
1599 | 1586 | ||
1600 | err = request_threaded_irq(pdev->irq, iwl_pcie_isr_ict, | 1587 | err = request_threaded_irq(pdev->irq, iwl_pcie_isr, |
1601 | iwl_pcie_irq_handler, | 1588 | iwl_pcie_irq_handler, |
1602 | IRQF_SHARED, DRV_NAME, trans); | 1589 | IRQF_SHARED, DRV_NAME, trans); |
1603 | if (err) { | 1590 | if (err) { |
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c index 8df24787c141..3b14fa8abfc7 100644 --- a/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/iwlwifi/pcie/tx.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2003 - 2013 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * Portions of this file are derived from the ipw3945 project, as well | 5 | * Portions of this file are derived from the ipw3945 project, as well |
6 | * as portions of the ieee80211 subsystem header files. | 6 | * as portions of the ieee80211 subsystem header files. |
@@ -737,10 +737,9 @@ int iwl_pcie_tx_stop(struct iwl_trans *trans) | |||
737 | { | 737 | { |
738 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 738 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
739 | int ch, txq_id, ret; | 739 | int ch, txq_id, ret; |
740 | unsigned long flags; | ||
741 | 740 | ||
742 | /* Turn off all Tx DMA fifos */ | 741 | /* Turn off all Tx DMA fifos */ |
743 | spin_lock_irqsave(&trans_pcie->irq_lock, flags); | 742 | spin_lock(&trans_pcie->irq_lock); |
744 | 743 | ||
745 | iwl_pcie_txq_set_sched(trans, 0); | 744 | iwl_pcie_txq_set_sched(trans, 0); |
746 | 745 | ||
@@ -757,13 +756,19 @@ int iwl_pcie_tx_stop(struct iwl_trans *trans) | |||
757 | iwl_read_direct32(trans, | 756 | iwl_read_direct32(trans, |
758 | FH_TSSR_TX_STATUS_REG)); | 757 | FH_TSSR_TX_STATUS_REG)); |
759 | } | 758 | } |
760 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); | 759 | spin_unlock(&trans_pcie->irq_lock); |
761 | 760 | ||
762 | if (!trans_pcie->txq) { | 761 | /* |
763 | IWL_WARN(trans, | 762 | * This function can be called before the op_mode disabled the |
764 | "Stopping tx queues that aren't allocated...\n"); | 763 | * queues. This happens when we have an rfkill interrupt. |
764 | * Since we stop Tx altogether - mark the queues as stopped. | ||
765 | */ | ||
766 | memset(trans_pcie->queue_stopped, 0, sizeof(trans_pcie->queue_stopped)); | ||
767 | memset(trans_pcie->queue_used, 0, sizeof(trans_pcie->queue_used)); | ||
768 | |||
769 | /* This can happen: start_hw, stop_device */ | ||
770 | if (!trans_pcie->txq) | ||
765 | return 0; | 771 | return 0; |
766 | } | ||
767 | 772 | ||
768 | /* Unmap DMA from host system and free skb's */ | 773 | /* Unmap DMA from host system and free skb's */ |
769 | for (txq_id = 0; txq_id < trans->cfg->base_params->num_of_queues; | 774 | for (txq_id = 0; txq_id < trans->cfg->base_params->num_of_queues; |
@@ -865,7 +870,6 @@ int iwl_pcie_tx_init(struct iwl_trans *trans) | |||
865 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 870 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
866 | int ret; | 871 | int ret; |
867 | int txq_id, slots_num; | 872 | int txq_id, slots_num; |
868 | unsigned long flags; | ||
869 | bool alloc = false; | 873 | bool alloc = false; |
870 | 874 | ||
871 | if (!trans_pcie->txq) { | 875 | if (!trans_pcie->txq) { |
@@ -875,7 +879,7 @@ int iwl_pcie_tx_init(struct iwl_trans *trans) | |||
875 | alloc = true; | 879 | alloc = true; |
876 | } | 880 | } |
877 | 881 | ||
878 | spin_lock_irqsave(&trans_pcie->irq_lock, flags); | 882 | spin_lock(&trans_pcie->irq_lock); |
879 | 883 | ||
880 | /* Turn off all Tx DMA fifos */ | 884 | /* Turn off all Tx DMA fifos */ |
881 | iwl_write_prph(trans, SCD_TXFACT, 0); | 885 | iwl_write_prph(trans, SCD_TXFACT, 0); |
@@ -884,7 +888,7 @@ int iwl_pcie_tx_init(struct iwl_trans *trans) | |||
884 | iwl_write_direct32(trans, FH_KW_MEM_ADDR_REG, | 888 | iwl_write_direct32(trans, FH_KW_MEM_ADDR_REG, |
885 | trans_pcie->kw.dma >> 4); | 889 | trans_pcie->kw.dma >> 4); |
886 | 890 | ||
887 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); | 891 | spin_unlock(&trans_pcie->irq_lock); |
888 | 892 | ||
889 | /* Alloc and init all Tx queues, including the command queue (#4/#9) */ | 893 | /* Alloc and init all Tx queues, including the command queue (#4/#9) */ |
890 | for (txq_id = 0; txq_id < trans->cfg->base_params->num_of_queues; | 894 | for (txq_id = 0; txq_id < trans->cfg->base_params->num_of_queues; |
@@ -1003,6 +1007,7 @@ static void iwl_pcie_cmdq_reclaim(struct iwl_trans *trans, int txq_id, int idx) | |||
1003 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 1007 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
1004 | struct iwl_txq *txq = &trans_pcie->txq[txq_id]; | 1008 | struct iwl_txq *txq = &trans_pcie->txq[txq_id]; |
1005 | struct iwl_queue *q = &txq->q; | 1009 | struct iwl_queue *q = &txq->q; |
1010 | unsigned long flags; | ||
1006 | int nfreed = 0; | 1011 | int nfreed = 0; |
1007 | 1012 | ||
1008 | lockdep_assert_held(&txq->lock); | 1013 | lockdep_assert_held(&txq->lock); |
@@ -1025,6 +1030,16 @@ static void iwl_pcie_cmdq_reclaim(struct iwl_trans *trans, int txq_id, int idx) | |||
1025 | } | 1030 | } |
1026 | } | 1031 | } |
1027 | 1032 | ||
1033 | if (q->read_ptr == q->write_ptr) { | ||
1034 | spin_lock_irqsave(&trans_pcie->reg_lock, flags); | ||
1035 | WARN_ON(!trans_pcie->cmd_in_flight); | ||
1036 | trans_pcie->cmd_in_flight = false; | ||
1037 | __iwl_trans_pcie_clear_bit(trans, | ||
1038 | CSR_GP_CNTRL, | ||
1039 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | ||
1040 | spin_unlock_irqrestore(&trans_pcie->reg_lock, flags); | ||
1041 | } | ||
1042 | |||
1028 | iwl_pcie_txq_progress(trans_pcie, txq); | 1043 | iwl_pcie_txq_progress(trans_pcie, txq); |
1029 | } | 1044 | } |
1030 | 1045 | ||
@@ -1141,8 +1156,15 @@ void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id) | |||
1141 | SCD_TX_STTS_QUEUE_OFFSET(txq_id); | 1156 | SCD_TX_STTS_QUEUE_OFFSET(txq_id); |
1142 | static const u32 zero_val[4] = {}; | 1157 | static const u32 zero_val[4] = {}; |
1143 | 1158 | ||
1159 | /* | ||
1160 | * Upon HW Rfkill - we stop the device, and then stop the queues | ||
1161 | * in the op_mode. Just for the sake of the simplicity of the op_mode, | ||
1162 | * allow the op_mode to call txq_disable after it already called | ||
1163 | * stop_device. | ||
1164 | */ | ||
1144 | if (!test_and_clear_bit(txq_id, trans_pcie->queue_used)) { | 1165 | if (!test_and_clear_bit(txq_id, trans_pcie->queue_used)) { |
1145 | WARN_ONCE(1, "queue %d not used", txq_id); | 1166 | WARN_ONCE(test_bit(STATUS_DEVICE_ENABLED, &trans->status), |
1167 | "queue %d not used", txq_id); | ||
1146 | return; | 1168 | return; |
1147 | } | 1169 | } |
1148 | 1170 | ||
@@ -1176,12 +1198,13 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, | |||
1176 | struct iwl_queue *q = &txq->q; | 1198 | struct iwl_queue *q = &txq->q; |
1177 | struct iwl_device_cmd *out_cmd; | 1199 | struct iwl_device_cmd *out_cmd; |
1178 | struct iwl_cmd_meta *out_meta; | 1200 | struct iwl_cmd_meta *out_meta; |
1201 | unsigned long flags; | ||
1179 | void *dup_buf = NULL; | 1202 | void *dup_buf = NULL; |
1180 | dma_addr_t phys_addr; | 1203 | dma_addr_t phys_addr; |
1181 | int idx; | 1204 | int idx; |
1182 | u16 copy_size, cmd_size, scratch_size; | 1205 | u16 copy_size, cmd_size, scratch_size; |
1183 | bool had_nocopy = false; | 1206 | bool had_nocopy = false; |
1184 | int i; | 1207 | int i, ret; |
1185 | u32 cmd_pos; | 1208 | u32 cmd_pos; |
1186 | const u8 *cmddata[IWL_MAX_CMD_TBS_PER_TFD]; | 1209 | const u8 *cmddata[IWL_MAX_CMD_TBS_PER_TFD]; |
1187 | u16 cmdlen[IWL_MAX_CMD_TBS_PER_TFD]; | 1210 | u16 cmdlen[IWL_MAX_CMD_TBS_PER_TFD]; |
@@ -1379,10 +1402,38 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, | |||
1379 | if (q->read_ptr == q->write_ptr && trans_pcie->wd_timeout) | 1402 | if (q->read_ptr == q->write_ptr && trans_pcie->wd_timeout) |
1380 | mod_timer(&txq->stuck_timer, jiffies + trans_pcie->wd_timeout); | 1403 | mod_timer(&txq->stuck_timer, jiffies + trans_pcie->wd_timeout); |
1381 | 1404 | ||
1405 | spin_lock_irqsave(&trans_pcie->reg_lock, flags); | ||
1406 | |||
1407 | /* | ||
1408 | * wake up the NIC to make sure that the firmware will see the host | ||
1409 | * command - we will let the NIC sleep once all the host commands | ||
1410 | * returned. | ||
1411 | */ | ||
1412 | if (!trans_pcie->cmd_in_flight) { | ||
1413 | trans_pcie->cmd_in_flight = true; | ||
1414 | __iwl_trans_pcie_set_bit(trans, CSR_GP_CNTRL, | ||
1415 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | ||
1416 | ret = iwl_poll_bit(trans, CSR_GP_CNTRL, | ||
1417 | CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN, | ||
1418 | (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY | | ||
1419 | CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), | ||
1420 | 15000); | ||
1421 | if (ret < 0) { | ||
1422 | __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL, | ||
1423 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | ||
1424 | spin_unlock_irqrestore(&trans_pcie->reg_lock, flags); | ||
1425 | trans_pcie->cmd_in_flight = false; | ||
1426 | idx = -EIO; | ||
1427 | goto out; | ||
1428 | } | ||
1429 | } | ||
1430 | |||
1382 | /* Increment and update queue's write index */ | 1431 | /* Increment and update queue's write index */ |
1383 | q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); | 1432 | q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); |
1384 | iwl_pcie_txq_inc_wr_ptr(trans, txq); | 1433 | iwl_pcie_txq_inc_wr_ptr(trans, txq); |
1385 | 1434 | ||
1435 | spin_unlock_irqrestore(&trans_pcie->reg_lock, flags); | ||
1436 | |||
1386 | out: | 1437 | out: |
1387 | spin_unlock_bh(&txq->lock); | 1438 | spin_unlock_bh(&txq->lock); |
1388 | free_dup_buf: | 1439 | free_dup_buf: |
@@ -1464,7 +1515,6 @@ void iwl_pcie_hcmd_complete(struct iwl_trans *trans, | |||
1464 | } | 1515 | } |
1465 | 1516 | ||
1466 | #define HOST_COMPLETE_TIMEOUT (2 * HZ) | 1517 | #define HOST_COMPLETE_TIMEOUT (2 * HZ) |
1467 | #define COMMAND_POKE_TIMEOUT (HZ / 10) | ||
1468 | 1518 | ||
1469 | static int iwl_pcie_send_hcmd_async(struct iwl_trans *trans, | 1519 | static int iwl_pcie_send_hcmd_async(struct iwl_trans *trans, |
1470 | struct iwl_host_cmd *cmd) | 1520 | struct iwl_host_cmd *cmd) |
@@ -1492,7 +1542,6 @@ static int iwl_pcie_send_hcmd_sync(struct iwl_trans *trans, | |||
1492 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 1542 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
1493 | int cmd_idx; | 1543 | int cmd_idx; |
1494 | int ret; | 1544 | int ret; |
1495 | int timeout = HOST_COMPLETE_TIMEOUT; | ||
1496 | 1545 | ||
1497 | IWL_DEBUG_INFO(trans, "Attempting to send sync command %s\n", | 1546 | IWL_DEBUG_INFO(trans, "Attempting to send sync command %s\n", |
1498 | get_cmd_string(trans_pcie, cmd->id)); | 1547 | get_cmd_string(trans_pcie, cmd->id)); |
@@ -1516,29 +1565,10 @@ static int iwl_pcie_send_hcmd_sync(struct iwl_trans *trans, | |||
1516 | return ret; | 1565 | return ret; |
1517 | } | 1566 | } |
1518 | 1567 | ||
1519 | while (timeout > 0) { | 1568 | ret = wait_event_timeout(trans_pcie->wait_command_queue, |
1520 | unsigned long flags; | 1569 | !test_bit(STATUS_SYNC_HCMD_ACTIVE, |
1521 | 1570 | &trans->status), | |
1522 | timeout -= COMMAND_POKE_TIMEOUT; | 1571 | HOST_COMPLETE_TIMEOUT); |
1523 | ret = wait_event_timeout(trans_pcie->wait_command_queue, | ||
1524 | !test_bit(STATUS_SYNC_HCMD_ACTIVE, | ||
1525 | &trans->status), | ||
1526 | COMMAND_POKE_TIMEOUT); | ||
1527 | if (ret) | ||
1528 | break; | ||
1529 | /* poke the device - it may have lost the command */ | ||
1530 | if (iwl_trans_grab_nic_access(trans, true, &flags)) { | ||
1531 | iwl_trans_release_nic_access(trans, &flags); | ||
1532 | IWL_DEBUG_INFO(trans, | ||
1533 | "Tried to wake NIC for command %s\n", | ||
1534 | get_cmd_string(trans_pcie, cmd->id)); | ||
1535 | } else { | ||
1536 | IWL_ERR(trans, "Failed to poke NIC for command %s\n", | ||
1537 | get_cmd_string(trans_pcie, cmd->id)); | ||
1538 | break; | ||
1539 | } | ||
1540 | } | ||
1541 | |||
1542 | if (!ret) { | 1572 | if (!ret) { |
1543 | struct iwl_txq *txq = &trans_pcie->txq[trans_pcie->cmd_queue]; | 1573 | struct iwl_txq *txq = &trans_pcie->txq[trans_pcie->cmd_queue]; |
1544 | struct iwl_queue *q = &txq->q; | 1574 | struct iwl_queue *q = &txq->q; |
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index b994679abce0..e7c81abf108e 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c | |||
@@ -563,14 +563,7 @@ static void mwifiex_reg_notifier(struct wiphy *wiphy, | |||
563 | memcpy(adapter->country_code, request->alpha2, | 563 | memcpy(adapter->country_code, request->alpha2, |
564 | sizeof(request->alpha2)); | 564 | sizeof(request->alpha2)); |
565 | mwifiex_send_domain_info_cmd_fw(wiphy); | 565 | mwifiex_send_domain_info_cmd_fw(wiphy); |
566 | 566 | mwifiex_dnld_txpwr_table(priv); | |
567 | if (adapter->dt_node) { | ||
568 | char txpwr[] = {"marvell,00_txpwrlimit"}; | ||
569 | |||
570 | memcpy(&txpwr[8], adapter->country_code, 2); | ||
571 | mwifiex_dnld_dt_cfgdata(priv, adapter->dt_node, | ||
572 | txpwr); | ||
573 | } | ||
574 | } | 567 | } |
575 | } | 568 | } |
576 | 569 | ||
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c index 6bf58aba51d2..2d6f5e1721cf 100644 --- a/drivers/net/wireless/mwifiex/main.c +++ b/drivers/net/wireless/mwifiex/main.c | |||
@@ -749,7 +749,7 @@ static struct net_device_stats *mwifiex_get_stats(struct net_device *dev) | |||
749 | static u16 | 749 | static u16 |
750 | mwifiex_netdev_select_wmm_queue(struct net_device *dev, struct sk_buff *skb) | 750 | mwifiex_netdev_select_wmm_queue(struct net_device *dev, struct sk_buff *skb) |
751 | { | 751 | { |
752 | skb->priority = cfg80211_classify8021d(skb); | 752 | skb->priority = cfg80211_classify8021d(skb, NULL); |
753 | return mwifiex_1d_to_wmm_queue[skb->priority]; | 753 | return mwifiex_1d_to_wmm_queue[skb->priority]; |
754 | } | 754 | } |
755 | 755 | ||
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index ab3416449bfd..d8ad554ce39f 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h | |||
@@ -1155,6 +1155,7 @@ void mwifiex_11h_process_join(struct mwifiex_private *priv, u8 **buffer, | |||
1155 | int mwifiex_11h_handle_event_chanswann(struct mwifiex_private *priv); | 1155 | int mwifiex_11h_handle_event_chanswann(struct mwifiex_private *priv); |
1156 | int mwifiex_dnld_dt_cfgdata(struct mwifiex_private *priv, | 1156 | int mwifiex_dnld_dt_cfgdata(struct mwifiex_private *priv, |
1157 | struct device_node *node, const char *prefix); | 1157 | struct device_node *node, const char *prefix); |
1158 | void mwifiex_dnld_txpwr_table(struct mwifiex_private *priv); | ||
1158 | 1159 | ||
1159 | extern const struct ethtool_ops mwifiex_ethtool_ops; | 1160 | extern const struct ethtool_ops mwifiex_ethtool_ops; |
1160 | 1161 | ||
diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c index 9c2404cd755f..9208a8816b80 100644 --- a/drivers/net/wireless/mwifiex/sta_cmd.c +++ b/drivers/net/wireless/mwifiex/sta_cmd.c | |||
@@ -1170,8 +1170,9 @@ int mwifiex_dnld_dt_cfgdata(struct mwifiex_private *priv, | |||
1170 | strncmp(prop->name, prefix, len)) | 1170 | strncmp(prop->name, prefix, len)) |
1171 | continue; | 1171 | continue; |
1172 | 1172 | ||
1173 | /* property header is 6 bytes */ | 1173 | /* property header is 6 bytes, data must fit in cmd buffer */ |
1174 | if (prop && prop->value && prop->length > 6) { | 1174 | if (prop && prop->value && prop->length > 6 && |
1175 | prop->length <= MWIFIEX_SIZE_OF_CMD_BUFFER - S_DS_GEN) { | ||
1175 | ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_CFG_DATA, | 1176 | ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_CFG_DATA, |
1176 | HostCmd_ACT_GEN_SET, 0, | 1177 | HostCmd_ACT_GEN_SET, 0, |
1177 | prop); | 1178 | prop); |
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c index 3edc92fad319..c5cb2ed19ec2 100644 --- a/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/mwifiex/sta_ioctl.c | |||
@@ -184,6 +184,16 @@ int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv, | |||
184 | return mwifiex_update_bss_desc_with_ie(priv->adapter, bss_desc); | 184 | return mwifiex_update_bss_desc_with_ie(priv->adapter, bss_desc); |
185 | } | 185 | } |
186 | 186 | ||
187 | void mwifiex_dnld_txpwr_table(struct mwifiex_private *priv) | ||
188 | { | ||
189 | if (priv->adapter->dt_node) { | ||
190 | char txpwr[] = {"marvell,00_txpwrlimit"}; | ||
191 | |||
192 | memcpy(&txpwr[8], priv->adapter->country_code, 2); | ||
193 | mwifiex_dnld_dt_cfgdata(priv, priv->adapter->dt_node, txpwr); | ||
194 | } | ||
195 | } | ||
196 | |||
187 | static int mwifiex_process_country_ie(struct mwifiex_private *priv, | 197 | static int mwifiex_process_country_ie(struct mwifiex_private *priv, |
188 | struct cfg80211_bss *bss) | 198 | struct cfg80211_bss *bss) |
189 | { | 199 | { |
@@ -234,12 +244,7 @@ static int mwifiex_process_country_ie(struct mwifiex_private *priv, | |||
234 | return -1; | 244 | return -1; |
235 | } | 245 | } |
236 | 246 | ||
237 | if (priv->adapter->dt_node) { | 247 | mwifiex_dnld_txpwr_table(priv); |
238 | char txpwr[] = {"marvell,00_txpwrlimit"}; | ||
239 | |||
240 | memcpy(&txpwr[8], priv->adapter->country_code, 2); | ||
241 | mwifiex_dnld_dt_cfgdata(priv, priv->adapter->dt_node, txpwr); | ||
242 | } | ||
243 | 248 | ||
244 | return 0; | 249 | return 0; |
245 | } | 250 | } |
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index b953ad621e0b..63dbde5c3713 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c | |||
@@ -9,7 +9,6 @@ | |||
9 | * warranty of any kind, whether express or implied. | 9 | * warranty of any kind, whether express or implied. |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/interrupt.h> | 12 | #include <linux/interrupt.h> |
14 | #include <linux/module.h> | 13 | #include <linux/module.h> |
15 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
@@ -1258,7 +1257,7 @@ mwl8k_capture_bssid(struct mwl8k_priv *priv, struct ieee80211_hdr *wh) | |||
1258 | { | 1257 | { |
1259 | return priv->capture_beacon && | 1258 | return priv->capture_beacon && |
1260 | ieee80211_is_beacon(wh->frame_control) && | 1259 | ieee80211_is_beacon(wh->frame_control) && |
1261 | ether_addr_equal(wh->addr3, priv->capture_bssid); | 1260 | ether_addr_equal_64bits(wh->addr3, priv->capture_bssid); |
1262 | } | 1261 | } |
1263 | 1262 | ||
1264 | static inline void mwl8k_save_beacon(struct ieee80211_hw *hw, | 1263 | static inline void mwl8k_save_beacon(struct ieee80211_hw *hw, |
diff --git a/drivers/net/wireless/orinoco/hermes.c b/drivers/net/wireless/orinoco/hermes.c index 75c15bc7b34c..43790fbea0e0 100644 --- a/drivers/net/wireless/orinoco/hermes.c +++ b/drivers/net/wireless/orinoco/hermes.c | |||
@@ -40,7 +40,6 @@ | |||
40 | 40 | ||
41 | #include <linux/module.h> | 41 | #include <linux/module.h> |
42 | #include <linux/kernel.h> | 42 | #include <linux/kernel.h> |
43 | #include <linux/init.h> | ||
44 | #include <linux/delay.h> | 43 | #include <linux/delay.h> |
45 | 44 | ||
46 | #include "hermes.h" | 45 | #include "hermes.h" |
diff --git a/drivers/net/wireless/orinoco/orinoco_cs.c b/drivers/net/wireless/orinoco/orinoco_cs.c index d21d95939316..c0a27377d9e2 100644 --- a/drivers/net/wireless/orinoco/orinoco_cs.c +++ b/drivers/net/wireless/orinoco/orinoco_cs.c | |||
@@ -15,7 +15,6 @@ | |||
15 | 15 | ||
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
18 | #include <linux/init.h> | ||
19 | #include <linux/delay.h> | 18 | #include <linux/delay.h> |
20 | #include <pcmcia/cistpl.h> | 19 | #include <pcmcia/cistpl.h> |
21 | #include <pcmcia/cisreg.h> | 20 | #include <pcmcia/cisreg.h> |
diff --git a/drivers/net/wireless/orinoco/orinoco_usb.c b/drivers/net/wireless/orinoco/orinoco_usb.c index bdfe637953f4..f9805c9353d2 100644 --- a/drivers/net/wireless/orinoco/orinoco_usb.c +++ b/drivers/net/wireless/orinoco/orinoco_usb.c | |||
@@ -52,7 +52,6 @@ | |||
52 | #include <linux/signal.h> | 52 | #include <linux/signal.h> |
53 | #include <linux/errno.h> | 53 | #include <linux/errno.h> |
54 | #include <linux/poll.h> | 54 | #include <linux/poll.h> |
55 | #include <linux/init.h> | ||
56 | #include <linux/slab.h> | 55 | #include <linux/slab.h> |
57 | #include <linux/fcntl.h> | 56 | #include <linux/fcntl.h> |
58 | #include <linux/spinlock.h> | 57 | #include <linux/spinlock.h> |
diff --git a/drivers/net/wireless/orinoco/spectrum_cs.c b/drivers/net/wireless/orinoco/spectrum_cs.c index e2264bc12ebf..b60048c95e0a 100644 --- a/drivers/net/wireless/orinoco/spectrum_cs.c +++ b/drivers/net/wireless/orinoco/spectrum_cs.c | |||
@@ -23,7 +23,6 @@ | |||
23 | 23 | ||
24 | #include <linux/module.h> | 24 | #include <linux/module.h> |
25 | #include <linux/kernel.h> | 25 | #include <linux/kernel.h> |
26 | #include <linux/init.h> | ||
27 | #include <linux/delay.h> | 26 | #include <linux/delay.h> |
28 | #include <pcmcia/cistpl.h> | 27 | #include <pcmcia/cistpl.h> |
29 | #include <pcmcia/cisreg.h> | 28 | #include <pcmcia/cisreg.h> |
diff --git a/drivers/net/wireless/p54/eeprom.c b/drivers/net/wireless/p54/eeprom.c index d43e3740e45d..0fe67d2da208 100644 --- a/drivers/net/wireless/p54/eeprom.c +++ b/drivers/net/wireless/p54/eeprom.c | |||
@@ -16,7 +16,6 @@ | |||
16 | * published by the Free Software Foundation. | 16 | * published by the Free Software Foundation. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/firmware.h> | 19 | #include <linux/firmware.h> |
21 | #include <linux/etherdevice.h> | 20 | #include <linux/etherdevice.h> |
22 | #include <linux/sort.h> | 21 | #include <linux/sort.h> |
diff --git a/drivers/net/wireless/p54/fwio.c b/drivers/net/wireless/p54/fwio.c index b3879fbf5368..bc065e8e348b 100644 --- a/drivers/net/wireless/p54/fwio.c +++ b/drivers/net/wireless/p54/fwio.c | |||
@@ -16,7 +16,6 @@ | |||
16 | * published by the Free Software Foundation. | 16 | * published by the Free Software Foundation. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
21 | #include <linux/firmware.h> | 20 | #include <linux/firmware.h> |
22 | #include <linux/etherdevice.h> | 21 | #include <linux/etherdevice.h> |
diff --git a/drivers/net/wireless/p54/led.c b/drivers/net/wireless/p54/led.c index 3837e1eec5f4..1f6fd5ff5531 100644 --- a/drivers/net/wireless/p54/led.c +++ b/drivers/net/wireless/p54/led.c | |||
@@ -16,7 +16,6 @@ | |||
16 | * published by the Free Software Foundation. | 16 | * published by the Free Software Foundation. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/firmware.h> | 19 | #include <linux/firmware.h> |
21 | #include <linux/etherdevice.h> | 20 | #include <linux/etherdevice.h> |
22 | 21 | ||
diff --git a/drivers/net/wireless/p54/main.c b/drivers/net/wireless/p54/main.c index 067e6f2fd050..80d93cba5150 100644 --- a/drivers/net/wireless/p54/main.c +++ b/drivers/net/wireless/p54/main.c | |||
@@ -16,7 +16,6 @@ | |||
16 | * published by the Free Software Foundation. | 16 | * published by the Free Software Foundation. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
21 | #include <linux/firmware.h> | 20 | #include <linux/firmware.h> |
22 | #include <linux/etherdevice.h> | 21 | #include <linux/etherdevice.h> |
diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c index f9a07b0d83ac..d411de409050 100644 --- a/drivers/net/wireless/p54/p54pci.c +++ b/drivers/net/wireless/p54/p54pci.c | |||
@@ -13,7 +13,6 @@ | |||
13 | * published by the Free Software Foundation. | 13 | * published by the Free Software Foundation. |
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/pci.h> | 16 | #include <linux/pci.h> |
18 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
19 | #include <linux/firmware.h> | 18 | #include <linux/firmware.h> |
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index e328d3058c41..6e635cfa24c8 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c | |||
@@ -12,7 +12,6 @@ | |||
12 | * published by the Free Software Foundation. | 12 | * published by the Free Software Foundation. |
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/usb.h> | 15 | #include <linux/usb.h> |
17 | #include <linux/pci.h> | 16 | #include <linux/pci.h> |
18 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
diff --git a/drivers/net/wireless/p54/txrx.c b/drivers/net/wireless/p54/txrx.c index f95de0d16216..9c96831c0b5c 100644 --- a/drivers/net/wireless/p54/txrx.c +++ b/drivers/net/wireless/p54/txrx.c | |||
@@ -17,7 +17,6 @@ | |||
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/export.h> | 19 | #include <linux/export.h> |
20 | #include <linux/init.h> | ||
21 | #include <linux/firmware.h> | 20 | #include <linux/firmware.h> |
22 | #include <linux/etherdevice.h> | 21 | #include <linux/etherdevice.h> |
23 | #include <asm/div64.h> | 22 | #include <asm/div64.h> |
@@ -308,7 +307,7 @@ static void p54_pspoll_workaround(struct p54_common *priv, struct sk_buff *skb) | |||
308 | return; | 307 | return; |
309 | 308 | ||
310 | /* only consider beacons from the associated BSSID */ | 309 | /* only consider beacons from the associated BSSID */ |
311 | if (!ether_addr_equal(hdr->addr3, priv->bssid)) | 310 | if (!ether_addr_equal_64bits(hdr->addr3, priv->bssid)) |
312 | return; | 311 | return; |
313 | 312 | ||
314 | tim = p54_find_ie(skb, WLAN_EID_TIM); | 313 | tim = p54_find_ie(skb, WLAN_EID_TIM); |
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index c3cdda1252de..5028557aa18a 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c | |||
@@ -26,7 +26,6 @@ | |||
26 | // #define VERBOSE // more; success messages | 26 | // #define VERBOSE // more; success messages |
27 | 27 | ||
28 | #include <linux/module.h> | 28 | #include <linux/module.h> |
29 | #include <linux/init.h> | ||
30 | #include <linux/netdevice.h> | 29 | #include <linux/netdevice.h> |
31 | #include <linux/etherdevice.h> | 30 | #include <linux/etherdevice.h> |
32 | #include <linux/ethtool.h> | 31 | #include <linux/ethtool.h> |
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index 4ad0de9d1d08..4ccfef5094e0 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c | |||
@@ -24,7 +24,6 @@ | |||
24 | 24 | ||
25 | #include <linux/delay.h> | 25 | #include <linux/delay.h> |
26 | #include <linux/etherdevice.h> | 26 | #include <linux/etherdevice.h> |
27 | #include <linux/init.h> | ||
28 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
29 | #include <linux/module.h> | 28 | #include <linux/module.h> |
30 | #include <linux/pci.h> | 29 | #include <linux/pci.h> |
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 4f61ffbcd2f1..abc5f56f29fe 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c | |||
@@ -24,7 +24,6 @@ | |||
24 | 24 | ||
25 | #include <linux/delay.h> | 25 | #include <linux/delay.h> |
26 | #include <linux/etherdevice.h> | 26 | #include <linux/etherdevice.h> |
27 | #include <linux/init.h> | ||
28 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
29 | #include <linux/module.h> | 28 | #include <linux/module.h> |
30 | #include <linux/pci.h> | 29 | #include <linux/pci.h> |
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 1bb76935da71..9f16824cd1bc 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c | |||
@@ -24,7 +24,6 @@ | |||
24 | 24 | ||
25 | #include <linux/delay.h> | 25 | #include <linux/delay.h> |
26 | #include <linux/etherdevice.h> | 26 | #include <linux/etherdevice.h> |
27 | #include <linux/init.h> | ||
28 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
29 | #include <linux/module.h> | 28 | #include <linux/module.h> |
30 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 49ff178a0b46..5c5c4906c6b6 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c | |||
@@ -29,7 +29,6 @@ | |||
29 | 29 | ||
30 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
31 | #include <linux/etherdevice.h> | 31 | #include <linux/etherdevice.h> |
32 | #include <linux/init.h> | ||
33 | #include <linux/kernel.h> | 32 | #include <linux/kernel.h> |
34 | #include <linux/module.h> | 33 | #include <linux/module.h> |
35 | #include <linux/usb.h> | 34 | #include <linux/usb.h> |
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 00c3fae6fa3c..2bde6729f5e6 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
@@ -565,10 +565,10 @@ static void rt2x00lib_rxdone_check_ba(struct rt2x00_dev *rt2x00dev, | |||
565 | 565 | ||
566 | #undef TID_CHECK | 566 | #undef TID_CHECK |
567 | 567 | ||
568 | if (!ether_addr_equal(ba->ra, entry->ta)) | 568 | if (!ether_addr_equal_64bits(ba->ra, entry->ta)) |
569 | continue; | 569 | continue; |
570 | 570 | ||
571 | if (!ether_addr_equal(ba->ta, entry->ra)) | 571 | if (!ether_addr_equal_64bits(ba->ta, entry->ra)) |
572 | continue; | 572 | continue; |
573 | 573 | ||
574 | /* Mark BAR since we received the according BA */ | 574 | /* Mark BAR since we received the according BA */ |
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index b76f6049ad9a..24402984ee57 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c | |||
@@ -25,7 +25,6 @@ | |||
25 | #include <linux/crc-itu-t.h> | 25 | #include <linux/crc-itu-t.h> |
26 | #include <linux/delay.h> | 26 | #include <linux/delay.h> |
27 | #include <linux/etherdevice.h> | 27 | #include <linux/etherdevice.h> |
28 | #include <linux/init.h> | ||
29 | #include <linux/kernel.h> | 28 | #include <linux/kernel.h> |
30 | #include <linux/module.h> | 29 | #include <linux/module.h> |
31 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index ade88d7e089c..a140170b1eb3 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c | |||
@@ -25,7 +25,6 @@ | |||
25 | #include <linux/crc-itu-t.h> | 25 | #include <linux/crc-itu-t.h> |
26 | #include <linux/delay.h> | 26 | #include <linux/delay.h> |
27 | #include <linux/etherdevice.h> | 27 | #include <linux/etherdevice.h> |
28 | #include <linux/init.h> | ||
29 | #include <linux/kernel.h> | 28 | #include <linux/kernel.h> |
30 | #include <linux/module.h> | 29 | #include <linux/module.h> |
31 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
diff --git a/drivers/net/wireless/rtl818x/rtl8180/dev.c b/drivers/net/wireless/rtl818x/rtl8180/dev.c index a91506b12a62..8ec17aad0e52 100644 --- a/drivers/net/wireless/rtl818x/rtl8180/dev.c +++ b/drivers/net/wireless/rtl818x/rtl8180/dev.c | |||
@@ -15,7 +15,6 @@ | |||
15 | * published by the Free Software Foundation. | 15 | * published by the Free Software Foundation. |
16 | */ | 16 | */ |
17 | 17 | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/interrupt.h> | 18 | #include <linux/interrupt.h> |
20 | #include <linux/pci.h> | 19 | #include <linux/pci.h> |
21 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
diff --git a/drivers/net/wireless/rtl818x/rtl8180/grf5101.c b/drivers/net/wireless/rtl818x/rtl8180/grf5101.c index dc845693f321..b1bfee738937 100644 --- a/drivers/net/wireless/rtl818x/rtl8180/grf5101.c +++ b/drivers/net/wireless/rtl818x/rtl8180/grf5101.c | |||
@@ -19,7 +19,6 @@ | |||
19 | * published by the Free Software Foundation. | 19 | * published by the Free Software Foundation. |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <linux/init.h> | ||
23 | #include <linux/pci.h> | 22 | #include <linux/pci.h> |
24 | #include <linux/delay.h> | 23 | #include <linux/delay.h> |
25 | #include <net/mac80211.h> | 24 | #include <net/mac80211.h> |
diff --git a/drivers/net/wireless/rtl818x/rtl8180/max2820.c b/drivers/net/wireless/rtl818x/rtl8180/max2820.c index a63c443c3c6f..eebf23976524 100644 --- a/drivers/net/wireless/rtl818x/rtl8180/max2820.c +++ b/drivers/net/wireless/rtl818x/rtl8180/max2820.c | |||
@@ -18,7 +18,6 @@ | |||
18 | * published by the Free Software Foundation. | 18 | * published by the Free Software Foundation. |
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include <linux/init.h> | ||
22 | #include <linux/pci.h> | 21 | #include <linux/pci.h> |
23 | #include <linux/delay.h> | 22 | #include <linux/delay.h> |
24 | #include <net/mac80211.h> | 23 | #include <net/mac80211.h> |
diff --git a/drivers/net/wireless/rtl818x/rtl8180/rtl8225.c b/drivers/net/wireless/rtl818x/rtl8180/rtl8225.c index ee638d0749d6..d60a5f399022 100644 --- a/drivers/net/wireless/rtl818x/rtl8180/rtl8225.c +++ b/drivers/net/wireless/rtl818x/rtl8180/rtl8225.c | |||
@@ -15,7 +15,6 @@ | |||
15 | * published by the Free Software Foundation. | 15 | * published by the Free Software Foundation. |
16 | */ | 16 | */ |
17 | 17 | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/pci.h> | 18 | #include <linux/pci.h> |
20 | #include <linux/delay.h> | 19 | #include <linux/delay.h> |
21 | #include <net/mac80211.h> | 20 | #include <net/mac80211.h> |
diff --git a/drivers/net/wireless/rtl818x/rtl8180/sa2400.c b/drivers/net/wireless/rtl818x/rtl8180/sa2400.c index 7614d9ccc729..959b049827de 100644 --- a/drivers/net/wireless/rtl818x/rtl8180/sa2400.c +++ b/drivers/net/wireless/rtl818x/rtl8180/sa2400.c | |||
@@ -19,7 +19,6 @@ | |||
19 | * published by the Free Software Foundation. | 19 | * published by the Free Software Foundation. |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <linux/init.h> | ||
23 | #include <linux/pci.h> | 22 | #include <linux/pci.h> |
24 | #include <linux/delay.h> | 23 | #include <linux/delay.h> |
25 | #include <net/mac80211.h> | 24 | #include <net/mac80211.h> |
diff --git a/drivers/net/wireless/rtl818x/rtl8187/dev.c b/drivers/net/wireless/rtl818x/rtl8187/dev.c index ec9aa5b67381..fd78df813a85 100644 --- a/drivers/net/wireless/rtl818x/rtl8187/dev.c +++ b/drivers/net/wireless/rtl818x/rtl8187/dev.c | |||
@@ -20,7 +20,6 @@ | |||
20 | * published by the Free Software Foundation. | 20 | * published by the Free Software Foundation. |
21 | */ | 21 | */ |
22 | 22 | ||
23 | #include <linux/init.h> | ||
24 | #include <linux/usb.h> | 23 | #include <linux/usb.h> |
25 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
26 | #include <linux/delay.h> | 25 | #include <linux/delay.h> |
diff --git a/drivers/net/wireless/rtl818x/rtl8187/rtl8225.c b/drivers/net/wireless/rtl818x/rtl8187/rtl8225.c index a26193a04447..5ecf18ed67b8 100644 --- a/drivers/net/wireless/rtl818x/rtl8187/rtl8225.c +++ b/drivers/net/wireless/rtl818x/rtl8187/rtl8225.c | |||
@@ -16,7 +16,6 @@ | |||
16 | * published by the Free Software Foundation. | 16 | * published by the Free Software Foundation. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/usb.h> | 19 | #include <linux/usb.h> |
21 | #include <net/mac80211.h> | 20 | #include <net/mac80211.h> |
22 | 21 | ||
diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c index fcf9b621918c..d63a12cc5de8 100644 --- a/drivers/net/wireless/rtlwifi/base.c +++ b/drivers/net/wireless/rtlwifi/base.c | |||
@@ -1293,7 +1293,7 @@ void rtl_beacon_statistic(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1293 | return; | 1293 | return; |
1294 | 1294 | ||
1295 | /* and only beacons from the associated BSSID, please */ | 1295 | /* and only beacons from the associated BSSID, please */ |
1296 | if (!ether_addr_equal(hdr->addr3, rtlpriv->mac80211.bssid)) | 1296 | if (!ether_addr_equal_64bits(hdr->addr3, rtlpriv->mac80211.bssid)) |
1297 | return; | 1297 | return; |
1298 | 1298 | ||
1299 | rtlpriv->link_info.bcn_rx_inperiod++; | 1299 | rtlpriv->link_info.bcn_rx_inperiod++; |
@@ -1781,7 +1781,7 @@ void rtl_recognize_peer(struct ieee80211_hw *hw, u8 *data, unsigned int len) | |||
1781 | return; | 1781 | return; |
1782 | 1782 | ||
1783 | /* and only beacons from the associated BSSID, please */ | 1783 | /* and only beacons from the associated BSSID, please */ |
1784 | if (!ether_addr_equal(hdr->addr3, rtlpriv->mac80211.bssid)) | 1784 | if (!ether_addr_equal_64bits(hdr->addr3, rtlpriv->mac80211.bssid)) |
1785 | return; | 1785 | return; |
1786 | 1786 | ||
1787 | if (rtl_find_221_ie(hw, data, len)) | 1787 | if (rtl_find_221_ie(hw, data, len)) |
diff --git a/drivers/net/wireless/rtlwifi/ps.c b/drivers/net/wireless/rtlwifi/ps.c index 0d81f766fd0f..deedae3c5449 100644 --- a/drivers/net/wireless/rtlwifi/ps.c +++ b/drivers/net/wireless/rtlwifi/ps.c | |||
@@ -478,7 +478,7 @@ void rtl_swlps_beacon(struct ieee80211_hw *hw, void *data, unsigned int len) | |||
478 | return; | 478 | return; |
479 | 479 | ||
480 | /* and only beacons from the associated BSSID, please */ | 480 | /* and only beacons from the associated BSSID, please */ |
481 | if (!ether_addr_equal(hdr->addr3, rtlpriv->mac80211.bssid)) | 481 | if (!ether_addr_equal_64bits(hdr->addr3, rtlpriv->mac80211.bssid)) |
482 | return; | 482 | return; |
483 | 483 | ||
484 | rtlpriv->psc.last_beacon = jiffies; | 484 | rtlpriv->psc.last_beacon = jiffies; |
@@ -923,7 +923,7 @@ void rtl_p2p_info(struct ieee80211_hw *hw, void *data, unsigned int len) | |||
923 | return; | 923 | return; |
924 | 924 | ||
925 | /* and only beacons from the associated BSSID, please */ | 925 | /* and only beacons from the associated BSSID, please */ |
926 | if (!ether_addr_equal(hdr->addr3, rtlpriv->mac80211.bssid)) | 926 | if (!ether_addr_equal_64bits(hdr->addr3, rtlpriv->mac80211.bssid)) |
927 | return; | 927 | return; |
928 | 928 | ||
929 | /* check if this really is a beacon */ | 929 | /* check if this really is a beacon */ |
diff --git a/drivers/net/wireless/ti/wl1251/acx.c b/drivers/net/wireless/ti/wl1251/acx.c index 374268d5ac6a..5a4ec56c83d0 100644 --- a/drivers/net/wireless/ti/wl1251/acx.c +++ b/drivers/net/wireless/ti/wl1251/acx.c | |||
@@ -194,7 +194,7 @@ out: | |||
194 | return ret; | 194 | return ret; |
195 | } | 195 | } |
196 | 196 | ||
197 | int wl1251_acx_feature_cfg(struct wl1251 *wl) | 197 | int wl1251_acx_feature_cfg(struct wl1251 *wl, u32 data_flow_options) |
198 | { | 198 | { |
199 | struct acx_feature_config *feature; | 199 | struct acx_feature_config *feature; |
200 | int ret; | 200 | int ret; |
@@ -205,8 +205,8 @@ int wl1251_acx_feature_cfg(struct wl1251 *wl) | |||
205 | if (!feature) | 205 | if (!feature) |
206 | return -ENOMEM; | 206 | return -ENOMEM; |
207 | 207 | ||
208 | /* DF_ENCRYPTION_DISABLE and DF_SNIFF_MODE_ENABLE are disabled */ | 208 | /* DF_ENCRYPTION_DISABLE and DF_SNIFF_MODE_ENABLE can be set */ |
209 | feature->data_flow_options = 0; | 209 | feature->data_flow_options = data_flow_options; |
210 | feature->options = 0; | 210 | feature->options = 0; |
211 | 211 | ||
212 | ret = wl1251_cmd_configure(wl, ACX_FEATURE_CFG, | 212 | ret = wl1251_cmd_configure(wl, ACX_FEATURE_CFG, |
@@ -381,7 +381,8 @@ out: | |||
381 | return ret; | 381 | return ret; |
382 | } | 382 | } |
383 | 383 | ||
384 | int wl1251_acx_group_address_tbl(struct wl1251 *wl) | 384 | int wl1251_acx_group_address_tbl(struct wl1251 *wl, bool enable, |
385 | void *mc_list, u32 mc_list_len) | ||
385 | { | 386 | { |
386 | struct acx_dot11_grp_addr_tbl *acx; | 387 | struct acx_dot11_grp_addr_tbl *acx; |
387 | int ret; | 388 | int ret; |
@@ -393,9 +394,9 @@ int wl1251_acx_group_address_tbl(struct wl1251 *wl) | |||
393 | return -ENOMEM; | 394 | return -ENOMEM; |
394 | 395 | ||
395 | /* MAC filtering */ | 396 | /* MAC filtering */ |
396 | acx->enabled = 0; | 397 | acx->enabled = enable; |
397 | acx->num_groups = 0; | 398 | acx->num_groups = mc_list_len; |
398 | memset(acx->mac_table, 0, ADDRESS_GROUP_MAX_LEN); | 399 | memcpy(acx->mac_table, mc_list, mc_list_len * ETH_ALEN); |
399 | 400 | ||
400 | ret = wl1251_cmd_configure(wl, DOT11_GROUP_ADDRESS_TBL, | 401 | ret = wl1251_cmd_configure(wl, DOT11_GROUP_ADDRESS_TBL, |
401 | acx, sizeof(*acx)); | 402 | acx, sizeof(*acx)); |
@@ -846,12 +847,18 @@ int wl1251_acx_rate_policies(struct wl1251 *wl) | |||
846 | return -ENOMEM; | 847 | return -ENOMEM; |
847 | 848 | ||
848 | /* configure one default (one-size-fits-all) rate class */ | 849 | /* configure one default (one-size-fits-all) rate class */ |
849 | acx->rate_class_cnt = 1; | 850 | acx->rate_class_cnt = 2; |
850 | acx->rate_class[0].enabled_rates = ACX_RATE_MASK_UNSPECIFIED; | 851 | acx->rate_class[0].enabled_rates = ACX_RATE_MASK_UNSPECIFIED; |
851 | acx->rate_class[0].short_retry_limit = ACX_RATE_RETRY_LIMIT; | 852 | acx->rate_class[0].short_retry_limit = ACX_RATE_RETRY_LIMIT; |
852 | acx->rate_class[0].long_retry_limit = ACX_RATE_RETRY_LIMIT; | 853 | acx->rate_class[0].long_retry_limit = ACX_RATE_RETRY_LIMIT; |
853 | acx->rate_class[0].aflags = 0; | 854 | acx->rate_class[0].aflags = 0; |
854 | 855 | ||
856 | /* no-retry rate class */ | ||
857 | acx->rate_class[1].enabled_rates = ACX_RATE_MASK_UNSPECIFIED; | ||
858 | acx->rate_class[1].short_retry_limit = 0; | ||
859 | acx->rate_class[1].long_retry_limit = 0; | ||
860 | acx->rate_class[1].aflags = 0; | ||
861 | |||
855 | ret = wl1251_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx)); | 862 | ret = wl1251_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx)); |
856 | if (ret < 0) { | 863 | if (ret < 0) { |
857 | wl1251_warning("Setting of rate policies failed: %d", ret); | 864 | wl1251_warning("Setting of rate policies failed: %d", ret); |
@@ -960,6 +967,32 @@ out: | |||
960 | return ret; | 967 | return ret; |
961 | } | 968 | } |
962 | 969 | ||
970 | int wl1251_acx_arp_ip_filter(struct wl1251 *wl, bool enable, __be32 address) | ||
971 | { | ||
972 | struct wl1251_acx_arp_filter *acx; | ||
973 | int ret; | ||
974 | |||
975 | wl1251_debug(DEBUG_ACX, "acx arp ip filter, enable: %d", enable); | ||
976 | |||
977 | acx = kzalloc(sizeof(*acx), GFP_KERNEL); | ||
978 | if (!acx) | ||
979 | return -ENOMEM; | ||
980 | |||
981 | acx->version = ACX_IPV4_VERSION; | ||
982 | acx->enable = enable; | ||
983 | |||
984 | if (enable) | ||
985 | memcpy(acx->address, &address, ACX_IPV4_ADDR_SIZE); | ||
986 | |||
987 | ret = wl1251_cmd_configure(wl, ACX_ARP_IP_FILTER, | ||
988 | acx, sizeof(*acx)); | ||
989 | if (ret < 0) | ||
990 | wl1251_warning("failed to set arp ip filter: %d", ret); | ||
991 | |||
992 | kfree(acx); | ||
993 | return ret; | ||
994 | } | ||
995 | |||
963 | int wl1251_acx_ac_cfg(struct wl1251 *wl, u8 ac, u8 cw_min, u16 cw_max, | 996 | int wl1251_acx_ac_cfg(struct wl1251 *wl, u8 ac, u8 cw_min, u16 cw_max, |
964 | u8 aifs, u16 txop) | 997 | u8 aifs, u16 txop) |
965 | { | 998 | { |
diff --git a/drivers/net/wireless/ti/wl1251/acx.h b/drivers/net/wireless/ti/wl1251/acx.h index c2ba100f9b1a..2bdec38699f4 100644 --- a/drivers/net/wireless/ti/wl1251/acx.h +++ b/drivers/net/wireless/ti/wl1251/acx.h | |||
@@ -350,8 +350,8 @@ struct acx_slot { | |||
350 | } __packed; | 350 | } __packed; |
351 | 351 | ||
352 | 352 | ||
353 | #define ADDRESS_GROUP_MAX (8) | 353 | #define ACX_MC_ADDRESS_GROUP_MAX (8) |
354 | #define ADDRESS_GROUP_MAX_LEN (ETH_ALEN * ADDRESS_GROUP_MAX) | 354 | #define ACX_MC_ADDRESS_GROUP_MAX_LEN (ETH_ALEN * ACX_MC_ADDRESS_GROUP_MAX) |
355 | 355 | ||
356 | struct acx_dot11_grp_addr_tbl { | 356 | struct acx_dot11_grp_addr_tbl { |
357 | struct acx_header header; | 357 | struct acx_header header; |
@@ -359,7 +359,7 @@ struct acx_dot11_grp_addr_tbl { | |||
359 | u8 enabled; | 359 | u8 enabled; |
360 | u8 num_groups; | 360 | u8 num_groups; |
361 | u8 pad[2]; | 361 | u8 pad[2]; |
362 | u8 mac_table[ADDRESS_GROUP_MAX_LEN]; | 362 | u8 mac_table[ACX_MC_ADDRESS_GROUP_MAX_LEN]; |
363 | } __packed; | 363 | } __packed; |
364 | 364 | ||
365 | 365 | ||
@@ -1232,6 +1232,20 @@ struct wl1251_acx_bet_enable { | |||
1232 | u8 padding[2]; | 1232 | u8 padding[2]; |
1233 | } __packed; | 1233 | } __packed; |
1234 | 1234 | ||
1235 | #define ACX_IPV4_VERSION 4 | ||
1236 | #define ACX_IPV6_VERSION 6 | ||
1237 | #define ACX_IPV4_ADDR_SIZE 4 | ||
1238 | struct wl1251_acx_arp_filter { | ||
1239 | struct acx_header header; | ||
1240 | u8 version; /* The IP version: 4 - IPv4, 6 - IPv6.*/ | ||
1241 | u8 enable; /* 1 - ARP filtering is enabled, 0 - disabled */ | ||
1242 | u8 padding[2]; | ||
1243 | u8 address[16]; /* The IP address used to filter ARP packets. | ||
1244 | ARP packets that do not match this address are | ||
1245 | dropped. When the IP Version is 4, the last 12 | ||
1246 | bytes of the the address are ignored. */ | ||
1247 | } __attribute__((packed)); | ||
1248 | |||
1235 | struct wl1251_acx_ac_cfg { | 1249 | struct wl1251_acx_ac_cfg { |
1236 | struct acx_header header; | 1250 | struct acx_header header; |
1237 | 1251 | ||
@@ -1440,7 +1454,7 @@ int wl1251_acx_wake_up_conditions(struct wl1251 *wl, u8 wake_up_event, | |||
1440 | int wl1251_acx_sleep_auth(struct wl1251 *wl, u8 sleep_auth); | 1454 | int wl1251_acx_sleep_auth(struct wl1251 *wl, u8 sleep_auth); |
1441 | int wl1251_acx_fw_version(struct wl1251 *wl, char *buf, size_t len); | 1455 | int wl1251_acx_fw_version(struct wl1251 *wl, char *buf, size_t len); |
1442 | int wl1251_acx_tx_power(struct wl1251 *wl, int power); | 1456 | int wl1251_acx_tx_power(struct wl1251 *wl, int power); |
1443 | int wl1251_acx_feature_cfg(struct wl1251 *wl); | 1457 | int wl1251_acx_feature_cfg(struct wl1251 *wl, u32 data_flow_options); |
1444 | int wl1251_acx_mem_map(struct wl1251 *wl, | 1458 | int wl1251_acx_mem_map(struct wl1251 *wl, |
1445 | struct acx_header *mem_map, size_t len); | 1459 | struct acx_header *mem_map, size_t len); |
1446 | int wl1251_acx_data_path_params(struct wl1251 *wl, | 1460 | int wl1251_acx_data_path_params(struct wl1251 *wl, |
@@ -1449,7 +1463,8 @@ int wl1251_acx_rx_msdu_life_time(struct wl1251 *wl, u32 life_time); | |||
1449 | int wl1251_acx_rx_config(struct wl1251 *wl, u32 config, u32 filter); | 1463 | int wl1251_acx_rx_config(struct wl1251 *wl, u32 config, u32 filter); |
1450 | int wl1251_acx_pd_threshold(struct wl1251 *wl); | 1464 | int wl1251_acx_pd_threshold(struct wl1251 *wl); |
1451 | int wl1251_acx_slot(struct wl1251 *wl, enum acx_slot_type slot_time); | 1465 | int wl1251_acx_slot(struct wl1251 *wl, enum acx_slot_type slot_time); |
1452 | int wl1251_acx_group_address_tbl(struct wl1251 *wl); | 1466 | int wl1251_acx_group_address_tbl(struct wl1251 *wl, bool enable, |
1467 | void *mc_list, u32 mc_list_len); | ||
1453 | int wl1251_acx_service_period_timeout(struct wl1251 *wl); | 1468 | int wl1251_acx_service_period_timeout(struct wl1251 *wl); |
1454 | int wl1251_acx_rts_threshold(struct wl1251 *wl, u16 rts_threshold); | 1469 | int wl1251_acx_rts_threshold(struct wl1251 *wl, u16 rts_threshold); |
1455 | int wl1251_acx_beacon_filter_opt(struct wl1251 *wl, bool enable_filter); | 1470 | int wl1251_acx_beacon_filter_opt(struct wl1251 *wl, bool enable_filter); |
@@ -1473,6 +1488,7 @@ int wl1251_acx_mem_cfg(struct wl1251 *wl); | |||
1473 | int wl1251_acx_wr_tbtt_and_dtim(struct wl1251 *wl, u16 tbtt, u8 dtim); | 1488 | int wl1251_acx_wr_tbtt_and_dtim(struct wl1251 *wl, u16 tbtt, u8 dtim); |
1474 | int wl1251_acx_bet_enable(struct wl1251 *wl, enum wl1251_acx_bet_mode mode, | 1489 | int wl1251_acx_bet_enable(struct wl1251 *wl, enum wl1251_acx_bet_mode mode, |
1475 | u8 max_consecutive); | 1490 | u8 max_consecutive); |
1491 | int wl1251_acx_arp_ip_filter(struct wl1251 *wl, bool enable, __be32 address); | ||
1476 | int wl1251_acx_ac_cfg(struct wl1251 *wl, u8 ac, u8 cw_min, u16 cw_max, | 1492 | int wl1251_acx_ac_cfg(struct wl1251 *wl, u8 ac, u8 cw_min, u16 cw_max, |
1477 | u8 aifs, u16 txop); | 1493 | u8 aifs, u16 txop); |
1478 | int wl1251_acx_tid_cfg(struct wl1251 *wl, u8 queue, | 1494 | int wl1251_acx_tid_cfg(struct wl1251 *wl, u8 queue, |
diff --git a/drivers/net/wireless/ti/wl1251/boot.c b/drivers/net/wireless/ti/wl1251/boot.c index a2e5241382da..2000cd536077 100644 --- a/drivers/net/wireless/ti/wl1251/boot.c +++ b/drivers/net/wireless/ti/wl1251/boot.c | |||
@@ -299,7 +299,8 @@ int wl1251_boot_run_firmware(struct wl1251 *wl) | |||
299 | ROAMING_TRIGGER_LOW_RSSI_EVENT_ID | | 299 | ROAMING_TRIGGER_LOW_RSSI_EVENT_ID | |
300 | ROAMING_TRIGGER_REGAINED_RSSI_EVENT_ID | | 300 | ROAMING_TRIGGER_REGAINED_RSSI_EVENT_ID | |
301 | REGAINED_BSS_EVENT_ID | BT_PTA_SENSE_EVENT_ID | | 301 | REGAINED_BSS_EVENT_ID | BT_PTA_SENSE_EVENT_ID | |
302 | BT_PTA_PREDICTION_EVENT_ID | JOIN_EVENT_COMPLETE_ID; | 302 | BT_PTA_PREDICTION_EVENT_ID | JOIN_EVENT_COMPLETE_ID | |
303 | PS_REPORT_EVENT_ID; | ||
303 | 304 | ||
304 | ret = wl1251_event_unmask(wl); | 305 | ret = wl1251_event_unmask(wl); |
305 | if (ret < 0) { | 306 | if (ret < 0) { |
diff --git a/drivers/net/wireless/ti/wl1251/cmd.c b/drivers/net/wireless/ti/wl1251/cmd.c index 6822b845efc1..223649bcaa5a 100644 --- a/drivers/net/wireless/ti/wl1251/cmd.c +++ b/drivers/net/wireless/ti/wl1251/cmd.c | |||
@@ -3,6 +3,7 @@ | |||
3 | #include <linux/module.h> | 3 | #include <linux/module.h> |
4 | #include <linux/slab.h> | 4 | #include <linux/slab.h> |
5 | #include <linux/crc7.h> | 5 | #include <linux/crc7.h> |
6 | #include <linux/etherdevice.h> | ||
6 | 7 | ||
7 | #include "wl1251.h" | 8 | #include "wl1251.h" |
8 | #include "reg.h" | 9 | #include "reg.h" |
@@ -203,11 +204,11 @@ out: | |||
203 | return ret; | 204 | return ret; |
204 | } | 205 | } |
205 | 206 | ||
206 | int wl1251_cmd_data_path(struct wl1251 *wl, u8 channel, bool enable) | 207 | int wl1251_cmd_data_path_rx(struct wl1251 *wl, u8 channel, bool enable) |
207 | { | 208 | { |
208 | struct cmd_enabledisable_path *cmd; | 209 | struct cmd_enabledisable_path *cmd; |
209 | int ret; | 210 | int ret; |
210 | u16 cmd_rx, cmd_tx; | 211 | u16 cmd_rx; |
211 | 212 | ||
212 | wl1251_debug(DEBUG_CMD, "cmd data path"); | 213 | wl1251_debug(DEBUG_CMD, "cmd data path"); |
213 | 214 | ||
@@ -219,13 +220,10 @@ int wl1251_cmd_data_path(struct wl1251 *wl, u8 channel, bool enable) | |||
219 | 220 | ||
220 | cmd->channel = channel; | 221 | cmd->channel = channel; |
221 | 222 | ||
222 | if (enable) { | 223 | if (enable) |
223 | cmd_rx = CMD_ENABLE_RX; | 224 | cmd_rx = CMD_ENABLE_RX; |
224 | cmd_tx = CMD_ENABLE_TX; | 225 | else |
225 | } else { | ||
226 | cmd_rx = CMD_DISABLE_RX; | 226 | cmd_rx = CMD_DISABLE_RX; |
227 | cmd_tx = CMD_DISABLE_TX; | ||
228 | } | ||
229 | 227 | ||
230 | ret = wl1251_cmd_send(wl, cmd_rx, cmd, sizeof(*cmd)); | 228 | ret = wl1251_cmd_send(wl, cmd_rx, cmd, sizeof(*cmd)); |
231 | if (ret < 0) { | 229 | if (ret < 0) { |
@@ -237,17 +235,38 @@ int wl1251_cmd_data_path(struct wl1251 *wl, u8 channel, bool enable) | |||
237 | wl1251_debug(DEBUG_BOOT, "rx %s cmd channel %d", | 235 | wl1251_debug(DEBUG_BOOT, "rx %s cmd channel %d", |
238 | enable ? "start" : "stop", channel); | 236 | enable ? "start" : "stop", channel); |
239 | 237 | ||
238 | out: | ||
239 | kfree(cmd); | ||
240 | return ret; | ||
241 | } | ||
242 | |||
243 | int wl1251_cmd_data_path_tx(struct wl1251 *wl, u8 channel, bool enable) | ||
244 | { | ||
245 | struct cmd_enabledisable_path *cmd; | ||
246 | int ret; | ||
247 | u16 cmd_tx; | ||
248 | |||
249 | wl1251_debug(DEBUG_CMD, "cmd data path"); | ||
250 | |||
251 | cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); | ||
252 | if (!cmd) | ||
253 | return -ENOMEM; | ||
254 | |||
255 | cmd->channel = channel; | ||
256 | |||
257 | if (enable) | ||
258 | cmd_tx = CMD_ENABLE_TX; | ||
259 | else | ||
260 | cmd_tx = CMD_DISABLE_TX; | ||
261 | |||
240 | ret = wl1251_cmd_send(wl, cmd_tx, cmd, sizeof(*cmd)); | 262 | ret = wl1251_cmd_send(wl, cmd_tx, cmd, sizeof(*cmd)); |
241 | if (ret < 0) { | 263 | if (ret < 0) |
242 | wl1251_error("tx %s cmd for channel %d failed", | 264 | wl1251_error("tx %s cmd for channel %d failed", |
243 | enable ? "start" : "stop", channel); | 265 | enable ? "start" : "stop", channel); |
244 | goto out; | 266 | else |
245 | } | 267 | wl1251_debug(DEBUG_BOOT, "tx %s cmd channel %d", |
246 | 268 | enable ? "start" : "stop", channel); | |
247 | wl1251_debug(DEBUG_BOOT, "tx %s cmd channel %d", | ||
248 | enable ? "start" : "stop", channel); | ||
249 | 269 | ||
250 | out: | ||
251 | kfree(cmd); | 270 | kfree(cmd); |
252 | return ret; | 271 | return ret; |
253 | } | 272 | } |
@@ -410,7 +429,9 @@ int wl1251_cmd_scan(struct wl1251 *wl, u8 *ssid, size_t ssid_len, | |||
410 | struct wl1251_cmd_scan *cmd; | 429 | struct wl1251_cmd_scan *cmd; |
411 | int i, ret = 0; | 430 | int i, ret = 0; |
412 | 431 | ||
413 | wl1251_debug(DEBUG_CMD, "cmd scan"); | 432 | wl1251_debug(DEBUG_CMD, "cmd scan channels %d", n_channels); |
433 | |||
434 | WARN_ON(n_channels > SCAN_MAX_NUM_OF_CHANNELS); | ||
414 | 435 | ||
415 | cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); | 436 | cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); |
416 | if (!cmd) | 437 | if (!cmd) |
@@ -421,6 +442,13 @@ int wl1251_cmd_scan(struct wl1251 *wl, u8 *ssid, size_t ssid_len, | |||
421 | CFG_RX_MGMT_EN | | 442 | CFG_RX_MGMT_EN | |
422 | CFG_RX_BCN_EN); | 443 | CFG_RX_BCN_EN); |
423 | cmd->params.scan_options = 0; | 444 | cmd->params.scan_options = 0; |
445 | /* | ||
446 | * Use high priority scan when not associated to prevent fw issue | ||
447 | * causing never-ending scans (sometimes 20+ minutes). | ||
448 | * Note: This bug may be caused by the fw's DTIM handling. | ||
449 | */ | ||
450 | if (is_zero_ether_addr(wl->bssid)) | ||
451 | cmd->params.scan_options |= WL1251_SCAN_OPT_PRIORITY_HIGH; | ||
424 | cmd->params.num_channels = n_channels; | 452 | cmd->params.num_channels = n_channels; |
425 | cmd->params.num_probe_requests = n_probes; | 453 | cmd->params.num_probe_requests = n_probes; |
426 | cmd->params.tx_rate = cpu_to_le16(1 << 1); /* 2 Mbps */ | 454 | cmd->params.tx_rate = cpu_to_le16(1 << 1); /* 2 Mbps */ |
diff --git a/drivers/net/wireless/ti/wl1251/cmd.h b/drivers/net/wireless/ti/wl1251/cmd.h index ee4f2b391822..d824ff978311 100644 --- a/drivers/net/wireless/ti/wl1251/cmd.h +++ b/drivers/net/wireless/ti/wl1251/cmd.h | |||
@@ -35,7 +35,8 @@ int wl1251_cmd_interrogate(struct wl1251 *wl, u16 id, void *buf, size_t len); | |||
35 | int wl1251_cmd_configure(struct wl1251 *wl, u16 id, void *buf, size_t len); | 35 | int wl1251_cmd_configure(struct wl1251 *wl, u16 id, void *buf, size_t len); |
36 | int wl1251_cmd_vbm(struct wl1251 *wl, u8 identity, | 36 | int wl1251_cmd_vbm(struct wl1251 *wl, u8 identity, |
37 | void *bitmap, u16 bitmap_len, u8 bitmap_control); | 37 | void *bitmap, u16 bitmap_len, u8 bitmap_control); |
38 | int wl1251_cmd_data_path(struct wl1251 *wl, u8 channel, bool enable); | 38 | int wl1251_cmd_data_path_rx(struct wl1251 *wl, u8 channel, bool enable); |
39 | int wl1251_cmd_data_path_tx(struct wl1251 *wl, u8 channel, bool enable); | ||
39 | int wl1251_cmd_join(struct wl1251 *wl, u8 bss_type, u8 channel, | 40 | int wl1251_cmd_join(struct wl1251 *wl, u8 bss_type, u8 channel, |
40 | u16 beacon_interval, u8 dtim_interval); | 41 | u16 beacon_interval, u8 dtim_interval); |
41 | int wl1251_cmd_ps_mode(struct wl1251 *wl, u8 ps_mode); | 42 | int wl1251_cmd_ps_mode(struct wl1251 *wl, u8 ps_mode); |
@@ -167,6 +168,11 @@ struct cmd_read_write_memory { | |||
167 | #define CMDMBOX_HEADER_LEN 4 | 168 | #define CMDMBOX_HEADER_LEN 4 |
168 | #define CMDMBOX_INFO_ELEM_HEADER_LEN 4 | 169 | #define CMDMBOX_INFO_ELEM_HEADER_LEN 4 |
169 | 170 | ||
171 | #define WL1251_SCAN_OPT_PASSIVE 1 | ||
172 | #define WL1251_SCAN_OPT_5GHZ_BAND 2 | ||
173 | #define WL1251_SCAN_OPT_TRIGGERD_SCAN 4 | ||
174 | #define WL1251_SCAN_OPT_PRIORITY_HIGH 8 | ||
175 | |||
170 | #define WL1251_SCAN_MIN_DURATION 30000 | 176 | #define WL1251_SCAN_MIN_DURATION 30000 |
171 | #define WL1251_SCAN_MAX_DURATION 60000 | 177 | #define WL1251_SCAN_MAX_DURATION 60000 |
172 | 178 | ||
diff --git a/drivers/net/wireless/ti/wl1251/event.c b/drivers/net/wireless/ti/wl1251/event.c index 74ae8e1c2e33..db0105313745 100644 --- a/drivers/net/wireless/ti/wl1251/event.c +++ b/drivers/net/wireless/ti/wl1251/event.c | |||
@@ -46,6 +46,43 @@ static int wl1251_event_scan_complete(struct wl1251 *wl, | |||
46 | return ret; | 46 | return ret; |
47 | } | 47 | } |
48 | 48 | ||
49 | #define WL1251_PSM_ENTRY_RETRIES 3 | ||
50 | static int wl1251_event_ps_report(struct wl1251 *wl, | ||
51 | struct event_mailbox *mbox) | ||
52 | { | ||
53 | int ret = 0; | ||
54 | |||
55 | wl1251_debug(DEBUG_EVENT, "ps status: %x", mbox->ps_status); | ||
56 | |||
57 | switch (mbox->ps_status) { | ||
58 | case EVENT_ENTER_POWER_SAVE_FAIL: | ||
59 | wl1251_debug(DEBUG_PSM, "PSM entry failed"); | ||
60 | |||
61 | if (wl->station_mode != STATION_POWER_SAVE_MODE) { | ||
62 | /* remain in active mode */ | ||
63 | wl->psm_entry_retry = 0; | ||
64 | break; | ||
65 | } | ||
66 | |||
67 | if (wl->psm_entry_retry < WL1251_PSM_ENTRY_RETRIES) { | ||
68 | wl->psm_entry_retry++; | ||
69 | ret = wl1251_ps_set_mode(wl, STATION_POWER_SAVE_MODE); | ||
70 | } else { | ||
71 | wl1251_error("Power save entry failed, giving up"); | ||
72 | wl->psm_entry_retry = 0; | ||
73 | } | ||
74 | break; | ||
75 | case EVENT_ENTER_POWER_SAVE_SUCCESS: | ||
76 | case EVENT_EXIT_POWER_SAVE_FAIL: | ||
77 | case EVENT_EXIT_POWER_SAVE_SUCCESS: | ||
78 | default: | ||
79 | wl->psm_entry_retry = 0; | ||
80 | break; | ||
81 | } | ||
82 | |||
83 | return 0; | ||
84 | } | ||
85 | |||
49 | static void wl1251_event_mbox_dump(struct event_mailbox *mbox) | 86 | static void wl1251_event_mbox_dump(struct event_mailbox *mbox) |
50 | { | 87 | { |
51 | wl1251_debug(DEBUG_EVENT, "MBOX DUMP:"); | 88 | wl1251_debug(DEBUG_EVENT, "MBOX DUMP:"); |
@@ -80,7 +117,14 @@ static int wl1251_event_process(struct wl1251 *wl, struct event_mailbox *mbox) | |||
80 | } | 117 | } |
81 | } | 118 | } |
82 | 119 | ||
83 | if (vector & SYNCHRONIZATION_TIMEOUT_EVENT_ID) { | 120 | if (vector & PS_REPORT_EVENT_ID) { |
121 | wl1251_debug(DEBUG_EVENT, "PS_REPORT_EVENT"); | ||
122 | ret = wl1251_event_ps_report(wl, mbox); | ||
123 | if (ret < 0) | ||
124 | return ret; | ||
125 | } | ||
126 | |||
127 | if (wl->vif && vector & SYNCHRONIZATION_TIMEOUT_EVENT_ID) { | ||
84 | wl1251_debug(DEBUG_EVENT, "SYNCHRONIZATION_TIMEOUT_EVENT"); | 128 | wl1251_debug(DEBUG_EVENT, "SYNCHRONIZATION_TIMEOUT_EVENT"); |
85 | 129 | ||
86 | /* indicate to the stack, that beacons have been lost */ | 130 | /* indicate to the stack, that beacons have been lost */ |
diff --git a/drivers/net/wireless/ti/wl1251/event.h b/drivers/net/wireless/ti/wl1251/event.h index 30eb5d150bf7..88570a5cd042 100644 --- a/drivers/net/wireless/ti/wl1251/event.h +++ b/drivers/net/wireless/ti/wl1251/event.h | |||
@@ -112,6 +112,13 @@ struct event_mailbox { | |||
112 | u8 padding[19]; | 112 | u8 padding[19]; |
113 | } __packed; | 113 | } __packed; |
114 | 114 | ||
115 | enum { | ||
116 | EVENT_ENTER_POWER_SAVE_FAIL = 0, | ||
117 | EVENT_ENTER_POWER_SAVE_SUCCESS, | ||
118 | EVENT_EXIT_POWER_SAVE_FAIL, | ||
119 | EVENT_EXIT_POWER_SAVE_SUCCESS, | ||
120 | }; | ||
121 | |||
115 | int wl1251_event_unmask(struct wl1251 *wl); | 122 | int wl1251_event_unmask(struct wl1251 *wl); |
116 | void wl1251_event_mbox_config(struct wl1251 *wl); | 123 | void wl1251_event_mbox_config(struct wl1251 *wl); |
117 | int wl1251_event_handle(struct wl1251 *wl, u8 mbox); | 124 | int wl1251_event_handle(struct wl1251 *wl, u8 mbox); |
diff --git a/drivers/net/wireless/ti/wl1251/init.c b/drivers/net/wireless/ti/wl1251/init.c index 89b43d35473c..1d799bffaa9f 100644 --- a/drivers/net/wireless/ti/wl1251/init.c +++ b/drivers/net/wireless/ti/wl1251/init.c | |||
@@ -33,7 +33,7 @@ int wl1251_hw_init_hwenc_config(struct wl1251 *wl) | |||
33 | { | 33 | { |
34 | int ret; | 34 | int ret; |
35 | 35 | ||
36 | ret = wl1251_acx_feature_cfg(wl); | 36 | ret = wl1251_acx_feature_cfg(wl, 0); |
37 | if (ret < 0) { | 37 | if (ret < 0) { |
38 | wl1251_warning("couldn't set feature config"); | 38 | wl1251_warning("couldn't set feature config"); |
39 | return ret; | 39 | return ret; |
@@ -127,7 +127,7 @@ int wl1251_hw_init_phy_config(struct wl1251 *wl) | |||
127 | if (ret < 0) | 127 | if (ret < 0) |
128 | return ret; | 128 | return ret; |
129 | 129 | ||
130 | ret = wl1251_acx_group_address_tbl(wl); | 130 | ret = wl1251_acx_group_address_tbl(wl, true, NULL, 0); |
131 | if (ret < 0) | 131 | if (ret < 0) |
132 | return ret; | 132 | return ret; |
133 | 133 | ||
@@ -394,8 +394,13 @@ int wl1251_hw_init(struct wl1251 *wl) | |||
394 | if (ret < 0) | 394 | if (ret < 0) |
395 | goto out_free_data_path; | 395 | goto out_free_data_path; |
396 | 396 | ||
397 | /* Enable data path */ | 397 | /* Enable rx data path */ |
398 | ret = wl1251_cmd_data_path(wl, wl->channel, 1); | 398 | ret = wl1251_cmd_data_path_rx(wl, wl->channel, 1); |
399 | if (ret < 0) | ||
400 | goto out_free_data_path; | ||
401 | |||
402 | /* Enable tx data path */ | ||
403 | ret = wl1251_cmd_data_path_tx(wl, wl->channel, 1); | ||
399 | if (ret < 0) | 404 | if (ret < 0) |
400 | goto out_free_data_path; | 405 | goto out_free_data_path; |
401 | 406 | ||
diff --git a/drivers/net/wireless/ti/wl1251/main.c b/drivers/net/wireless/ti/wl1251/main.c index b8a360b43e76..119c148f7740 100644 --- a/drivers/net/wireless/ti/wl1251/main.c +++ b/drivers/net/wireless/ti/wl1251/main.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/etherdevice.h> | 28 | #include <linux/etherdevice.h> |
29 | #include <linux/vmalloc.h> | 29 | #include <linux/vmalloc.h> |
30 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
31 | #include <linux/netdevice.h> | ||
31 | 32 | ||
32 | #include "wl1251.h" | 33 | #include "wl1251.h" |
33 | #include "wl12xx_80211.h" | 34 | #include "wl12xx_80211.h" |
@@ -479,10 +480,13 @@ static void wl1251_op_stop(struct ieee80211_hw *hw) | |||
479 | wl->next_tx_complete = 0; | 480 | wl->next_tx_complete = 0; |
480 | wl->elp = false; | 481 | wl->elp = false; |
481 | wl->station_mode = STATION_ACTIVE_MODE; | 482 | wl->station_mode = STATION_ACTIVE_MODE; |
483 | wl->psm_entry_retry = 0; | ||
482 | wl->tx_queue_stopped = false; | 484 | wl->tx_queue_stopped = false; |
483 | wl->power_level = WL1251_DEFAULT_POWER_LEVEL; | 485 | wl->power_level = WL1251_DEFAULT_POWER_LEVEL; |
484 | wl->rssi_thold = 0; | 486 | wl->rssi_thold = 0; |
485 | wl->channel = WL1251_DEFAULT_CHANNEL; | 487 | wl->channel = WL1251_DEFAULT_CHANNEL; |
488 | wl->monitor_present = false; | ||
489 | wl->joined = false; | ||
486 | 490 | ||
487 | wl1251_debugfs_reset(wl); | 491 | wl1251_debugfs_reset(wl); |
488 | 492 | ||
@@ -542,6 +546,7 @@ static void wl1251_op_remove_interface(struct ieee80211_hw *hw, | |||
542 | mutex_lock(&wl->mutex); | 546 | mutex_lock(&wl->mutex); |
543 | wl1251_debug(DEBUG_MAC80211, "mac80211 remove interface"); | 547 | wl1251_debug(DEBUG_MAC80211, "mac80211 remove interface"); |
544 | wl->vif = NULL; | 548 | wl->vif = NULL; |
549 | memset(wl->bssid, 0, ETH_ALEN); | ||
545 | mutex_unlock(&wl->mutex); | 550 | mutex_unlock(&wl->mutex); |
546 | } | 551 | } |
547 | 552 | ||
@@ -566,6 +571,11 @@ static int wl1251_build_qos_null_data(struct wl1251 *wl) | |||
566 | sizeof(template)); | 571 | sizeof(template)); |
567 | } | 572 | } |
568 | 573 | ||
574 | static bool wl1251_can_do_pm(struct ieee80211_conf *conf, struct wl1251 *wl) | ||
575 | { | ||
576 | return (conf->flags & IEEE80211_CONF_PS) && !wl->monitor_present; | ||
577 | } | ||
578 | |||
569 | static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed) | 579 | static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed) |
570 | { | 580 | { |
571 | struct wl1251 *wl = hw->priv; | 581 | struct wl1251 *wl = hw->priv; |
@@ -575,8 +585,10 @@ static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed) | |||
575 | channel = ieee80211_frequency_to_channel( | 585 | channel = ieee80211_frequency_to_channel( |
576 | conf->chandef.chan->center_freq); | 586 | conf->chandef.chan->center_freq); |
577 | 587 | ||
578 | wl1251_debug(DEBUG_MAC80211, "mac80211 config ch %d psm %s power %d", | 588 | wl1251_debug(DEBUG_MAC80211, |
589 | "mac80211 config ch %d monitor %s psm %s power %d", | ||
579 | channel, | 590 | channel, |
591 | conf->flags & IEEE80211_CONF_MONITOR ? "on" : "off", | ||
580 | conf->flags & IEEE80211_CONF_PS ? "on" : "off", | 592 | conf->flags & IEEE80211_CONF_PS ? "on" : "off", |
581 | conf->power_level); | 593 | conf->power_level); |
582 | 594 | ||
@@ -586,16 +598,44 @@ static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed) | |||
586 | if (ret < 0) | 598 | if (ret < 0) |
587 | goto out; | 599 | goto out; |
588 | 600 | ||
601 | if (changed & IEEE80211_CONF_CHANGE_MONITOR) { | ||
602 | u32 mode; | ||
603 | |||
604 | if (conf->flags & IEEE80211_CONF_MONITOR) { | ||
605 | wl->monitor_present = true; | ||
606 | mode = DF_SNIFF_MODE_ENABLE | DF_ENCRYPTION_DISABLE; | ||
607 | } else { | ||
608 | wl->monitor_present = false; | ||
609 | mode = 0; | ||
610 | } | ||
611 | |||
612 | ret = wl1251_acx_feature_cfg(wl, mode); | ||
613 | if (ret < 0) | ||
614 | goto out_sleep; | ||
615 | } | ||
616 | |||
589 | if (channel != wl->channel) { | 617 | if (channel != wl->channel) { |
590 | wl->channel = channel; | 618 | wl->channel = channel; |
591 | 619 | ||
592 | ret = wl1251_join(wl, wl->bss_type, wl->channel, | 620 | /* |
593 | wl->beacon_int, wl->dtim_period); | 621 | * Use ENABLE_RX command for channel switching when no |
622 | * interface is present (monitor mode only). | ||
623 | * This leaves the tx path disabled in firmware, whereas | ||
624 | * the usual JOIN command seems to transmit some frames | ||
625 | * at firmware level. | ||
626 | */ | ||
627 | if (wl->vif == NULL) { | ||
628 | wl->joined = false; | ||
629 | ret = wl1251_cmd_data_path_rx(wl, wl->channel, 1); | ||
630 | } else { | ||
631 | ret = wl1251_join(wl, wl->bss_type, wl->channel, | ||
632 | wl->beacon_int, wl->dtim_period); | ||
633 | } | ||
594 | if (ret < 0) | 634 | if (ret < 0) |
595 | goto out_sleep; | 635 | goto out_sleep; |
596 | } | 636 | } |
597 | 637 | ||
598 | if (conf->flags & IEEE80211_CONF_PS && !wl->psm_requested) { | 638 | if (wl1251_can_do_pm(conf, wl) && !wl->psm_requested) { |
599 | wl1251_debug(DEBUG_PSM, "psm enabled"); | 639 | wl1251_debug(DEBUG_PSM, "psm enabled"); |
600 | 640 | ||
601 | wl->psm_requested = true; | 641 | wl->psm_requested = true; |
@@ -611,8 +651,7 @@ static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed) | |||
611 | ret = wl1251_ps_set_mode(wl, STATION_POWER_SAVE_MODE); | 651 | ret = wl1251_ps_set_mode(wl, STATION_POWER_SAVE_MODE); |
612 | if (ret < 0) | 652 | if (ret < 0) |
613 | goto out_sleep; | 653 | goto out_sleep; |
614 | } else if (!(conf->flags & IEEE80211_CONF_PS) && | 654 | } else if (!wl1251_can_do_pm(conf, wl) && wl->psm_requested) { |
615 | wl->psm_requested) { | ||
616 | wl1251_debug(DEBUG_PSM, "psm disabled"); | 655 | wl1251_debug(DEBUG_PSM, "psm disabled"); |
617 | 656 | ||
618 | wl->psm_requested = false; | 657 | wl->psm_requested = false; |
@@ -648,6 +687,16 @@ static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed) | |||
648 | wl->power_level = conf->power_level; | 687 | wl->power_level = conf->power_level; |
649 | } | 688 | } |
650 | 689 | ||
690 | /* | ||
691 | * Tell stack that connection is lost because hw encryption isn't | ||
692 | * supported in monitor mode. | ||
693 | * This requires temporary enabling of the hw connection monitor flag | ||
694 | */ | ||
695 | if ((changed & IEEE80211_CONF_CHANGE_MONITOR) && wl->vif) { | ||
696 | wl->hw->flags |= IEEE80211_HW_CONNECTION_MONITOR; | ||
697 | ieee80211_connection_loss(wl->vif); | ||
698 | } | ||
699 | |||
651 | out_sleep: | 700 | out_sleep: |
652 | wl1251_ps_elp_sleep(wl); | 701 | wl1251_ps_elp_sleep(wl); |
653 | 702 | ||
@@ -657,6 +706,44 @@ out: | |||
657 | return ret; | 706 | return ret; |
658 | } | 707 | } |
659 | 708 | ||
709 | struct wl1251_filter_params { | ||
710 | bool enabled; | ||
711 | int mc_list_length; | ||
712 | u8 mc_list[ACX_MC_ADDRESS_GROUP_MAX][ETH_ALEN]; | ||
713 | }; | ||
714 | |||
715 | static u64 wl1251_op_prepare_multicast(struct ieee80211_hw *hw, | ||
716 | struct netdev_hw_addr_list *mc_list) | ||
717 | { | ||
718 | struct wl1251_filter_params *fp; | ||
719 | struct netdev_hw_addr *ha; | ||
720 | struct wl1251 *wl = hw->priv; | ||
721 | |||
722 | if (unlikely(wl->state == WL1251_STATE_OFF)) | ||
723 | return 0; | ||
724 | |||
725 | fp = kzalloc(sizeof(*fp), GFP_ATOMIC); | ||
726 | if (!fp) { | ||
727 | wl1251_error("Out of memory setting filters."); | ||
728 | return 0; | ||
729 | } | ||
730 | |||
731 | /* update multicast filtering parameters */ | ||
732 | fp->mc_list_length = 0; | ||
733 | if (netdev_hw_addr_list_count(mc_list) > ACX_MC_ADDRESS_GROUP_MAX) { | ||
734 | fp->enabled = false; | ||
735 | } else { | ||
736 | fp->enabled = true; | ||
737 | netdev_hw_addr_list_for_each(ha, mc_list) { | ||
738 | memcpy(fp->mc_list[fp->mc_list_length], | ||
739 | ha->addr, ETH_ALEN); | ||
740 | fp->mc_list_length++; | ||
741 | } | ||
742 | } | ||
743 | |||
744 | return (u64)(unsigned long)fp; | ||
745 | } | ||
746 | |||
660 | #define WL1251_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \ | 747 | #define WL1251_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \ |
661 | FIF_ALLMULTI | \ | 748 | FIF_ALLMULTI | \ |
662 | FIF_FCSFAIL | \ | 749 | FIF_FCSFAIL | \ |
@@ -667,8 +754,9 @@ out: | |||
667 | 754 | ||
668 | static void wl1251_op_configure_filter(struct ieee80211_hw *hw, | 755 | static void wl1251_op_configure_filter(struct ieee80211_hw *hw, |
669 | unsigned int changed, | 756 | unsigned int changed, |
670 | unsigned int *total,u64 multicast) | 757 | unsigned int *total, u64 multicast) |
671 | { | 758 | { |
759 | struct wl1251_filter_params *fp = (void *)(unsigned long)multicast; | ||
672 | struct wl1251 *wl = hw->priv; | 760 | struct wl1251 *wl = hw->priv; |
673 | int ret; | 761 | int ret; |
674 | 762 | ||
@@ -677,9 +765,11 @@ static void wl1251_op_configure_filter(struct ieee80211_hw *hw, | |||
677 | *total &= WL1251_SUPPORTED_FILTERS; | 765 | *total &= WL1251_SUPPORTED_FILTERS; |
678 | changed &= WL1251_SUPPORTED_FILTERS; | 766 | changed &= WL1251_SUPPORTED_FILTERS; |
679 | 767 | ||
680 | if (changed == 0) | 768 | if (changed == 0) { |
681 | /* no filters which we support changed */ | 769 | /* no filters which we support changed */ |
770 | kfree(fp); | ||
682 | return; | 771 | return; |
772 | } | ||
683 | 773 | ||
684 | mutex_lock(&wl->mutex); | 774 | mutex_lock(&wl->mutex); |
685 | 775 | ||
@@ -716,6 +806,15 @@ static void wl1251_op_configure_filter(struct ieee80211_hw *hw, | |||
716 | if (ret < 0) | 806 | if (ret < 0) |
717 | goto out; | 807 | goto out; |
718 | 808 | ||
809 | if (*total & FIF_ALLMULTI || *total & FIF_PROMISC_IN_BSS) | ||
810 | ret = wl1251_acx_group_address_tbl(wl, false, NULL, 0); | ||
811 | else if (fp) | ||
812 | ret = wl1251_acx_group_address_tbl(wl, fp->enabled, | ||
813 | fp->mc_list, | ||
814 | fp->mc_list_length); | ||
815 | if (ret < 0) | ||
816 | goto out; | ||
817 | |||
719 | /* send filters to firmware */ | 818 | /* send filters to firmware */ |
720 | wl1251_acx_rx_config(wl, wl->rx_config, wl->rx_filter); | 819 | wl1251_acx_rx_config(wl, wl->rx_config, wl->rx_filter); |
721 | 820 | ||
@@ -723,6 +822,7 @@ static void wl1251_op_configure_filter(struct ieee80211_hw *hw, | |||
723 | 822 | ||
724 | out: | 823 | out: |
725 | mutex_unlock(&wl->mutex); | 824 | mutex_unlock(&wl->mutex); |
825 | kfree(fp); | ||
726 | } | 826 | } |
727 | 827 | ||
728 | /* HW encryption */ | 828 | /* HW encryption */ |
@@ -802,12 +902,12 @@ static int wl1251_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
802 | 902 | ||
803 | mutex_lock(&wl->mutex); | 903 | mutex_lock(&wl->mutex); |
804 | 904 | ||
805 | ret = wl1251_ps_elp_wakeup(wl); | ||
806 | if (ret < 0) | ||
807 | goto out_unlock; | ||
808 | |||
809 | switch (cmd) { | 905 | switch (cmd) { |
810 | case SET_KEY: | 906 | case SET_KEY: |
907 | if (wl->monitor_present) { | ||
908 | ret = -EOPNOTSUPP; | ||
909 | goto out_unlock; | ||
910 | } | ||
811 | wl_cmd->key_action = KEY_ADD_OR_REPLACE; | 911 | wl_cmd->key_action = KEY_ADD_OR_REPLACE; |
812 | break; | 912 | break; |
813 | case DISABLE_KEY: | 913 | case DISABLE_KEY: |
@@ -818,6 +918,10 @@ static int wl1251_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
818 | break; | 918 | break; |
819 | } | 919 | } |
820 | 920 | ||
921 | ret = wl1251_ps_elp_wakeup(wl); | ||
922 | if (ret < 0) | ||
923 | goto out_unlock; | ||
924 | |||
821 | ret = wl1251_set_key_type(wl, wl_cmd, cmd, key, addr); | 925 | ret = wl1251_set_key_type(wl, wl_cmd, cmd, key, addr); |
822 | if (ret < 0) { | 926 | if (ret < 0) { |
823 | wl1251_error("Set KEY type failed"); | 927 | wl1251_error("Set KEY type failed"); |
@@ -930,6 +1034,7 @@ static int wl1251_op_hw_scan(struct ieee80211_hw *hw, | |||
930 | ret = wl1251_cmd_scan(wl, ssid, ssid_len, req->channels, | 1034 | ret = wl1251_cmd_scan(wl, ssid, ssid_len, req->channels, |
931 | req->n_channels, WL1251_SCAN_NUM_PROBES); | 1035 | req->n_channels, WL1251_SCAN_NUM_PROBES); |
932 | if (ret < 0) { | 1036 | if (ret < 0) { |
1037 | wl1251_debug(DEBUG_SCAN, "scan failed %d", ret); | ||
933 | wl->scanning = false; | 1038 | wl->scanning = false; |
934 | goto out_idle; | 1039 | goto out_idle; |
935 | } | 1040 | } |
@@ -977,6 +1082,7 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw, | |||
977 | { | 1082 | { |
978 | struct wl1251 *wl = hw->priv; | 1083 | struct wl1251 *wl = hw->priv; |
979 | struct sk_buff *beacon, *skb; | 1084 | struct sk_buff *beacon, *skb; |
1085 | bool enable; | ||
980 | int ret; | 1086 | int ret; |
981 | 1087 | ||
982 | wl1251_debug(DEBUG_MAC80211, "mac80211 bss info changed"); | 1088 | wl1251_debug(DEBUG_MAC80211, "mac80211 bss info changed"); |
@@ -1023,6 +1129,9 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw, | |||
1023 | } | 1129 | } |
1024 | 1130 | ||
1025 | if (changed & BSS_CHANGED_ASSOC) { | 1131 | if (changed & BSS_CHANGED_ASSOC) { |
1132 | /* Disable temporary enabled hw connection monitor flag */ | ||
1133 | wl->hw->flags &= ~IEEE80211_HW_CONNECTION_MONITOR; | ||
1134 | |||
1026 | if (bss_conf->assoc) { | 1135 | if (bss_conf->assoc) { |
1027 | wl->beacon_int = bss_conf->beacon_int; | 1136 | wl->beacon_int = bss_conf->beacon_int; |
1028 | 1137 | ||
@@ -1075,6 +1184,17 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw, | |||
1075 | } | 1184 | } |
1076 | } | 1185 | } |
1077 | 1186 | ||
1187 | if (changed & BSS_CHANGED_ARP_FILTER) { | ||
1188 | __be32 addr = bss_conf->arp_addr_list[0]; | ||
1189 | WARN_ON(wl->bss_type != BSS_TYPE_STA_BSS); | ||
1190 | |||
1191 | enable = bss_conf->arp_addr_cnt == 1 && bss_conf->assoc; | ||
1192 | wl1251_acx_arp_ip_filter(wl, enable, addr); | ||
1193 | |||
1194 | if (ret < 0) | ||
1195 | goto out_sleep; | ||
1196 | } | ||
1197 | |||
1078 | if (changed & BSS_CHANGED_BEACON) { | 1198 | if (changed & BSS_CHANGED_BEACON) { |
1079 | beacon = ieee80211_beacon_get(hw, vif); | 1199 | beacon = ieee80211_beacon_get(hw, vif); |
1080 | if (!beacon) | 1200 | if (!beacon) |
@@ -1245,6 +1365,7 @@ static const struct ieee80211_ops wl1251_ops = { | |||
1245 | .add_interface = wl1251_op_add_interface, | 1365 | .add_interface = wl1251_op_add_interface, |
1246 | .remove_interface = wl1251_op_remove_interface, | 1366 | .remove_interface = wl1251_op_remove_interface, |
1247 | .config = wl1251_op_config, | 1367 | .config = wl1251_op_config, |
1368 | .prepare_multicast = wl1251_op_prepare_multicast, | ||
1248 | .configure_filter = wl1251_op_configure_filter, | 1369 | .configure_filter = wl1251_op_configure_filter, |
1249 | .tx = wl1251_op_tx, | 1370 | .tx = wl1251_op_tx, |
1250 | .set_key = wl1251_op_set_key, | 1371 | .set_key = wl1251_op_set_key, |
@@ -1401,7 +1522,10 @@ struct ieee80211_hw *wl1251_alloc_hw(void) | |||
1401 | 1522 | ||
1402 | INIT_DELAYED_WORK(&wl->elp_work, wl1251_elp_work); | 1523 | INIT_DELAYED_WORK(&wl->elp_work, wl1251_elp_work); |
1403 | wl->channel = WL1251_DEFAULT_CHANNEL; | 1524 | wl->channel = WL1251_DEFAULT_CHANNEL; |
1525 | wl->monitor_present = false; | ||
1526 | wl->joined = false; | ||
1404 | wl->scanning = false; | 1527 | wl->scanning = false; |
1528 | wl->bss_type = MAX_BSS_TYPE; | ||
1405 | wl->default_key = 0; | 1529 | wl->default_key = 0; |
1406 | wl->listen_int = 1; | 1530 | wl->listen_int = 1; |
1407 | wl->rx_counter = 0; | 1531 | wl->rx_counter = 0; |
@@ -1413,6 +1537,7 @@ struct ieee80211_hw *wl1251_alloc_hw(void) | |||
1413 | wl->elp = false; | 1537 | wl->elp = false; |
1414 | wl->station_mode = STATION_ACTIVE_MODE; | 1538 | wl->station_mode = STATION_ACTIVE_MODE; |
1415 | wl->psm_requested = false; | 1539 | wl->psm_requested = false; |
1540 | wl->psm_entry_retry = 0; | ||
1416 | wl->tx_queue_stopped = false; | 1541 | wl->tx_queue_stopped = false; |
1417 | wl->power_level = WL1251_DEFAULT_POWER_LEVEL; | 1542 | wl->power_level = WL1251_DEFAULT_POWER_LEVEL; |
1418 | wl->rssi_thold = 0; | 1543 | wl->rssi_thold = 0; |
@@ -1478,3 +1603,4 @@ MODULE_DESCRIPTION("TI wl1251 Wireles LAN Driver Core"); | |||
1478 | MODULE_LICENSE("GPL"); | 1603 | MODULE_LICENSE("GPL"); |
1479 | MODULE_AUTHOR("Kalle Valo <kvalo@adurom.com>"); | 1604 | MODULE_AUTHOR("Kalle Valo <kvalo@adurom.com>"); |
1480 | MODULE_FIRMWARE(WL1251_FW_NAME); | 1605 | MODULE_FIRMWARE(WL1251_FW_NAME); |
1606 | MODULE_FIRMWARE(WL1251_NVS_NAME); | ||
diff --git a/drivers/net/wireless/ti/wl1251/rx.c b/drivers/net/wireless/ti/wl1251/rx.c index 23289d49dd31..123c4bb50e0a 100644 --- a/drivers/net/wireless/ti/wl1251/rx.c +++ b/drivers/net/wireless/ti/wl1251/rx.c | |||
@@ -83,7 +83,7 @@ static void wl1251_rx_status(struct wl1251 *wl, | |||
83 | 83 | ||
84 | status->flag |= RX_FLAG_MACTIME_START; | 84 | status->flag |= RX_FLAG_MACTIME_START; |
85 | 85 | ||
86 | if (desc->flags & RX_DESC_ENCRYPTION_MASK) { | 86 | if (!wl->monitor_present && (desc->flags & RX_DESC_ENCRYPTION_MASK)) { |
87 | status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_MMIC_STRIPPED; | 87 | status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_MMIC_STRIPPED; |
88 | 88 | ||
89 | if (likely(!(desc->flags & RX_DESC_DECRYPT_FAIL))) | 89 | if (likely(!(desc->flags & RX_DESC_DECRYPT_FAIL))) |
diff --git a/drivers/net/wireless/ti/wl1251/tx.c b/drivers/net/wireless/ti/wl1251/tx.c index 28121c590a2b..81de83c6fcf6 100644 --- a/drivers/net/wireless/ti/wl1251/tx.c +++ b/drivers/net/wireless/ti/wl1251/tx.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include "tx.h" | 28 | #include "tx.h" |
29 | #include "ps.h" | 29 | #include "ps.h" |
30 | #include "io.h" | 30 | #include "io.h" |
31 | #include "event.h" | ||
31 | 32 | ||
32 | static bool wl1251_tx_double_buffer_busy(struct wl1251 *wl, u32 data_out_count) | 33 | static bool wl1251_tx_double_buffer_busy(struct wl1251 *wl, u32 data_out_count) |
33 | { | 34 | { |
@@ -89,8 +90,12 @@ static void wl1251_tx_control(struct tx_double_buffer_desc *tx_hdr, | |||
89 | /* 802.11 packets */ | 90 | /* 802.11 packets */ |
90 | tx_hdr->control.packet_type = 0; | 91 | tx_hdr->control.packet_type = 0; |
91 | 92 | ||
92 | if (control->flags & IEEE80211_TX_CTL_NO_ACK) | 93 | /* Also disable retry and ACK policy for injected packets */ |
94 | if ((control->flags & IEEE80211_TX_CTL_NO_ACK) || | ||
95 | (control->flags & IEEE80211_TX_CTL_INJECTED)) { | ||
96 | tx_hdr->control.rate_policy = 1; | ||
93 | tx_hdr->control.ack_policy = 1; | 97 | tx_hdr->control.ack_policy = 1; |
98 | } | ||
94 | 99 | ||
95 | tx_hdr->control.tx_complete = 1; | 100 | tx_hdr->control.tx_complete = 1; |
96 | 101 | ||
@@ -277,6 +282,26 @@ static void wl1251_tx_trigger(struct wl1251 *wl) | |||
277 | TX_STATUS_DATA_OUT_COUNT_MASK; | 282 | TX_STATUS_DATA_OUT_COUNT_MASK; |
278 | } | 283 | } |
279 | 284 | ||
285 | static void enable_tx_for_packet_injection(struct wl1251 *wl) | ||
286 | { | ||
287 | int ret; | ||
288 | |||
289 | ret = wl1251_cmd_join(wl, BSS_TYPE_STA_BSS, wl->channel, | ||
290 | wl->beacon_int, wl->dtim_period); | ||
291 | if (ret < 0) { | ||
292 | wl1251_warning("join failed"); | ||
293 | return; | ||
294 | } | ||
295 | |||
296 | ret = wl1251_event_wait(wl, JOIN_EVENT_COMPLETE_ID, 100); | ||
297 | if (ret < 0) { | ||
298 | wl1251_warning("join timeout"); | ||
299 | return; | ||
300 | } | ||
301 | |||
302 | wl->joined = true; | ||
303 | } | ||
304 | |||
280 | /* caller must hold wl->mutex */ | 305 | /* caller must hold wl->mutex */ |
281 | static int wl1251_tx_frame(struct wl1251 *wl, struct sk_buff *skb) | 306 | static int wl1251_tx_frame(struct wl1251 *wl, struct sk_buff *skb) |
282 | { | 307 | { |
@@ -287,6 +312,9 @@ static int wl1251_tx_frame(struct wl1251 *wl, struct sk_buff *skb) | |||
287 | info = IEEE80211_SKB_CB(skb); | 312 | info = IEEE80211_SKB_CB(skb); |
288 | 313 | ||
289 | if (info->control.hw_key) { | 314 | if (info->control.hw_key) { |
315 | if (unlikely(wl->monitor_present)) | ||
316 | return -EINVAL; | ||
317 | |||
290 | idx = info->control.hw_key->hw_key_idx; | 318 | idx = info->control.hw_key->hw_key_idx; |
291 | if (unlikely(wl->default_key != idx)) { | 319 | if (unlikely(wl->default_key != idx)) { |
292 | ret = wl1251_acx_default_key(wl, idx); | 320 | ret = wl1251_acx_default_key(wl, idx); |
@@ -295,6 +323,10 @@ static int wl1251_tx_frame(struct wl1251 *wl, struct sk_buff *skb) | |||
295 | } | 323 | } |
296 | } | 324 | } |
297 | 325 | ||
326 | /* Enable tx path in monitor mode for packet injection */ | ||
327 | if ((wl->vif == NULL) && !wl->joined) | ||
328 | enable_tx_for_packet_injection(wl); | ||
329 | |||
298 | ret = wl1251_tx_path_status(wl); | 330 | ret = wl1251_tx_path_status(wl); |
299 | if (ret < 0) | 331 | if (ret < 0) |
300 | return ret; | 332 | return ret; |
@@ -394,6 +426,7 @@ static void wl1251_tx_packet_cb(struct wl1251 *wl, | |||
394 | info = IEEE80211_SKB_CB(skb); | 426 | info = IEEE80211_SKB_CB(skb); |
395 | 427 | ||
396 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) && | 428 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) && |
429 | !(info->flags & IEEE80211_TX_CTL_INJECTED) && | ||
397 | (result->status == TX_SUCCESS)) | 430 | (result->status == TX_SUCCESS)) |
398 | info->flags |= IEEE80211_TX_STAT_ACK; | 431 | info->flags |= IEEE80211_TX_STAT_ACK; |
399 | 432 | ||
diff --git a/drivers/net/wireless/ti/wl1251/wl1251.h b/drivers/net/wireless/ti/wl1251/wl1251.h index 2c3bd1bff3f6..235617a7716d 100644 --- a/drivers/net/wireless/ti/wl1251/wl1251.h +++ b/drivers/net/wireless/ti/wl1251/wl1251.h | |||
@@ -93,6 +93,7 @@ enum { | |||
93 | } while (0) | 93 | } while (0) |
94 | 94 | ||
95 | #define WL1251_DEFAULT_RX_CONFIG (CFG_UNI_FILTER_EN | \ | 95 | #define WL1251_DEFAULT_RX_CONFIG (CFG_UNI_FILTER_EN | \ |
96 | CFG_MC_FILTER_EN | \ | ||
96 | CFG_BSSID_FILTER_EN) | 97 | CFG_BSSID_FILTER_EN) |
97 | 98 | ||
98 | #define WL1251_DEFAULT_RX_FILTER (CFG_RX_PRSP_EN | \ | 99 | #define WL1251_DEFAULT_RX_FILTER (CFG_RX_PRSP_EN | \ |
@@ -303,6 +304,8 @@ struct wl1251 { | |||
303 | u8 bss_type; | 304 | u8 bss_type; |
304 | u8 listen_int; | 305 | u8 listen_int; |
305 | int channel; | 306 | int channel; |
307 | bool monitor_present; | ||
308 | bool joined; | ||
306 | 309 | ||
307 | void *target_mem_map; | 310 | void *target_mem_map; |
308 | struct acx_data_path_params_resp *data_path; | 311 | struct acx_data_path_params_resp *data_path; |
@@ -368,6 +371,9 @@ struct wl1251 { | |||
368 | /* PSM mode requested */ | 371 | /* PSM mode requested */ |
369 | bool psm_requested; | 372 | bool psm_requested; |
370 | 373 | ||
374 | /* retry counter for PSM entries */ | ||
375 | u8 psm_entry_retry; | ||
376 | |||
371 | u16 beacon_int; | 377 | u16 beacon_int; |
372 | u8 dtim_period; | 378 | u8 dtim_period; |
373 | 379 | ||
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c index 1477d7f05905..d24d4a958c67 100644 --- a/drivers/net/wireless/wl3501_cs.c +++ b/drivers/net/wireless/wl3501_cs.c | |||
@@ -29,7 +29,6 @@ | |||
29 | 29 | ||
30 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
31 | #include <linux/types.h> | 31 | #include <linux/types.h> |
32 | #include <linux/init.h> | ||
33 | #include <linux/interrupt.h> | 32 | #include <linux/interrupt.h> |
34 | #include <linux/in.h> | 33 | #include <linux/in.h> |
35 | #include <linux/kernel.h> | 34 | #include <linux/kernel.h> |
diff --git a/drivers/ssb/driver_chipcommon_sflash.c b/drivers/ssb/driver_chipcommon_sflash.c index 50328de712fa..937fc31971a7 100644 --- a/drivers/ssb/driver_chipcommon_sflash.c +++ b/drivers/ssb/driver_chipcommon_sflash.c | |||
@@ -37,7 +37,7 @@ static const struct ssb_sflash_tbl_e ssb_sflash_st_tbl[] = { | |||
37 | { "M25P32", 0x15, 0x10000, 64, }, | 37 | { "M25P32", 0x15, 0x10000, 64, }, |
38 | { "M25P64", 0x16, 0x10000, 128, }, | 38 | { "M25P64", 0x16, 0x10000, 128, }, |
39 | { "M25FL128", 0x17, 0x10000, 256, }, | 39 | { "M25FL128", 0x17, 0x10000, 256, }, |
40 | { 0 }, | 40 | { NULL }, |
41 | }; | 41 | }; |
42 | 42 | ||
43 | static const struct ssb_sflash_tbl_e ssb_sflash_sst_tbl[] = { | 43 | static const struct ssb_sflash_tbl_e ssb_sflash_sst_tbl[] = { |
@@ -55,7 +55,7 @@ static const struct ssb_sflash_tbl_e ssb_sflash_sst_tbl[] = { | |||
55 | { "SST25VF016", 0x41, 0x1000, 512, }, | 55 | { "SST25VF016", 0x41, 0x1000, 512, }, |
56 | { "SST25VF032", 0x4a, 0x1000, 1024, }, | 56 | { "SST25VF032", 0x4a, 0x1000, 1024, }, |
57 | { "SST25VF064", 0x4b, 0x1000, 2048, }, | 57 | { "SST25VF064", 0x4b, 0x1000, 2048, }, |
58 | { 0 }, | 58 | { NULL }, |
59 | }; | 59 | }; |
60 | 60 | ||
61 | static const struct ssb_sflash_tbl_e ssb_sflash_at_tbl[] = { | 61 | static const struct ssb_sflash_tbl_e ssb_sflash_at_tbl[] = { |
@@ -66,7 +66,7 @@ static const struct ssb_sflash_tbl_e ssb_sflash_at_tbl[] = { | |||
66 | { "AT45DB161", 0x2c, 512, 4096, }, | 66 | { "AT45DB161", 0x2c, 512, 4096, }, |
67 | { "AT45DB321", 0x34, 512, 8192, }, | 67 | { "AT45DB321", 0x34, 512, 8192, }, |
68 | { "AT45DB642", 0x3c, 1024, 8192, }, | 68 | { "AT45DB642", 0x3c, 1024, 8192, }, |
69 | { 0 }, | 69 | { NULL }, |
70 | }; | 70 | }; |
71 | 71 | ||
72 | static void ssb_sflash_cmd(struct ssb_chipcommon *cc, u32 opcode) | 72 | static void ssb_sflash_cmd(struct ssb_chipcommon *cc, u32 opcode) |
diff --git a/include/linux/mmc/sdio_ids.h b/include/linux/mmc/sdio_ids.h index 9f03feedc8e7..d8836623f36a 100644 --- a/include/linux/mmc/sdio_ids.h +++ b/include/linux/mmc/sdio_ids.h | |||
@@ -23,6 +23,15 @@ | |||
23 | /* | 23 | /* |
24 | * Vendors and devices. Sort key: vendor first, device next. | 24 | * Vendors and devices. Sort key: vendor first, device next. |
25 | */ | 25 | */ |
26 | #define SDIO_VENDOR_ID_BROADCOM 0x02d0 | ||
27 | #define SDIO_DEVICE_ID_BROADCOM_43143 43143 | ||
28 | #define SDIO_DEVICE_ID_BROADCOM_43241 0x4324 | ||
29 | #define SDIO_DEVICE_ID_BROADCOM_4329 0x4329 | ||
30 | #define SDIO_DEVICE_ID_BROADCOM_4330 0x4330 | ||
31 | #define SDIO_DEVICE_ID_BROADCOM_4334 0x4334 | ||
32 | #define SDIO_DEVICE_ID_BROADCOM_4335_4339 0x4335 | ||
33 | #define SDIO_DEVICE_ID_BROADCOM_43362 43362 | ||
34 | |||
26 | #define SDIO_VENDOR_ID_INTEL 0x0089 | 35 | #define SDIO_VENDOR_ID_INTEL 0x0089 |
27 | #define SDIO_DEVICE_ID_INTEL_IWMC3200WIMAX 0x1402 | 36 | #define SDIO_DEVICE_ID_INTEL_IWMC3200WIMAX 0x1402 |
28 | #define SDIO_DEVICE_ID_INTEL_IWMC3200WIFI 0x1403 | 37 | #define SDIO_DEVICE_ID_INTEL_IWMC3200WIFI 0x1403 |
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index cc2da73055fa..66c1cd87bfe7 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h | |||
@@ -83,7 +83,8 @@ | |||
83 | enum { | 83 | enum { |
84 | HCI_QUIRK_RESET_ON_CLOSE, | 84 | HCI_QUIRK_RESET_ON_CLOSE, |
85 | HCI_QUIRK_RAW_DEVICE, | 85 | HCI_QUIRK_RAW_DEVICE, |
86 | HCI_QUIRK_FIXUP_BUFFER_SIZE | 86 | HCI_QUIRK_FIXUP_BUFFER_SIZE, |
87 | HCI_QUIRK_BROKEN_STORED_LINK_KEY, | ||
87 | }; | 88 | }; |
88 | 89 | ||
89 | /* HCI device flags */ | 90 | /* HCI device flags */ |
@@ -131,6 +132,7 @@ enum { | |||
131 | HCI_PERIODIC_INQ, | 132 | HCI_PERIODIC_INQ, |
132 | HCI_FAST_CONNECTABLE, | 133 | HCI_FAST_CONNECTABLE, |
133 | HCI_BREDR_ENABLED, | 134 | HCI_BREDR_ENABLED, |
135 | HCI_6LOWPAN_ENABLED, | ||
134 | }; | 136 | }; |
135 | 137 | ||
136 | /* A mask for the flags that are supposed to remain when a reset happens | 138 | /* A mask for the flags that are supposed to remain when a reset happens |
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index b796161fb04e..f2f0cf5865c4 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h | |||
@@ -448,6 +448,7 @@ enum { | |||
448 | HCI_CONN_SSP_ENABLED, | 448 | HCI_CONN_SSP_ENABLED, |
449 | HCI_CONN_POWER_SAVE, | 449 | HCI_CONN_POWER_SAVE, |
450 | HCI_CONN_REMOTE_OOB, | 450 | HCI_CONN_REMOTE_OOB, |
451 | HCI_CONN_6LOWPAN, | ||
451 | }; | 452 | }; |
452 | 453 | ||
453 | static inline bool hci_conn_ssp_enabled(struct hci_conn *conn) | 454 | static inline bool hci_conn_ssp_enabled(struct hci_conn *conn) |
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index e149e992fdae..dbc4a89984ca 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h | |||
@@ -136,6 +136,7 @@ struct l2cap_conninfo { | |||
136 | #define L2CAP_FC_L2CAP 0x02 | 136 | #define L2CAP_FC_L2CAP 0x02 |
137 | #define L2CAP_FC_CONNLESS 0x04 | 137 | #define L2CAP_FC_CONNLESS 0x04 |
138 | #define L2CAP_FC_A2MP 0x08 | 138 | #define L2CAP_FC_A2MP 0x08 |
139 | #define L2CAP_FC_6LOWPAN 0x3e /* reserved and temporary value */ | ||
139 | 140 | ||
140 | /* L2CAP Control Field bit masks */ | 141 | /* L2CAP Control Field bit masks */ |
141 | #define L2CAP_CTRL_SAR 0xC000 | 142 | #define L2CAP_CTRL_SAR 0xC000 |
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 80a10212b1b9..56c597793d6d 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h | |||
@@ -1972,6 +1972,50 @@ struct cfg80211_mgmt_tx_params { | |||
1972 | }; | 1972 | }; |
1973 | 1973 | ||
1974 | /** | 1974 | /** |
1975 | * struct cfg80211_dscp_exception - DSCP exception | ||
1976 | * | ||
1977 | * @dscp: DSCP value that does not adhere to the user priority range definition | ||
1978 | * @up: user priority value to which the corresponding DSCP value belongs | ||
1979 | */ | ||
1980 | struct cfg80211_dscp_exception { | ||
1981 | u8 dscp; | ||
1982 | u8 up; | ||
1983 | }; | ||
1984 | |||
1985 | /** | ||
1986 | * struct cfg80211_dscp_range - DSCP range definition for user priority | ||
1987 | * | ||
1988 | * @low: lowest DSCP value of this user priority range, inclusive | ||
1989 | * @high: highest DSCP value of this user priority range, inclusive | ||
1990 | */ | ||
1991 | struct cfg80211_dscp_range { | ||
1992 | u8 low; | ||
1993 | u8 high; | ||
1994 | }; | ||
1995 | |||
1996 | /* QoS Map Set element length defined in IEEE Std 802.11-2012, 8.4.2.97 */ | ||
1997 | #define IEEE80211_QOS_MAP_MAX_EX 21 | ||
1998 | #define IEEE80211_QOS_MAP_LEN_MIN 16 | ||
1999 | #define IEEE80211_QOS_MAP_LEN_MAX \ | ||
2000 | (IEEE80211_QOS_MAP_LEN_MIN + 2 * IEEE80211_QOS_MAP_MAX_EX) | ||
2001 | |||
2002 | /** | ||
2003 | * struct cfg80211_qos_map - QoS Map Information | ||
2004 | * | ||
2005 | * This struct defines the Interworking QoS map setting for DSCP values | ||
2006 | * | ||
2007 | * @num_des: number of DSCP exceptions (0..21) | ||
2008 | * @dscp_exception: optionally up to maximum of 21 DSCP exceptions from | ||
2009 | * the user priority DSCP range definition | ||
2010 | * @up: DSCP range definition for a particular user priority | ||
2011 | */ | ||
2012 | struct cfg80211_qos_map { | ||
2013 | u8 num_des; | ||
2014 | struct cfg80211_dscp_exception dscp_exception[IEEE80211_QOS_MAP_MAX_EX]; | ||
2015 | struct cfg80211_dscp_range up[8]; | ||
2016 | }; | ||
2017 | |||
2018 | /** | ||
1975 | * struct cfg80211_ops - backend description for wireless configuration | 2019 | * struct cfg80211_ops - backend description for wireless configuration |
1976 | * | 2020 | * |
1977 | * This struct is registered by fullmac card drivers and/or wireless stacks | 2021 | * This struct is registered by fullmac card drivers and/or wireless stacks |
@@ -2213,6 +2257,8 @@ struct cfg80211_mgmt_tx_params { | |||
2213 | * @set_coalesce: Set coalesce parameters. | 2257 | * @set_coalesce: Set coalesce parameters. |
2214 | * | 2258 | * |
2215 | * @channel_switch: initiate channel-switch procedure (with CSA) | 2259 | * @channel_switch: initiate channel-switch procedure (with CSA) |
2260 | * | ||
2261 | * @set_qos_map: Set QoS mapping information to the driver | ||
2216 | */ | 2262 | */ |
2217 | struct cfg80211_ops { | 2263 | struct cfg80211_ops { |
2218 | int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow); | 2264 | int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow); |
@@ -2454,6 +2500,9 @@ struct cfg80211_ops { | |||
2454 | int (*channel_switch)(struct wiphy *wiphy, | 2500 | int (*channel_switch)(struct wiphy *wiphy, |
2455 | struct net_device *dev, | 2501 | struct net_device *dev, |
2456 | struct cfg80211_csa_settings *params); | 2502 | struct cfg80211_csa_settings *params); |
2503 | int (*set_qos_map)(struct wiphy *wiphy, | ||
2504 | struct net_device *dev, | ||
2505 | struct cfg80211_qos_map *qos_map); | ||
2457 | }; | 2506 | }; |
2458 | 2507 | ||
2459 | /* | 2508 | /* |
@@ -2824,6 +2873,8 @@ struct wiphy_vendor_command { | |||
2824 | * | 2873 | * |
2825 | * @vendor_commands: array of vendor commands supported by the hardware | 2874 | * @vendor_commands: array of vendor commands supported by the hardware |
2826 | * @n_vendor_commands: number of vendor commands | 2875 | * @n_vendor_commands: number of vendor commands |
2876 | * @vendor_events: array of vendor events supported by the hardware | ||
2877 | * @n_vendor_events: number of vendor events | ||
2827 | */ | 2878 | */ |
2828 | struct wiphy { | 2879 | struct wiphy { |
2829 | /* assign these fields before you register the wiphy */ | 2880 | /* assign these fields before you register the wiphy */ |
@@ -2936,7 +2987,8 @@ struct wiphy { | |||
2936 | const struct wiphy_coalesce_support *coalesce; | 2987 | const struct wiphy_coalesce_support *coalesce; |
2937 | 2988 | ||
2938 | const struct wiphy_vendor_command *vendor_commands; | 2989 | const struct wiphy_vendor_command *vendor_commands; |
2939 | int n_vendor_commands; | 2990 | const struct nl80211_vendor_cmd_info *vendor_events; |
2991 | int n_vendor_commands, n_vendor_events; | ||
2940 | 2992 | ||
2941 | char priv[0] __aligned(NETDEV_ALIGN); | 2993 | char priv[0] __aligned(NETDEV_ALIGN); |
2942 | }; | 2994 | }; |
@@ -3429,9 +3481,11 @@ void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list, | |||
3429 | /** | 3481 | /** |
3430 | * cfg80211_classify8021d - determine the 802.1p/1d tag for a data frame | 3482 | * cfg80211_classify8021d - determine the 802.1p/1d tag for a data frame |
3431 | * @skb: the data frame | 3483 | * @skb: the data frame |
3484 | * @qos_map: Interworking QoS mapping or %NULL if not in use | ||
3432 | * Return: The 802.1p/1d tag. | 3485 | * Return: The 802.1p/1d tag. |
3433 | */ | 3486 | */ |
3434 | unsigned int cfg80211_classify8021d(struct sk_buff *skb); | 3487 | unsigned int cfg80211_classify8021d(struct sk_buff *skb, |
3488 | struct cfg80211_qos_map *qos_map); | ||
3435 | 3489 | ||
3436 | /** | 3490 | /** |
3437 | * cfg80211_find_ie - find information element in data | 3491 | * cfg80211_find_ie - find information element in data |
@@ -3907,6 +3961,14 @@ struct sk_buff *__cfg80211_alloc_reply_skb(struct wiphy *wiphy, | |||
3907 | enum nl80211_attrs attr, | 3961 | enum nl80211_attrs attr, |
3908 | int approxlen); | 3962 | int approxlen); |
3909 | 3963 | ||
3964 | struct sk_buff *__cfg80211_alloc_event_skb(struct wiphy *wiphy, | ||
3965 | enum nl80211_commands cmd, | ||
3966 | enum nl80211_attrs attr, | ||
3967 | int vendor_event_idx, | ||
3968 | int approxlen, gfp_t gfp); | ||
3969 | |||
3970 | void __cfg80211_send_event_skb(struct sk_buff *skb, gfp_t gfp); | ||
3971 | |||
3910 | /** | 3972 | /** |
3911 | * cfg80211_vendor_cmd_alloc_reply_skb - allocate vendor command reply | 3973 | * cfg80211_vendor_cmd_alloc_reply_skb - allocate vendor command reply |
3912 | * @wiphy: the wiphy | 3974 | * @wiphy: the wiphy |
@@ -3951,6 +4013,44 @@ cfg80211_vendor_cmd_alloc_reply_skb(struct wiphy *wiphy, int approxlen) | |||
3951 | */ | 4013 | */ |
3952 | int cfg80211_vendor_cmd_reply(struct sk_buff *skb); | 4014 | int cfg80211_vendor_cmd_reply(struct sk_buff *skb); |
3953 | 4015 | ||
4016 | /** | ||
4017 | * cfg80211_vendor_event_alloc - allocate vendor-specific event skb | ||
4018 | * @wiphy: the wiphy | ||
4019 | * @event_idx: index of the vendor event in the wiphy's vendor_events | ||
4020 | * @approxlen: an upper bound of the length of the data that will | ||
4021 | * be put into the skb | ||
4022 | * @gfp: allocation flags | ||
4023 | * | ||
4024 | * This function allocates and pre-fills an skb for an event on the | ||
4025 | * vendor-specific multicast group. | ||
4026 | * | ||
4027 | * When done filling the skb, call cfg80211_vendor_event() with the | ||
4028 | * skb to send the event. | ||
4029 | * | ||
4030 | * Return: An allocated and pre-filled skb. %NULL if any errors happen. | ||
4031 | */ | ||
4032 | static inline struct sk_buff * | ||
4033 | cfg80211_vendor_event_alloc(struct wiphy *wiphy, int approxlen, | ||
4034 | int event_idx, gfp_t gfp) | ||
4035 | { | ||
4036 | return __cfg80211_alloc_event_skb(wiphy, NL80211_CMD_VENDOR, | ||
4037 | NL80211_ATTR_VENDOR_DATA, | ||
4038 | event_idx, approxlen, gfp); | ||
4039 | } | ||
4040 | |||
4041 | /** | ||
4042 | * cfg80211_vendor_event - send the event | ||
4043 | * @skb: The skb, must have been allocated with cfg80211_vendor_event_alloc() | ||
4044 | * @gfp: allocation flags | ||
4045 | * | ||
4046 | * This function sends the given @skb, which must have been allocated | ||
4047 | * by cfg80211_vendor_event_alloc(), as an event. It always consumes it. | ||
4048 | */ | ||
4049 | static inline void cfg80211_vendor_event(struct sk_buff *skb, gfp_t gfp) | ||
4050 | { | ||
4051 | __cfg80211_send_event_skb(skb, gfp); | ||
4052 | } | ||
4053 | |||
3954 | #ifdef CONFIG_NL80211_TESTMODE | 4054 | #ifdef CONFIG_NL80211_TESTMODE |
3955 | /** | 4055 | /** |
3956 | * DOC: Test mode | 4056 | * DOC: Test mode |
@@ -4031,8 +4131,13 @@ static inline int cfg80211_testmode_reply(struct sk_buff *skb) | |||
4031 | * | 4131 | * |
4032 | * Return: An allocated and pre-filled skb. %NULL if any errors happen. | 4132 | * Return: An allocated and pre-filled skb. %NULL if any errors happen. |
4033 | */ | 4133 | */ |
4034 | struct sk_buff *cfg80211_testmode_alloc_event_skb(struct wiphy *wiphy, | 4134 | static inline struct sk_buff * |
4035 | int approxlen, gfp_t gfp); | 4135 | cfg80211_testmode_alloc_event_skb(struct wiphy *wiphy, int approxlen, gfp_t gfp) |
4136 | { | ||
4137 | return __cfg80211_alloc_event_skb(wiphy, NL80211_CMD_TESTMODE, | ||
4138 | NL80211_ATTR_TESTDATA, -1, | ||
4139 | approxlen, gfp); | ||
4140 | } | ||
4036 | 4141 | ||
4037 | /** | 4142 | /** |
4038 | * cfg80211_testmode_event - send the event | 4143 | * cfg80211_testmode_event - send the event |
@@ -4044,7 +4149,10 @@ struct sk_buff *cfg80211_testmode_alloc_event_skb(struct wiphy *wiphy, | |||
4044 | * by cfg80211_testmode_alloc_event_skb(), as an event. It always | 4149 | * by cfg80211_testmode_alloc_event_skb(), as an event. It always |
4045 | * consumes it. | 4150 | * consumes it. |
4046 | */ | 4151 | */ |
4047 | void cfg80211_testmode_event(struct sk_buff *skb, gfp_t gfp); | 4152 | static inline void cfg80211_testmode_event(struct sk_buff *skb, gfp_t gfp) |
4153 | { | ||
4154 | __cfg80211_send_event_skb(skb, gfp); | ||
4155 | } | ||
4048 | 4156 | ||
4049 | #define CFG80211_TESTMODE_CMD(cmd) .testmode_cmd = (cmd), | 4157 | #define CFG80211_TESTMODE_CMD(cmd) .testmode_cmd = (cmd), |
4050 | #define CFG80211_TESTMODE_DUMP(cmd) .testmode_dump = (cmd), | 4158 | #define CFG80211_TESTMODE_DUMP(cmd) .testmode_dump = (cmd), |
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 531785f5819e..f838af816b56 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -4652,4 +4652,51 @@ bool ieee80211_tx_prepare_skb(struct ieee80211_hw *hw, | |||
4652 | struct ieee80211_vif *vif, struct sk_buff *skb, | 4652 | struct ieee80211_vif *vif, struct sk_buff *skb, |
4653 | int band, struct ieee80211_sta **sta); | 4653 | int band, struct ieee80211_sta **sta); |
4654 | 4654 | ||
4655 | /** | ||
4656 | * struct ieee80211_noa_data - holds temporary data for tracking P2P NoA state | ||
4657 | * | ||
4658 | * @next_tsf: TSF timestamp of the next absent state change | ||
4659 | * @has_next_tsf: next absent state change event pending | ||
4660 | * | ||
4661 | * @absent: descriptor bitmask, set if GO is currently absent | ||
4662 | * | ||
4663 | * private: | ||
4664 | * | ||
4665 | * @count: count fields from the NoA descriptors | ||
4666 | * @desc: adjusted data from the NoA | ||
4667 | */ | ||
4668 | struct ieee80211_noa_data { | ||
4669 | u32 next_tsf; | ||
4670 | bool has_next_tsf; | ||
4671 | |||
4672 | u8 absent; | ||
4673 | |||
4674 | u8 count[IEEE80211_P2P_NOA_DESC_MAX]; | ||
4675 | struct { | ||
4676 | u32 start; | ||
4677 | u32 duration; | ||
4678 | u32 interval; | ||
4679 | } desc[IEEE80211_P2P_NOA_DESC_MAX]; | ||
4680 | }; | ||
4681 | |||
4682 | /** | ||
4683 | * ieee80211_parse_p2p_noa - initialize NoA tracking data from P2P IE | ||
4684 | * | ||
4685 | * @attr: P2P NoA IE | ||
4686 | * @data: NoA tracking data | ||
4687 | * @tsf: current TSF timestamp | ||
4688 | * | ||
4689 | * Return: number of successfully parsed descriptors | ||
4690 | */ | ||
4691 | int ieee80211_parse_p2p_noa(const struct ieee80211_p2p_noa_attr *attr, | ||
4692 | struct ieee80211_noa_data *data, u32 tsf); | ||
4693 | |||
4694 | /** | ||
4695 | * ieee80211_update_p2p_noa - get next pending P2P GO absent state change | ||
4696 | * | ||
4697 | * @data: NoA tracking data | ||
4698 | * @tsf: current TSF timestamp | ||
4699 | */ | ||
4700 | void ieee80211_update_p2p_noa(struct ieee80211_noa_data *data, u32 tsf); | ||
4701 | |||
4655 | #endif /* MAC80211_H */ | 4702 | #endif /* MAC80211_H */ |
diff --git a/include/uapi/linux/if_arp.h b/include/uapi/linux/if_arp.h index d7fea3496f32..4d024d75d64b 100644 --- a/include/uapi/linux/if_arp.h +++ b/include/uapi/linux/if_arp.h | |||
@@ -94,6 +94,7 @@ | |||
94 | #define ARPHRD_CAIF 822 /* CAIF media type */ | 94 | #define ARPHRD_CAIF 822 /* CAIF media type */ |
95 | #define ARPHRD_IP6GRE 823 /* GRE over IPv6 */ | 95 | #define ARPHRD_IP6GRE 823 /* GRE over IPv6 */ |
96 | #define ARPHRD_NETLINK 824 /* Netlink header */ | 96 | #define ARPHRD_NETLINK 824 /* Netlink header */ |
97 | #define ARPHRD_6LOWPAN 825 /* IPv6 over LoWPAN */ | ||
97 | 98 | ||
98 | #define ARPHRD_VOID 0xFFFF /* Void type, nothing is known */ | 99 | #define ARPHRD_VOID 0xFFFF /* Void type, nothing is known */ |
99 | #define ARPHRD_NONE 0xFFFE /* zero header length */ | 100 | #define ARPHRD_NONE 0xFFFE /* zero header length */ |
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index e1307909ecf1..91054fd660e0 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h | |||
@@ -702,6 +702,12 @@ | |||
702 | * (&struct nl80211_vendor_cmd_info) of the supported vendor commands. | 702 | * (&struct nl80211_vendor_cmd_info) of the supported vendor commands. |
703 | * This may also be sent as an event with the same attributes. | 703 | * This may also be sent as an event with the same attributes. |
704 | * | 704 | * |
705 | * @NL80211_CMD_SET_QOS_MAP: Set Interworking QoS mapping for IP DSCP values. | ||
706 | * The QoS mapping information is included in %NL80211_ATTR_QOS_MAP. If | ||
707 | * that attribute is not included, QoS mapping is disabled. Since this | ||
708 | * QoS mapping is relevant for IP packets, it is only valid during an | ||
709 | * association. This is cleared on disassociation and AP restart. | ||
710 | * | ||
705 | * @NL80211_CMD_MAX: highest used command number | 711 | * @NL80211_CMD_MAX: highest used command number |
706 | * @__NL80211_CMD_AFTER_LAST: internal use | 712 | * @__NL80211_CMD_AFTER_LAST: internal use |
707 | */ | 713 | */ |
@@ -871,6 +877,8 @@ enum nl80211_commands { | |||
871 | 877 | ||
872 | NL80211_CMD_VENDOR, | 878 | NL80211_CMD_VENDOR, |
873 | 879 | ||
880 | NL80211_CMD_SET_QOS_MAP, | ||
881 | |||
874 | /* add new commands above here */ | 882 | /* add new commands above here */ |
875 | 883 | ||
876 | /* used to define NL80211_CMD_MAX below */ | 884 | /* used to define NL80211_CMD_MAX below */ |
@@ -1540,6 +1548,12 @@ enum nl80211_commands { | |||
1540 | * @NL80211_ATTR_VENDOR_SUBCMD: vendor sub-command | 1548 | * @NL80211_ATTR_VENDOR_SUBCMD: vendor sub-command |
1541 | * @NL80211_ATTR_VENDOR_DATA: data for the vendor command, if any; this | 1549 | * @NL80211_ATTR_VENDOR_DATA: data for the vendor command, if any; this |
1542 | * attribute is also used for vendor command feature advertisement | 1550 | * attribute is also used for vendor command feature advertisement |
1551 | * @NL80211_ATTR_VENDOR_EVENTS: used for event list advertising in the wiphy | ||
1552 | * info, containing a nested array of possible events | ||
1553 | * | ||
1554 | * @NL80211_ATTR_QOS_MAP: IP DSCP mapping for Interworking QoS mapping. This | ||
1555 | * data is in the format defined for the payload of the QoS Map Set element | ||
1556 | * in IEEE Std 802.11-2012, 8.4.2.97. | ||
1543 | * | 1557 | * |
1544 | * @NL80211_ATTR_MAX: highest attribute number currently defined | 1558 | * @NL80211_ATTR_MAX: highest attribute number currently defined |
1545 | * @__NL80211_ATTR_AFTER_LAST: internal use | 1559 | * @__NL80211_ATTR_AFTER_LAST: internal use |
@@ -1865,6 +1879,9 @@ enum nl80211_attrs { | |||
1865 | NL80211_ATTR_VENDOR_ID, | 1879 | NL80211_ATTR_VENDOR_ID, |
1866 | NL80211_ATTR_VENDOR_SUBCMD, | 1880 | NL80211_ATTR_VENDOR_SUBCMD, |
1867 | NL80211_ATTR_VENDOR_DATA, | 1881 | NL80211_ATTR_VENDOR_DATA, |
1882 | NL80211_ATTR_VENDOR_EVENTS, | ||
1883 | |||
1884 | NL80211_ATTR_QOS_MAP, | ||
1868 | 1885 | ||
1869 | /* add attributes here, update the policy in nl80211.c */ | 1886 | /* add attributes here, update the policy in nl80211.c */ |
1870 | 1887 | ||
diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c new file mode 100644 index 000000000000..adb3ea04adaa --- /dev/null +++ b/net/bluetooth/6lowpan.c | |||
@@ -0,0 +1,860 @@ | |||
1 | /* | ||
2 | Copyright (c) 2013 Intel Corp. | ||
3 | |||
4 | This program is free software; you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Public License version 2 and | ||
6 | only version 2 as published by the Free Software Foundation. | ||
7 | |||
8 | This program is distributed in the hope that it will be useful, | ||
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | GNU General Public License for more details. | ||
12 | */ | ||
13 | |||
14 | #include <linux/if_arp.h> | ||
15 | #include <linux/netdevice.h> | ||
16 | #include <linux/etherdevice.h> | ||
17 | |||
18 | #include <net/ipv6.h> | ||
19 | #include <net/ip6_route.h> | ||
20 | #include <net/addrconf.h> | ||
21 | |||
22 | #include <net/af_ieee802154.h> /* to get the address type */ | ||
23 | |||
24 | #include <net/bluetooth/bluetooth.h> | ||
25 | #include <net/bluetooth/hci_core.h> | ||
26 | #include <net/bluetooth/l2cap.h> | ||
27 | |||
28 | #include "6lowpan.h" | ||
29 | |||
30 | #include "../ieee802154/6lowpan.h" /* for the compression support */ | ||
31 | |||
32 | #define IFACE_NAME_TEMPLATE "bt%d" | ||
33 | #define EUI64_ADDR_LEN 8 | ||
34 | |||
35 | struct skb_cb { | ||
36 | struct in6_addr addr; | ||
37 | struct l2cap_conn *conn; | ||
38 | }; | ||
39 | #define lowpan_cb(skb) ((struct skb_cb *)((skb)->cb)) | ||
40 | |||
41 | /* The devices list contains those devices that we are acting | ||
42 | * as a proxy. The BT 6LoWPAN device is a virtual device that | ||
43 | * connects to the Bluetooth LE device. The real connection to | ||
44 | * BT device is done via l2cap layer. There exists one | ||
45 | * virtual device / one BT 6LoWPAN network (=hciX device). | ||
46 | * The list contains struct lowpan_dev elements. | ||
47 | */ | ||
48 | static LIST_HEAD(bt_6lowpan_devices); | ||
49 | static DEFINE_RWLOCK(devices_lock); | ||
50 | |||
51 | struct lowpan_peer { | ||
52 | struct list_head list; | ||
53 | struct l2cap_conn *conn; | ||
54 | |||
55 | /* peer addresses in various formats */ | ||
56 | unsigned char eui64_addr[EUI64_ADDR_LEN]; | ||
57 | struct in6_addr peer_addr; | ||
58 | }; | ||
59 | |||
60 | struct lowpan_dev { | ||
61 | struct list_head list; | ||
62 | |||
63 | struct hci_dev *hdev; | ||
64 | struct net_device *netdev; | ||
65 | struct list_head peers; | ||
66 | atomic_t peer_count; /* number of items in peers list */ | ||
67 | |||
68 | struct work_struct delete_netdev; | ||
69 | struct delayed_work notify_peers; | ||
70 | }; | ||
71 | |||
72 | static inline struct lowpan_dev *lowpan_dev(const struct net_device *netdev) | ||
73 | { | ||
74 | return netdev_priv(netdev); | ||
75 | } | ||
76 | |||
77 | static inline void peer_add(struct lowpan_dev *dev, struct lowpan_peer *peer) | ||
78 | { | ||
79 | list_add(&peer->list, &dev->peers); | ||
80 | atomic_inc(&dev->peer_count); | ||
81 | } | ||
82 | |||
83 | static inline bool peer_del(struct lowpan_dev *dev, struct lowpan_peer *peer) | ||
84 | { | ||
85 | list_del(&peer->list); | ||
86 | |||
87 | if (atomic_dec_and_test(&dev->peer_count)) { | ||
88 | BT_DBG("last peer"); | ||
89 | return true; | ||
90 | } | ||
91 | |||
92 | return false; | ||
93 | } | ||
94 | |||
95 | static inline struct lowpan_peer *peer_lookup_ba(struct lowpan_dev *dev, | ||
96 | bdaddr_t *ba, __u8 type) | ||
97 | { | ||
98 | struct lowpan_peer *peer, *tmp; | ||
99 | |||
100 | BT_DBG("peers %d addr %pMR type %d", atomic_read(&dev->peer_count), | ||
101 | ba, type); | ||
102 | |||
103 | list_for_each_entry_safe(peer, tmp, &dev->peers, list) { | ||
104 | BT_DBG("addr %pMR type %d", | ||
105 | &peer->conn->hcon->dst, peer->conn->hcon->dst_type); | ||
106 | |||
107 | if (bacmp(&peer->conn->hcon->dst, ba)) | ||
108 | continue; | ||
109 | |||
110 | if (type == peer->conn->hcon->dst_type) | ||
111 | return peer; | ||
112 | } | ||
113 | |||
114 | return NULL; | ||
115 | } | ||
116 | |||
117 | static inline struct lowpan_peer *peer_lookup_conn(struct lowpan_dev *dev, | ||
118 | struct l2cap_conn *conn) | ||
119 | { | ||
120 | struct lowpan_peer *peer, *tmp; | ||
121 | |||
122 | list_for_each_entry_safe(peer, tmp, &dev->peers, list) { | ||
123 | if (peer->conn == conn) | ||
124 | return peer; | ||
125 | } | ||
126 | |||
127 | return NULL; | ||
128 | } | ||
129 | |||
130 | static struct lowpan_peer *lookup_peer(struct l2cap_conn *conn) | ||
131 | { | ||
132 | struct lowpan_dev *entry, *tmp; | ||
133 | struct lowpan_peer *peer = NULL; | ||
134 | unsigned long flags; | ||
135 | |||
136 | read_lock_irqsave(&devices_lock, flags); | ||
137 | |||
138 | list_for_each_entry_safe(entry, tmp, &bt_6lowpan_devices, list) { | ||
139 | peer = peer_lookup_conn(entry, conn); | ||
140 | if (peer) | ||
141 | break; | ||
142 | } | ||
143 | |||
144 | read_unlock_irqrestore(&devices_lock, flags); | ||
145 | |||
146 | return peer; | ||
147 | } | ||
148 | |||
149 | static struct lowpan_dev *lookup_dev(struct l2cap_conn *conn) | ||
150 | { | ||
151 | struct lowpan_dev *entry, *tmp; | ||
152 | struct lowpan_dev *dev = NULL; | ||
153 | unsigned long flags; | ||
154 | |||
155 | read_lock_irqsave(&devices_lock, flags); | ||
156 | |||
157 | list_for_each_entry_safe(entry, tmp, &bt_6lowpan_devices, list) { | ||
158 | if (conn->hcon->hdev == entry->hdev) { | ||
159 | dev = entry; | ||
160 | break; | ||
161 | } | ||
162 | } | ||
163 | |||
164 | read_unlock_irqrestore(&devices_lock, flags); | ||
165 | |||
166 | return dev; | ||
167 | } | ||
168 | |||
169 | static int give_skb_to_upper(struct sk_buff *skb, struct net_device *dev) | ||
170 | { | ||
171 | struct sk_buff *skb_cp; | ||
172 | int ret; | ||
173 | |||
174 | skb_cp = skb_copy(skb, GFP_ATOMIC); | ||
175 | if (!skb_cp) | ||
176 | return -ENOMEM; | ||
177 | |||
178 | ret = netif_rx(skb_cp); | ||
179 | |||
180 | BT_DBG("receive skb %d", ret); | ||
181 | if (ret < 0) | ||
182 | return NET_RX_DROP; | ||
183 | |||
184 | return ret; | ||
185 | } | ||
186 | |||
187 | static int process_data(struct sk_buff *skb, struct net_device *netdev, | ||
188 | struct l2cap_conn *conn) | ||
189 | { | ||
190 | const u8 *saddr, *daddr; | ||
191 | u8 iphc0, iphc1; | ||
192 | struct lowpan_dev *dev; | ||
193 | struct lowpan_peer *peer; | ||
194 | unsigned long flags; | ||
195 | |||
196 | dev = lowpan_dev(netdev); | ||
197 | |||
198 | read_lock_irqsave(&devices_lock, flags); | ||
199 | peer = peer_lookup_conn(dev, conn); | ||
200 | read_unlock_irqrestore(&devices_lock, flags); | ||
201 | if (!peer) | ||
202 | goto drop; | ||
203 | |||
204 | saddr = peer->eui64_addr; | ||
205 | daddr = dev->netdev->dev_addr; | ||
206 | |||
207 | /* at least two bytes will be used for the encoding */ | ||
208 | if (skb->len < 2) | ||
209 | goto drop; | ||
210 | |||
211 | if (lowpan_fetch_skb_u8(skb, &iphc0)) | ||
212 | goto drop; | ||
213 | |||
214 | if (lowpan_fetch_skb_u8(skb, &iphc1)) | ||
215 | goto drop; | ||
216 | |||
217 | return lowpan_process_data(skb, netdev, | ||
218 | saddr, IEEE802154_ADDR_LONG, EUI64_ADDR_LEN, | ||
219 | daddr, IEEE802154_ADDR_LONG, EUI64_ADDR_LEN, | ||
220 | iphc0, iphc1, give_skb_to_upper); | ||
221 | |||
222 | drop: | ||
223 | kfree_skb(skb); | ||
224 | return -EINVAL; | ||
225 | } | ||
226 | |||
227 | static int recv_pkt(struct sk_buff *skb, struct net_device *dev, | ||
228 | struct l2cap_conn *conn) | ||
229 | { | ||
230 | struct sk_buff *local_skb; | ||
231 | int ret; | ||
232 | |||
233 | if (!netif_running(dev)) | ||
234 | goto drop; | ||
235 | |||
236 | if (dev->type != ARPHRD_6LOWPAN) | ||
237 | goto drop; | ||
238 | |||
239 | /* check that it's our buffer */ | ||
240 | if (skb->data[0] == LOWPAN_DISPATCH_IPV6) { | ||
241 | /* Copy the packet so that the IPv6 header is | ||
242 | * properly aligned. | ||
243 | */ | ||
244 | local_skb = skb_copy_expand(skb, NET_SKB_PAD - 1, | ||
245 | skb_tailroom(skb), GFP_ATOMIC); | ||
246 | if (!local_skb) | ||
247 | goto drop; | ||
248 | |||
249 | local_skb->protocol = htons(ETH_P_IPV6); | ||
250 | local_skb->pkt_type = PACKET_HOST; | ||
251 | |||
252 | skb_reset_network_header(local_skb); | ||
253 | skb_set_transport_header(local_skb, sizeof(struct ipv6hdr)); | ||
254 | |||
255 | if (give_skb_to_upper(local_skb, dev) != NET_RX_SUCCESS) { | ||
256 | kfree_skb(local_skb); | ||
257 | goto drop; | ||
258 | } | ||
259 | |||
260 | dev->stats.rx_bytes += skb->len; | ||
261 | dev->stats.rx_packets++; | ||
262 | |||
263 | kfree_skb(local_skb); | ||
264 | kfree_skb(skb); | ||
265 | } else { | ||
266 | switch (skb->data[0] & 0xe0) { | ||
267 | case LOWPAN_DISPATCH_IPHC: /* ipv6 datagram */ | ||
268 | local_skb = skb_clone(skb, GFP_ATOMIC); | ||
269 | if (!local_skb) | ||
270 | goto drop; | ||
271 | |||
272 | ret = process_data(local_skb, dev, conn); | ||
273 | if (ret != NET_RX_SUCCESS) | ||
274 | goto drop; | ||
275 | |||
276 | dev->stats.rx_bytes += skb->len; | ||
277 | dev->stats.rx_packets++; | ||
278 | |||
279 | kfree_skb(skb); | ||
280 | break; | ||
281 | default: | ||
282 | break; | ||
283 | } | ||
284 | } | ||
285 | |||
286 | return NET_RX_SUCCESS; | ||
287 | |||
288 | drop: | ||
289 | kfree_skb(skb); | ||
290 | return NET_RX_DROP; | ||
291 | } | ||
292 | |||
293 | /* Packet from BT LE device */ | ||
294 | int bt_6lowpan_recv(struct l2cap_conn *conn, struct sk_buff *skb) | ||
295 | { | ||
296 | struct lowpan_dev *dev; | ||
297 | struct lowpan_peer *peer; | ||
298 | int err; | ||
299 | |||
300 | peer = lookup_peer(conn); | ||
301 | if (!peer) | ||
302 | return -ENOENT; | ||
303 | |||
304 | dev = lookup_dev(conn); | ||
305 | if (!dev || !dev->netdev) | ||
306 | return -ENOENT; | ||
307 | |||
308 | err = recv_pkt(skb, dev->netdev, conn); | ||
309 | BT_DBG("recv pkt %d", err); | ||
310 | |||
311 | return err; | ||
312 | } | ||
313 | |||
314 | static inline int skbuff_copy(void *msg, int len, int count, int mtu, | ||
315 | struct sk_buff *skb, struct net_device *dev) | ||
316 | { | ||
317 | struct sk_buff **frag; | ||
318 | int sent = 0; | ||
319 | |||
320 | memcpy(skb_put(skb, count), msg, count); | ||
321 | |||
322 | sent += count; | ||
323 | msg += count; | ||
324 | len -= count; | ||
325 | |||
326 | dev->stats.tx_bytes += count; | ||
327 | dev->stats.tx_packets++; | ||
328 | |||
329 | raw_dump_table(__func__, "Sending", skb->data, skb->len); | ||
330 | |||
331 | /* Continuation fragments (no L2CAP header) */ | ||
332 | frag = &skb_shinfo(skb)->frag_list; | ||
333 | while (len > 0) { | ||
334 | struct sk_buff *tmp; | ||
335 | |||
336 | count = min_t(unsigned int, mtu, len); | ||
337 | |||
338 | tmp = bt_skb_alloc(count, GFP_ATOMIC); | ||
339 | if (!tmp) | ||
340 | return -ENOMEM; | ||
341 | |||
342 | *frag = tmp; | ||
343 | |||
344 | memcpy(skb_put(*frag, count), msg, count); | ||
345 | |||
346 | raw_dump_table(__func__, "Sending fragment", | ||
347 | (*frag)->data, count); | ||
348 | |||
349 | (*frag)->priority = skb->priority; | ||
350 | |||
351 | sent += count; | ||
352 | msg += count; | ||
353 | len -= count; | ||
354 | |||
355 | skb->len += (*frag)->len; | ||
356 | skb->data_len += (*frag)->len; | ||
357 | |||
358 | frag = &(*frag)->next; | ||
359 | |||
360 | dev->stats.tx_bytes += count; | ||
361 | dev->stats.tx_packets++; | ||
362 | } | ||
363 | |||
364 | return sent; | ||
365 | } | ||
366 | |||
367 | static struct sk_buff *create_pdu(struct l2cap_conn *conn, void *msg, | ||
368 | size_t len, u32 priority, | ||
369 | struct net_device *dev) | ||
370 | { | ||
371 | struct sk_buff *skb; | ||
372 | int err, count; | ||
373 | struct l2cap_hdr *lh; | ||
374 | |||
375 | /* FIXME: This mtu check should be not needed and atm is only used for | ||
376 | * testing purposes | ||
377 | */ | ||
378 | if (conn->mtu > (L2CAP_LE_MIN_MTU + L2CAP_HDR_SIZE)) | ||
379 | conn->mtu = L2CAP_LE_MIN_MTU + L2CAP_HDR_SIZE; | ||
380 | |||
381 | count = min_t(unsigned int, (conn->mtu - L2CAP_HDR_SIZE), len); | ||
382 | |||
383 | BT_DBG("conn %p len %zu mtu %d count %d", conn, len, conn->mtu, count); | ||
384 | |||
385 | skb = bt_skb_alloc(count + L2CAP_HDR_SIZE, GFP_ATOMIC); | ||
386 | if (!skb) | ||
387 | return ERR_PTR(-ENOMEM); | ||
388 | |||
389 | skb->priority = priority; | ||
390 | |||
391 | lh = (struct l2cap_hdr *)skb_put(skb, L2CAP_HDR_SIZE); | ||
392 | lh->cid = cpu_to_le16(L2CAP_FC_6LOWPAN); | ||
393 | lh->len = cpu_to_le16(len); | ||
394 | |||
395 | err = skbuff_copy(msg, len, count, conn->mtu, skb, dev); | ||
396 | if (unlikely(err < 0)) { | ||
397 | kfree_skb(skb); | ||
398 | BT_DBG("skbuff copy %d failed", err); | ||
399 | return ERR_PTR(err); | ||
400 | } | ||
401 | |||
402 | return skb; | ||
403 | } | ||
404 | |||
405 | static int conn_send(struct l2cap_conn *conn, | ||
406 | void *msg, size_t len, u32 priority, | ||
407 | struct net_device *dev) | ||
408 | { | ||
409 | struct sk_buff *skb; | ||
410 | |||
411 | skb = create_pdu(conn, msg, len, priority, dev); | ||
412 | if (IS_ERR(skb)) | ||
413 | return -EINVAL; | ||
414 | |||
415 | BT_DBG("conn %p skb %p len %d priority %u", conn, skb, skb->len, | ||
416 | skb->priority); | ||
417 | |||
418 | hci_send_acl(conn->hchan, skb, ACL_START); | ||
419 | |||
420 | return 0; | ||
421 | } | ||
422 | |||
423 | static void get_dest_bdaddr(struct in6_addr *ip6_daddr, | ||
424 | bdaddr_t *addr, u8 *addr_type) | ||
425 | { | ||
426 | u8 *eui64; | ||
427 | |||
428 | eui64 = ip6_daddr->s6_addr + 8; | ||
429 | |||
430 | addr->b[0] = eui64[7]; | ||
431 | addr->b[1] = eui64[6]; | ||
432 | addr->b[2] = eui64[5]; | ||
433 | addr->b[3] = eui64[2]; | ||
434 | addr->b[4] = eui64[1]; | ||
435 | addr->b[5] = eui64[0]; | ||
436 | |||
437 | addr->b[5] ^= 2; | ||
438 | |||
439 | /* Set universal/local bit to 0 */ | ||
440 | if (addr->b[5] & 1) { | ||
441 | addr->b[5] &= ~1; | ||
442 | *addr_type = ADDR_LE_DEV_PUBLIC; | ||
443 | } else { | ||
444 | *addr_type = ADDR_LE_DEV_RANDOM; | ||
445 | } | ||
446 | } | ||
447 | |||
448 | static int header_create(struct sk_buff *skb, struct net_device *netdev, | ||
449 | unsigned short type, const void *_daddr, | ||
450 | const void *_saddr, unsigned int len) | ||
451 | { | ||
452 | struct ipv6hdr *hdr; | ||
453 | struct lowpan_dev *dev; | ||
454 | struct lowpan_peer *peer; | ||
455 | bdaddr_t addr, *any = BDADDR_ANY; | ||
456 | u8 *saddr, *daddr = any->b; | ||
457 | u8 addr_type; | ||
458 | |||
459 | if (type != ETH_P_IPV6) | ||
460 | return -EINVAL; | ||
461 | |||
462 | hdr = ipv6_hdr(skb); | ||
463 | |||
464 | dev = lowpan_dev(netdev); | ||
465 | |||
466 | if (ipv6_addr_is_multicast(&hdr->daddr)) { | ||
467 | memcpy(&lowpan_cb(skb)->addr, &hdr->daddr, | ||
468 | sizeof(struct in6_addr)); | ||
469 | lowpan_cb(skb)->conn = NULL; | ||
470 | } else { | ||
471 | unsigned long flags; | ||
472 | |||
473 | /* Get destination BT device from skb. | ||
474 | * If there is no such peer then discard the packet. | ||
475 | */ | ||
476 | get_dest_bdaddr(&hdr->daddr, &addr, &addr_type); | ||
477 | |||
478 | BT_DBG("dest addr %pMR type %d", &addr, addr_type); | ||
479 | |||
480 | read_lock_irqsave(&devices_lock, flags); | ||
481 | peer = peer_lookup_ba(dev, &addr, addr_type); | ||
482 | read_unlock_irqrestore(&devices_lock, flags); | ||
483 | |||
484 | if (!peer) { | ||
485 | BT_DBG("no such peer %pMR found", &addr); | ||
486 | return -ENOENT; | ||
487 | } | ||
488 | |||
489 | daddr = peer->eui64_addr; | ||
490 | |||
491 | memcpy(&lowpan_cb(skb)->addr, &hdr->daddr, | ||
492 | sizeof(struct in6_addr)); | ||
493 | lowpan_cb(skb)->conn = peer->conn; | ||
494 | } | ||
495 | |||
496 | saddr = dev->netdev->dev_addr; | ||
497 | |||
498 | return lowpan_header_compress(skb, netdev, type, daddr, saddr, len); | ||
499 | } | ||
500 | |||
501 | /* Packet to BT LE device */ | ||
502 | static int send_pkt(struct l2cap_conn *conn, const void *saddr, | ||
503 | const void *daddr, struct sk_buff *skb, | ||
504 | struct net_device *netdev) | ||
505 | { | ||
506 | raw_dump_table(__func__, "raw skb data dump before fragmentation", | ||
507 | skb->data, skb->len); | ||
508 | |||
509 | return conn_send(conn, skb->data, skb->len, 0, netdev); | ||
510 | } | ||
511 | |||
512 | static void send_mcast_pkt(struct sk_buff *skb, struct net_device *netdev) | ||
513 | { | ||
514 | struct sk_buff *local_skb; | ||
515 | struct lowpan_dev *entry, *tmp; | ||
516 | unsigned long flags; | ||
517 | |||
518 | read_lock_irqsave(&devices_lock, flags); | ||
519 | |||
520 | list_for_each_entry_safe(entry, tmp, &bt_6lowpan_devices, list) { | ||
521 | struct lowpan_peer *pentry, *ptmp; | ||
522 | struct lowpan_dev *dev; | ||
523 | |||
524 | if (entry->netdev != netdev) | ||
525 | continue; | ||
526 | |||
527 | dev = lowpan_dev(entry->netdev); | ||
528 | |||
529 | list_for_each_entry_safe(pentry, ptmp, &dev->peers, list) { | ||
530 | local_skb = skb_clone(skb, GFP_ATOMIC); | ||
531 | |||
532 | send_pkt(pentry->conn, netdev->dev_addr, | ||
533 | pentry->eui64_addr, local_skb, netdev); | ||
534 | |||
535 | kfree_skb(local_skb); | ||
536 | } | ||
537 | } | ||
538 | |||
539 | read_unlock_irqrestore(&devices_lock, flags); | ||
540 | } | ||
541 | |||
542 | static netdev_tx_t bt_xmit(struct sk_buff *skb, struct net_device *netdev) | ||
543 | { | ||
544 | int err = 0; | ||
545 | unsigned char *eui64_addr; | ||
546 | struct lowpan_dev *dev; | ||
547 | struct lowpan_peer *peer; | ||
548 | bdaddr_t addr; | ||
549 | u8 addr_type; | ||
550 | |||
551 | if (ipv6_addr_is_multicast(&lowpan_cb(skb)->addr)) { | ||
552 | /* We need to send the packet to every device | ||
553 | * behind this interface. | ||
554 | */ | ||
555 | send_mcast_pkt(skb, netdev); | ||
556 | } else { | ||
557 | unsigned long flags; | ||
558 | |||
559 | get_dest_bdaddr(&lowpan_cb(skb)->addr, &addr, &addr_type); | ||
560 | eui64_addr = lowpan_cb(skb)->addr.s6_addr + 8; | ||
561 | dev = lowpan_dev(netdev); | ||
562 | |||
563 | read_lock_irqsave(&devices_lock, flags); | ||
564 | peer = peer_lookup_ba(dev, &addr, addr_type); | ||
565 | read_unlock_irqrestore(&devices_lock, flags); | ||
566 | |||
567 | BT_DBG("xmit from %s to %pMR (%pI6c) peer %p", netdev->name, | ||
568 | &addr, &lowpan_cb(skb)->addr, peer); | ||
569 | |||
570 | if (peer && peer->conn) | ||
571 | err = send_pkt(peer->conn, netdev->dev_addr, | ||
572 | eui64_addr, skb, netdev); | ||
573 | } | ||
574 | dev_kfree_skb(skb); | ||
575 | |||
576 | if (err) | ||
577 | BT_DBG("ERROR: xmit failed (%d)", err); | ||
578 | |||
579 | return (err < 0) ? NET_XMIT_DROP : err; | ||
580 | } | ||
581 | |||
582 | static const struct net_device_ops netdev_ops = { | ||
583 | .ndo_start_xmit = bt_xmit, | ||
584 | }; | ||
585 | |||
586 | static struct header_ops header_ops = { | ||
587 | .create = header_create, | ||
588 | }; | ||
589 | |||
590 | static void netdev_setup(struct net_device *dev) | ||
591 | { | ||
592 | dev->addr_len = EUI64_ADDR_LEN; | ||
593 | dev->type = ARPHRD_6LOWPAN; | ||
594 | |||
595 | dev->hard_header_len = 0; | ||
596 | dev->needed_tailroom = 0; | ||
597 | dev->mtu = IPV6_MIN_MTU; | ||
598 | dev->tx_queue_len = 0; | ||
599 | dev->flags = IFF_RUNNING | IFF_POINTOPOINT; | ||
600 | dev->watchdog_timeo = 0; | ||
601 | |||
602 | dev->netdev_ops = &netdev_ops; | ||
603 | dev->header_ops = &header_ops; | ||
604 | dev->destructor = free_netdev; | ||
605 | } | ||
606 | |||
607 | static struct device_type bt_type = { | ||
608 | .name = "bluetooth", | ||
609 | }; | ||
610 | |||
611 | static void set_addr(u8 *eui, u8 *addr, u8 addr_type) | ||
612 | { | ||
613 | /* addr is the BT address in little-endian format */ | ||
614 | eui[0] = addr[5]; | ||
615 | eui[1] = addr[4]; | ||
616 | eui[2] = addr[3]; | ||
617 | eui[3] = 0xFF; | ||
618 | eui[4] = 0xFE; | ||
619 | eui[5] = addr[2]; | ||
620 | eui[6] = addr[1]; | ||
621 | eui[7] = addr[0]; | ||
622 | |||
623 | eui[0] ^= 2; | ||
624 | |||
625 | /* Universal/local bit set, RFC 4291 */ | ||
626 | if (addr_type == ADDR_LE_DEV_PUBLIC) | ||
627 | eui[0] |= 1; | ||
628 | else | ||
629 | eui[0] &= ~1; | ||
630 | } | ||
631 | |||
632 | static void set_dev_addr(struct net_device *netdev, bdaddr_t *addr, | ||
633 | u8 addr_type) | ||
634 | { | ||
635 | netdev->addr_assign_type = NET_ADDR_PERM; | ||
636 | set_addr(netdev->dev_addr, addr->b, addr_type); | ||
637 | netdev->dev_addr[0] ^= 2; | ||
638 | } | ||
639 | |||
640 | static void ifup(struct net_device *netdev) | ||
641 | { | ||
642 | int err; | ||
643 | |||
644 | rtnl_lock(); | ||
645 | err = dev_open(netdev); | ||
646 | if (err < 0) | ||
647 | BT_INFO("iface %s cannot be opened (%d)", netdev->name, err); | ||
648 | rtnl_unlock(); | ||
649 | } | ||
650 | |||
651 | static void do_notify_peers(struct work_struct *work) | ||
652 | { | ||
653 | struct lowpan_dev *dev = container_of(work, struct lowpan_dev, | ||
654 | notify_peers.work); | ||
655 | |||
656 | netdev_notify_peers(dev->netdev); /* send neighbour adv at startup */ | ||
657 | } | ||
658 | |||
659 | static bool is_bt_6lowpan(struct hci_conn *hcon) | ||
660 | { | ||
661 | if (hcon->type != LE_LINK) | ||
662 | return false; | ||
663 | |||
664 | return test_bit(HCI_CONN_6LOWPAN, &hcon->flags); | ||
665 | } | ||
666 | |||
667 | static int add_peer_conn(struct l2cap_conn *conn, struct lowpan_dev *dev) | ||
668 | { | ||
669 | struct lowpan_peer *peer; | ||
670 | unsigned long flags; | ||
671 | |||
672 | peer = kzalloc(sizeof(*peer), GFP_ATOMIC); | ||
673 | if (!peer) | ||
674 | return -ENOMEM; | ||
675 | |||
676 | peer->conn = conn; | ||
677 | memset(&peer->peer_addr, 0, sizeof(struct in6_addr)); | ||
678 | |||
679 | /* RFC 2464 ch. 5 */ | ||
680 | peer->peer_addr.s6_addr[0] = 0xFE; | ||
681 | peer->peer_addr.s6_addr[1] = 0x80; | ||
682 | set_addr((u8 *)&peer->peer_addr.s6_addr + 8, conn->hcon->dst.b, | ||
683 | conn->hcon->dst_type); | ||
684 | |||
685 | memcpy(&peer->eui64_addr, (u8 *)&peer->peer_addr.s6_addr + 8, | ||
686 | EUI64_ADDR_LEN); | ||
687 | peer->eui64_addr[0] ^= 2; /* second bit-flip (Universe/Local) | ||
688 | * is done according RFC2464 | ||
689 | */ | ||
690 | |||
691 | raw_dump_inline(__func__, "peer IPv6 address", | ||
692 | (unsigned char *)&peer->peer_addr, 16); | ||
693 | raw_dump_inline(__func__, "peer EUI64 address", peer->eui64_addr, 8); | ||
694 | |||
695 | write_lock_irqsave(&devices_lock, flags); | ||
696 | INIT_LIST_HEAD(&peer->list); | ||
697 | peer_add(dev, peer); | ||
698 | write_unlock_irqrestore(&devices_lock, flags); | ||
699 | |||
700 | /* Notifying peers about us needs to be done without locks held */ | ||
701 | INIT_DELAYED_WORK(&dev->notify_peers, do_notify_peers); | ||
702 | schedule_delayed_work(&dev->notify_peers, msecs_to_jiffies(100)); | ||
703 | |||
704 | return 0; | ||
705 | } | ||
706 | |||
707 | /* This gets called when BT LE 6LoWPAN device is connected. We then | ||
708 | * create network device that acts as a proxy between BT LE device | ||
709 | * and kernel network stack. | ||
710 | */ | ||
711 | int bt_6lowpan_add_conn(struct l2cap_conn *conn) | ||
712 | { | ||
713 | struct lowpan_peer *peer = NULL; | ||
714 | struct lowpan_dev *dev; | ||
715 | struct net_device *netdev; | ||
716 | int err = 0; | ||
717 | unsigned long flags; | ||
718 | |||
719 | if (!is_bt_6lowpan(conn->hcon)) | ||
720 | return 0; | ||
721 | |||
722 | peer = lookup_peer(conn); | ||
723 | if (peer) | ||
724 | return -EEXIST; | ||
725 | |||
726 | dev = lookup_dev(conn); | ||
727 | if (dev) | ||
728 | return add_peer_conn(conn, dev); | ||
729 | |||
730 | netdev = alloc_netdev(sizeof(*dev), IFACE_NAME_TEMPLATE, netdev_setup); | ||
731 | if (!netdev) | ||
732 | return -ENOMEM; | ||
733 | |||
734 | set_dev_addr(netdev, &conn->hcon->src, conn->hcon->src_type); | ||
735 | |||
736 | netdev->netdev_ops = &netdev_ops; | ||
737 | SET_NETDEV_DEV(netdev, &conn->hcon->dev); | ||
738 | SET_NETDEV_DEVTYPE(netdev, &bt_type); | ||
739 | |||
740 | err = register_netdev(netdev); | ||
741 | if (err < 0) { | ||
742 | BT_INFO("register_netdev failed %d", err); | ||
743 | free_netdev(netdev); | ||
744 | goto out; | ||
745 | } | ||
746 | |||
747 | BT_DBG("ifindex %d peer bdaddr %pMR my addr %pMR", | ||
748 | netdev->ifindex, &conn->hcon->dst, &conn->hcon->src); | ||
749 | set_bit(__LINK_STATE_PRESENT, &netdev->state); | ||
750 | |||
751 | dev = netdev_priv(netdev); | ||
752 | dev->netdev = netdev; | ||
753 | dev->hdev = conn->hcon->hdev; | ||
754 | INIT_LIST_HEAD(&dev->peers); | ||
755 | |||
756 | write_lock_irqsave(&devices_lock, flags); | ||
757 | INIT_LIST_HEAD(&dev->list); | ||
758 | list_add(&dev->list, &bt_6lowpan_devices); | ||
759 | write_unlock_irqrestore(&devices_lock, flags); | ||
760 | |||
761 | ifup(netdev); | ||
762 | |||
763 | return add_peer_conn(conn, dev); | ||
764 | |||
765 | out: | ||
766 | return err; | ||
767 | } | ||
768 | |||
769 | static void delete_netdev(struct work_struct *work) | ||
770 | { | ||
771 | struct lowpan_dev *entry = container_of(work, struct lowpan_dev, | ||
772 | delete_netdev); | ||
773 | |||
774 | unregister_netdev(entry->netdev); | ||
775 | |||
776 | /* The entry pointer is deleted in device_event() */ | ||
777 | } | ||
778 | |||
779 | int bt_6lowpan_del_conn(struct l2cap_conn *conn) | ||
780 | { | ||
781 | struct lowpan_dev *entry, *tmp; | ||
782 | struct lowpan_dev *dev = NULL; | ||
783 | struct lowpan_peer *peer; | ||
784 | int err = -ENOENT; | ||
785 | unsigned long flags; | ||
786 | bool last = false; | ||
787 | |||
788 | if (!conn || !is_bt_6lowpan(conn->hcon)) | ||
789 | return 0; | ||
790 | |||
791 | write_lock_irqsave(&devices_lock, flags); | ||
792 | |||
793 | list_for_each_entry_safe(entry, tmp, &bt_6lowpan_devices, list) { | ||
794 | dev = lowpan_dev(entry->netdev); | ||
795 | peer = peer_lookup_conn(dev, conn); | ||
796 | if (peer) { | ||
797 | last = peer_del(dev, peer); | ||
798 | err = 0; | ||
799 | break; | ||
800 | } | ||
801 | } | ||
802 | |||
803 | if (!err && last && dev && !atomic_read(&dev->peer_count)) { | ||
804 | write_unlock_irqrestore(&devices_lock, flags); | ||
805 | |||
806 | cancel_delayed_work_sync(&dev->notify_peers); | ||
807 | |||
808 | /* bt_6lowpan_del_conn() is called with hci dev lock held which | ||
809 | * means that we must delete the netdevice in worker thread. | ||
810 | */ | ||
811 | INIT_WORK(&entry->delete_netdev, delete_netdev); | ||
812 | schedule_work(&entry->delete_netdev); | ||
813 | } else { | ||
814 | write_unlock_irqrestore(&devices_lock, flags); | ||
815 | } | ||
816 | |||
817 | return err; | ||
818 | } | ||
819 | |||
820 | static int device_event(struct notifier_block *unused, | ||
821 | unsigned long event, void *ptr) | ||
822 | { | ||
823 | struct net_device *netdev = netdev_notifier_info_to_dev(ptr); | ||
824 | struct lowpan_dev *entry, *tmp; | ||
825 | unsigned long flags; | ||
826 | |||
827 | if (netdev->type != ARPHRD_6LOWPAN) | ||
828 | return NOTIFY_DONE; | ||
829 | |||
830 | switch (event) { | ||
831 | case NETDEV_UNREGISTER: | ||
832 | write_lock_irqsave(&devices_lock, flags); | ||
833 | list_for_each_entry_safe(entry, tmp, &bt_6lowpan_devices, | ||
834 | list) { | ||
835 | if (entry->netdev == netdev) { | ||
836 | list_del(&entry->list); | ||
837 | kfree(entry); | ||
838 | break; | ||
839 | } | ||
840 | } | ||
841 | write_unlock_irqrestore(&devices_lock, flags); | ||
842 | break; | ||
843 | } | ||
844 | |||
845 | return NOTIFY_DONE; | ||
846 | } | ||
847 | |||
848 | static struct notifier_block bt_6lowpan_dev_notifier = { | ||
849 | .notifier_call = device_event, | ||
850 | }; | ||
851 | |||
852 | int bt_6lowpan_init(void) | ||
853 | { | ||
854 | return register_netdevice_notifier(&bt_6lowpan_dev_notifier); | ||
855 | } | ||
856 | |||
857 | void bt_6lowpan_cleanup(void) | ||
858 | { | ||
859 | unregister_netdevice_notifier(&bt_6lowpan_dev_notifier); | ||
860 | } | ||
diff --git a/net/bluetooth/6lowpan.h b/net/bluetooth/6lowpan.h new file mode 100644 index 000000000000..680eac808d74 --- /dev/null +++ b/net/bluetooth/6lowpan.h | |||
@@ -0,0 +1,26 @@ | |||
1 | /* | ||
2 | Copyright (c) 2013 Intel Corp. | ||
3 | |||
4 | This program is free software; you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Public License version 2 and | ||
6 | only version 2 as published by the Free Software Foundation. | ||
7 | |||
8 | This program is distributed in the hope that it will be useful, | ||
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | GNU General Public License for more details. | ||
12 | */ | ||
13 | |||
14 | #ifndef __6LOWPAN_H | ||
15 | #define __6LOWPAN_H | ||
16 | |||
17 | #include <linux/skbuff.h> | ||
18 | #include <net/bluetooth/l2cap.h> | ||
19 | |||
20 | int bt_6lowpan_recv(struct l2cap_conn *conn, struct sk_buff *skb); | ||
21 | int bt_6lowpan_add_conn(struct l2cap_conn *conn); | ||
22 | int bt_6lowpan_del_conn(struct l2cap_conn *conn); | ||
23 | int bt_6lowpan_init(void); | ||
24 | void bt_6lowpan_cleanup(void); | ||
25 | |||
26 | #endif /* __6LOWPAN_H */ | ||
diff --git a/net/bluetooth/Makefile b/net/bluetooth/Makefile index 6a791e73e39d..cc6827e2ce68 100644 --- a/net/bluetooth/Makefile +++ b/net/bluetooth/Makefile | |||
@@ -10,6 +10,10 @@ obj-$(CONFIG_BT_HIDP) += hidp/ | |||
10 | 10 | ||
11 | bluetooth-y := af_bluetooth.o hci_core.o hci_conn.o hci_event.o mgmt.o \ | 11 | bluetooth-y := af_bluetooth.o hci_core.o hci_conn.o hci_event.o mgmt.o \ |
12 | hci_sock.o hci_sysfs.o l2cap_core.o l2cap_sock.o smp.o sco.o lib.o \ | 12 | hci_sock.o hci_sysfs.o l2cap_core.o l2cap_sock.o smp.o sco.o lib.o \ |
13 | a2mp.o amp.o | 13 | a2mp.o amp.o 6lowpan.o |
14 | |||
15 | ifeq ($(CONFIG_IEEE802154_6LOWPAN),) | ||
16 | bluetooth-y += ../ieee802154/6lowpan_iphc.o | ||
17 | endif | ||
14 | 18 | ||
15 | subdir-ccflags-y += -D__CHECK_ENDIAN__ | 19 | subdir-ccflags-y += -D__CHECK_ENDIAN__ |
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 8b8b5f80dd89..5e8663c194c1 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c | |||
@@ -636,6 +636,49 @@ static int conn_max_interval_get(void *data, u64 *val) | |||
636 | DEFINE_SIMPLE_ATTRIBUTE(conn_max_interval_fops, conn_max_interval_get, | 636 | DEFINE_SIMPLE_ATTRIBUTE(conn_max_interval_fops, conn_max_interval_get, |
637 | conn_max_interval_set, "%llu\n"); | 637 | conn_max_interval_set, "%llu\n"); |
638 | 638 | ||
639 | static ssize_t lowpan_read(struct file *file, char __user *user_buf, | ||
640 | size_t count, loff_t *ppos) | ||
641 | { | ||
642 | struct hci_dev *hdev = file->private_data; | ||
643 | char buf[3]; | ||
644 | |||
645 | buf[0] = test_bit(HCI_6LOWPAN_ENABLED, &hdev->dev_flags) ? 'Y' : 'N'; | ||
646 | buf[1] = '\n'; | ||
647 | buf[2] = '\0'; | ||
648 | return simple_read_from_buffer(user_buf, count, ppos, buf, 2); | ||
649 | } | ||
650 | |||
651 | static ssize_t lowpan_write(struct file *fp, const char __user *user_buffer, | ||
652 | size_t count, loff_t *position) | ||
653 | { | ||
654 | struct hci_dev *hdev = fp->private_data; | ||
655 | bool enable; | ||
656 | char buf[32]; | ||
657 | size_t buf_size = min(count, (sizeof(buf)-1)); | ||
658 | |||
659 | if (copy_from_user(buf, user_buffer, buf_size)) | ||
660 | return -EFAULT; | ||
661 | |||
662 | buf[buf_size] = '\0'; | ||
663 | |||
664 | if (strtobool(buf, &enable) < 0) | ||
665 | return -EINVAL; | ||
666 | |||
667 | if (enable == test_bit(HCI_6LOWPAN_ENABLED, &hdev->dev_flags)) | ||
668 | return -EALREADY; | ||
669 | |||
670 | change_bit(HCI_6LOWPAN_ENABLED, &hdev->dev_flags); | ||
671 | |||
672 | return count; | ||
673 | } | ||
674 | |||
675 | static const struct file_operations lowpan_debugfs_fops = { | ||
676 | .open = simple_open, | ||
677 | .read = lowpan_read, | ||
678 | .write = lowpan_write, | ||
679 | .llseek = default_llseek, | ||
680 | }; | ||
681 | |||
639 | /* ---- HCI requests ---- */ | 682 | /* ---- HCI requests ---- */ |
640 | 683 | ||
641 | static void hci_req_sync_complete(struct hci_dev *hdev, u8 result) | 684 | static void hci_req_sync_complete(struct hci_dev *hdev, u8 result) |
@@ -1261,8 +1304,13 @@ static void hci_init3_req(struct hci_request *req, unsigned long opt) | |||
1261 | * as supported send it. If not supported assume that the controller | 1304 | * as supported send it. If not supported assume that the controller |
1262 | * does not have actual support for stored link keys which makes this | 1305 | * does not have actual support for stored link keys which makes this |
1263 | * command redundant anyway. | 1306 | * command redundant anyway. |
1307 | * | ||
1308 | * Some controllers indicate that they support handling deleting | ||
1309 | * stored link keys, but they don't. The quirk lets a driver | ||
1310 | * just disable this command. | ||
1264 | */ | 1311 | */ |
1265 | if (hdev->commands[6] & 0x80) { | 1312 | if (hdev->commands[6] & 0x80 && |
1313 | !test_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks)) { | ||
1266 | struct hci_cp_delete_stored_link_key cp; | 1314 | struct hci_cp_delete_stored_link_key cp; |
1267 | 1315 | ||
1268 | bacpy(&cp.bdaddr, BDADDR_ANY); | 1316 | bacpy(&cp.bdaddr, BDADDR_ANY); |
@@ -1406,6 +1454,8 @@ static int __hci_init(struct hci_dev *hdev) | |||
1406 | hdev, &conn_min_interval_fops); | 1454 | hdev, &conn_min_interval_fops); |
1407 | debugfs_create_file("conn_max_interval", 0644, hdev->debugfs, | 1455 | debugfs_create_file("conn_max_interval", 0644, hdev->debugfs, |
1408 | hdev, &conn_max_interval_fops); | 1456 | hdev, &conn_max_interval_fops); |
1457 | debugfs_create_file("6lowpan", 0644, hdev->debugfs, hdev, | ||
1458 | &lowpan_debugfs_fops); | ||
1409 | } | 1459 | } |
1410 | 1460 | ||
1411 | return 0; | 1461 | return 0; |
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 5fb3df66c2cd..5f812455a450 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -3533,6 +3533,9 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
3533 | conn->handle = __le16_to_cpu(ev->handle); | 3533 | conn->handle = __le16_to_cpu(ev->handle); |
3534 | conn->state = BT_CONNECTED; | 3534 | conn->state = BT_CONNECTED; |
3535 | 3535 | ||
3536 | if (test_bit(HCI_6LOWPAN_ENABLED, &hdev->dev_flags)) | ||
3537 | set_bit(HCI_CONN_6LOWPAN, &conn->flags); | ||
3538 | |||
3536 | hci_conn_add_sysfs(conn); | 3539 | hci_conn_add_sysfs(conn); |
3537 | 3540 | ||
3538 | hci_proto_connect_cfm(conn, ev->status); | 3541 | hci_proto_connect_cfm(conn, ev->status); |
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index b6bca64b320d..b0ad2c752d73 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include "smp.h" | 40 | #include "smp.h" |
41 | #include "a2mp.h" | 41 | #include "a2mp.h" |
42 | #include "amp.h" | 42 | #include "amp.h" |
43 | #include "6lowpan.h" | ||
43 | 44 | ||
44 | bool disable_ertm; | 45 | bool disable_ertm; |
45 | 46 | ||
@@ -1468,6 +1469,8 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn) | |||
1468 | 1469 | ||
1469 | BT_DBG(""); | 1470 | BT_DBG(""); |
1470 | 1471 | ||
1472 | bt_6lowpan_add_conn(conn); | ||
1473 | |||
1471 | /* Check if we have socket listening on cid */ | 1474 | /* Check if we have socket listening on cid */ |
1472 | pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_ATT, | 1475 | pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_ATT, |
1473 | &hcon->src, &hcon->dst); | 1476 | &hcon->src, &hcon->dst); |
@@ -7119,6 +7122,10 @@ static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb) | |||
7119 | l2cap_conn_del(conn->hcon, EACCES); | 7122 | l2cap_conn_del(conn->hcon, EACCES); |
7120 | break; | 7123 | break; |
7121 | 7124 | ||
7125 | case L2CAP_FC_6LOWPAN: | ||
7126 | bt_6lowpan_recv(conn, skb); | ||
7127 | break; | ||
7128 | |||
7122 | default: | 7129 | default: |
7123 | l2cap_data_channel(conn, cid, skb); | 7130 | l2cap_data_channel(conn, cid, skb); |
7124 | break; | 7131 | break; |
@@ -7186,6 +7193,8 @@ void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason) | |||
7186 | { | 7193 | { |
7187 | BT_DBG("hcon %p reason %d", hcon, reason); | 7194 | BT_DBG("hcon %p reason %d", hcon, reason); |
7188 | 7195 | ||
7196 | bt_6lowpan_del_conn(hcon->l2cap_data); | ||
7197 | |||
7189 | l2cap_conn_del(hcon, bt_to_errno(reason)); | 7198 | l2cap_conn_del(hcon, bt_to_errno(reason)); |
7190 | } | 7199 | } |
7191 | 7200 | ||
@@ -7467,11 +7476,14 @@ int __init l2cap_init(void) | |||
7467 | debugfs_create_u16("l2cap_le_default_mps", 0466, bt_debugfs, | 7476 | debugfs_create_u16("l2cap_le_default_mps", 0466, bt_debugfs, |
7468 | &le_default_mps); | 7477 | &le_default_mps); |
7469 | 7478 | ||
7479 | bt_6lowpan_init(); | ||
7480 | |||
7470 | return 0; | 7481 | return 0; |
7471 | } | 7482 | } |
7472 | 7483 | ||
7473 | void l2cap_exit(void) | 7484 | void l2cap_exit(void) |
7474 | { | 7485 | { |
7486 | bt_6lowpan_cleanup(); | ||
7475 | debugfs_remove(l2cap_debugfs); | 7487 | debugfs_remove(l2cap_debugfs); |
7476 | l2cap_cleanup_sockets(); | 7488 | l2cap_cleanup_sockets(); |
7477 | } | 7489 | } |
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index e7806e6d282c..20ef748b2906 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c | |||
@@ -147,6 +147,9 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) | |||
147 | __le16_to_cpu(la.l2_psm) == L2CAP_PSM_RFCOMM) | 147 | __le16_to_cpu(la.l2_psm) == L2CAP_PSM_RFCOMM) |
148 | chan->sec_level = BT_SECURITY_SDP; | 148 | chan->sec_level = BT_SECURITY_SDP; |
149 | break; | 149 | break; |
150 | case L2CAP_CHAN_RAW: | ||
151 | chan->sec_level = BT_SECURITY_SDP; | ||
152 | break; | ||
150 | } | 153 | } |
151 | 154 | ||
152 | bacpy(&chan->src, &la.l2_bdaddr); | 155 | bacpy(&chan->src, &la.l2_bdaddr); |
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c index 84fcf9fff3ea..f9c0980abeea 100644 --- a/net/bluetooth/rfcomm/tty.c +++ b/net/bluetooth/rfcomm/tty.c | |||
@@ -58,6 +58,7 @@ struct rfcomm_dev { | |||
58 | uint modem_status; | 58 | uint modem_status; |
59 | 59 | ||
60 | struct rfcomm_dlc *dlc; | 60 | struct rfcomm_dlc *dlc; |
61 | wait_queue_head_t conn_wait; | ||
61 | 62 | ||
62 | struct device *tty_dev; | 63 | struct device *tty_dev; |
63 | 64 | ||
@@ -103,20 +104,60 @@ static void rfcomm_dev_destruct(struct tty_port *port) | |||
103 | module_put(THIS_MODULE); | 104 | module_put(THIS_MODULE); |
104 | } | 105 | } |
105 | 106 | ||
106 | /* device-specific initialization: open the dlc */ | 107 | static struct device *rfcomm_get_device(struct rfcomm_dev *dev) |
107 | static int rfcomm_dev_activate(struct tty_port *port, struct tty_struct *tty) | ||
108 | { | 108 | { |
109 | struct rfcomm_dev *dev = container_of(port, struct rfcomm_dev, port); | 109 | struct hci_dev *hdev; |
110 | struct hci_conn *conn; | ||
110 | 111 | ||
111 | return rfcomm_dlc_open(dev->dlc, &dev->src, &dev->dst, dev->channel); | 112 | hdev = hci_get_route(&dev->dst, &dev->src); |
113 | if (!hdev) | ||
114 | return NULL; | ||
115 | |||
116 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &dev->dst); | ||
117 | |||
118 | hci_dev_put(hdev); | ||
119 | |||
120 | return conn ? &conn->dev : NULL; | ||
112 | } | 121 | } |
113 | 122 | ||
114 | /* we block the open until the dlc->state becomes BT_CONNECTED */ | 123 | /* device-specific initialization: open the dlc */ |
115 | static int rfcomm_dev_carrier_raised(struct tty_port *port) | 124 | static int rfcomm_dev_activate(struct tty_port *port, struct tty_struct *tty) |
116 | { | 125 | { |
117 | struct rfcomm_dev *dev = container_of(port, struct rfcomm_dev, port); | 126 | struct rfcomm_dev *dev = container_of(port, struct rfcomm_dev, port); |
127 | DEFINE_WAIT(wait); | ||
128 | int err; | ||
129 | |||
130 | err = rfcomm_dlc_open(dev->dlc, &dev->src, &dev->dst, dev->channel); | ||
131 | if (err) | ||
132 | return err; | ||
133 | |||
134 | while (1) { | ||
135 | prepare_to_wait(&dev->conn_wait, &wait, TASK_INTERRUPTIBLE); | ||
136 | |||
137 | if (dev->dlc->state == BT_CLOSED) { | ||
138 | err = -dev->err; | ||
139 | break; | ||
140 | } | ||
141 | |||
142 | if (dev->dlc->state == BT_CONNECTED) | ||
143 | break; | ||
144 | |||
145 | if (signal_pending(current)) { | ||
146 | err = -ERESTARTSYS; | ||
147 | break; | ||
148 | } | ||
149 | |||
150 | tty_unlock(tty); | ||
151 | schedule(); | ||
152 | tty_lock(tty); | ||
153 | } | ||
154 | finish_wait(&dev->conn_wait, &wait); | ||
155 | |||
156 | if (!err) | ||
157 | device_move(dev->tty_dev, rfcomm_get_device(dev), | ||
158 | DPM_ORDER_DEV_AFTER_PARENT); | ||
118 | 159 | ||
119 | return (dev->dlc->state == BT_CONNECTED); | 160 | return err; |
120 | } | 161 | } |
121 | 162 | ||
122 | /* device-specific cleanup: close the dlc */ | 163 | /* device-specific cleanup: close the dlc */ |
@@ -135,7 +176,6 @@ static const struct tty_port_operations rfcomm_port_ops = { | |||
135 | .destruct = rfcomm_dev_destruct, | 176 | .destruct = rfcomm_dev_destruct, |
136 | .activate = rfcomm_dev_activate, | 177 | .activate = rfcomm_dev_activate, |
137 | .shutdown = rfcomm_dev_shutdown, | 178 | .shutdown = rfcomm_dev_shutdown, |
138 | .carrier_raised = rfcomm_dev_carrier_raised, | ||
139 | }; | 179 | }; |
140 | 180 | ||
141 | static struct rfcomm_dev *__rfcomm_dev_get(int id) | 181 | static struct rfcomm_dev *__rfcomm_dev_get(int id) |
@@ -169,22 +209,6 @@ static struct rfcomm_dev *rfcomm_dev_get(int id) | |||
169 | return dev; | 209 | return dev; |
170 | } | 210 | } |
171 | 211 | ||
172 | static struct device *rfcomm_get_device(struct rfcomm_dev *dev) | ||
173 | { | ||
174 | struct hci_dev *hdev; | ||
175 | struct hci_conn *conn; | ||
176 | |||
177 | hdev = hci_get_route(&dev->dst, &dev->src); | ||
178 | if (!hdev) | ||
179 | return NULL; | ||
180 | |||
181 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &dev->dst); | ||
182 | |||
183 | hci_dev_put(hdev); | ||
184 | |||
185 | return conn ? &conn->dev : NULL; | ||
186 | } | ||
187 | |||
188 | static ssize_t show_address(struct device *tty_dev, struct device_attribute *attr, char *buf) | 212 | static ssize_t show_address(struct device *tty_dev, struct device_attribute *attr, char *buf) |
189 | { | 213 | { |
190 | struct rfcomm_dev *dev = dev_get_drvdata(tty_dev); | 214 | struct rfcomm_dev *dev = dev_get_drvdata(tty_dev); |
@@ -258,6 +282,7 @@ static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc) | |||
258 | 282 | ||
259 | tty_port_init(&dev->port); | 283 | tty_port_init(&dev->port); |
260 | dev->port.ops = &rfcomm_port_ops; | 284 | dev->port.ops = &rfcomm_port_ops; |
285 | init_waitqueue_head(&dev->conn_wait); | ||
261 | 286 | ||
262 | skb_queue_head_init(&dev->pending); | 287 | skb_queue_head_init(&dev->pending); |
263 | 288 | ||
@@ -437,7 +462,8 @@ static int rfcomm_release_dev(void __user *arg) | |||
437 | tty_kref_put(tty); | 462 | tty_kref_put(tty); |
438 | } | 463 | } |
439 | 464 | ||
440 | if (!test_and_set_bit(RFCOMM_TTY_RELEASED, &dev->flags)) | 465 | if (!test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags) && |
466 | !test_and_set_bit(RFCOMM_TTY_RELEASED, &dev->flags)) | ||
441 | tty_port_put(&dev->port); | 467 | tty_port_put(&dev->port); |
442 | 468 | ||
443 | tty_port_put(&dev->port); | 469 | tty_port_put(&dev->port); |
@@ -575,12 +601,9 @@ static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err) | |||
575 | BT_DBG("dlc %p dev %p err %d", dlc, dev, err); | 601 | BT_DBG("dlc %p dev %p err %d", dlc, dev, err); |
576 | 602 | ||
577 | dev->err = err; | 603 | dev->err = err; |
578 | if (dlc->state == BT_CONNECTED) { | 604 | wake_up_interruptible(&dev->conn_wait); |
579 | device_move(dev->tty_dev, rfcomm_get_device(dev), | ||
580 | DPM_ORDER_DEV_AFTER_PARENT); | ||
581 | 605 | ||
582 | wake_up_interruptible(&dev->port.open_wait); | 606 | if (dlc->state == BT_CLOSED) |
583 | } else if (dlc->state == BT_CLOSED) | ||
584 | tty_port_tty_hangup(&dev->port, false); | 607 | tty_port_tty_hangup(&dev->port, false); |
585 | } | 608 | } |
586 | 609 | ||
@@ -670,10 +693,20 @@ static int rfcomm_tty_install(struct tty_driver *driver, struct tty_struct *tty) | |||
670 | 693 | ||
671 | /* install the tty_port */ | 694 | /* install the tty_port */ |
672 | err = tty_port_install(&dev->port, driver, tty); | 695 | err = tty_port_install(&dev->port, driver, tty); |
673 | if (err) | 696 | if (err) { |
674 | rfcomm_tty_cleanup(tty); | 697 | rfcomm_tty_cleanup(tty); |
698 | return err; | ||
699 | } | ||
675 | 700 | ||
676 | return err; | 701 | /* take over the tty_port reference if the port was created with the |
702 | * flag RFCOMM_RELEASE_ONHUP. This will force the release of the port | ||
703 | * when the last process closes the tty. The behaviour is expected by | ||
704 | * userspace. | ||
705 | */ | ||
706 | if (test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags)) | ||
707 | tty_port_put(&dev->port); | ||
708 | |||
709 | return 0; | ||
677 | } | 710 | } |
678 | 711 | ||
679 | static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp) | 712 | static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp) |
@@ -1010,10 +1043,6 @@ static void rfcomm_tty_hangup(struct tty_struct *tty) | |||
1010 | BT_DBG("tty %p dev %p", tty, dev); | 1043 | BT_DBG("tty %p dev %p", tty, dev); |
1011 | 1044 | ||
1012 | tty_port_hangup(&dev->port); | 1045 | tty_port_hangup(&dev->port); |
1013 | |||
1014 | if (test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags) && | ||
1015 | !test_and_set_bit(RFCOMM_TTY_RELEASED, &dev->flags)) | ||
1016 | tty_port_put(&dev->port); | ||
1017 | } | 1046 | } |
1018 | 1047 | ||
1019 | static int rfcomm_tty_tiocmget(struct tty_struct *tty) | 1048 | static int rfcomm_tty_tiocmget(struct tty_struct *tty) |
@@ -1096,7 +1125,7 @@ int __init rfcomm_init_ttys(void) | |||
1096 | rfcomm_tty_driver->subtype = SERIAL_TYPE_NORMAL; | 1125 | rfcomm_tty_driver->subtype = SERIAL_TYPE_NORMAL; |
1097 | rfcomm_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; | 1126 | rfcomm_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; |
1098 | rfcomm_tty_driver->init_termios = tty_std_termios; | 1127 | rfcomm_tty_driver->init_termios = tty_std_termios; |
1099 | rfcomm_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL; | 1128 | rfcomm_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; |
1100 | rfcomm_tty_driver->init_termios.c_lflag &= ~ICANON; | 1129 | rfcomm_tty_driver->init_termios.c_lflag &= ~ICANON; |
1101 | tty_set_operations(rfcomm_tty_driver, &rfcomm_ops); | 1130 | tty_set_operations(rfcomm_tty_driver, &rfcomm_ops); |
1102 | 1131 | ||
diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c index a2d2456a557a..48b25c0af4d0 100644 --- a/net/ieee802154/6lowpan.c +++ b/net/ieee802154/6lowpan.c | |||
@@ -62,9 +62,6 @@ | |||
62 | 62 | ||
63 | #include "6lowpan.h" | 63 | #include "6lowpan.h" |
64 | 64 | ||
65 | /* TTL uncompression values */ | ||
66 | static const u8 lowpan_ttl_values[] = {0, 1, 64, 255}; | ||
67 | |||
68 | static LIST_HEAD(lowpan_devices); | 65 | static LIST_HEAD(lowpan_devices); |
69 | 66 | ||
70 | /* private device info */ | 67 | /* private device info */ |
@@ -104,378 +101,14 @@ static inline void lowpan_address_flip(u8 *src, u8 *dest) | |||
104 | (dest)[IEEE802154_ADDR_LEN - i - 1] = (src)[i]; | 101 | (dest)[IEEE802154_ADDR_LEN - i - 1] = (src)[i]; |
105 | } | 102 | } |
106 | 103 | ||
107 | /* list of all 6lowpan devices, uses for package delivering */ | ||
108 | /* print data in line */ | ||
109 | static inline void lowpan_raw_dump_inline(const char *caller, char *msg, | ||
110 | unsigned char *buf, int len) | ||
111 | { | ||
112 | #ifdef DEBUG | ||
113 | if (msg) | ||
114 | pr_debug("(%s) %s: ", caller, msg); | ||
115 | print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_NONE, | ||
116 | 16, 1, buf, len, false); | ||
117 | #endif /* DEBUG */ | ||
118 | } | ||
119 | |||
120 | /* | ||
121 | * print data in a table format: | ||
122 | * | ||
123 | * addr: xx xx xx xx xx xx | ||
124 | * addr: xx xx xx xx xx xx | ||
125 | * ... | ||
126 | */ | ||
127 | static inline void lowpan_raw_dump_table(const char *caller, char *msg, | ||
128 | unsigned char *buf, int len) | ||
129 | { | ||
130 | #ifdef DEBUG | ||
131 | if (msg) | ||
132 | pr_debug("(%s) %s:\n", caller, msg); | ||
133 | print_hex_dump(KERN_DEBUG, "\t", DUMP_PREFIX_OFFSET, | ||
134 | 16, 1, buf, len, false); | ||
135 | #endif /* DEBUG */ | ||
136 | } | ||
137 | |||
138 | static u8 | ||
139 | lowpan_compress_addr_64(u8 **hc06_ptr, u8 shift, const struct in6_addr *ipaddr, | ||
140 | const unsigned char *lladdr) | ||
141 | { | ||
142 | u8 val = 0; | ||
143 | |||
144 | if (is_addr_mac_addr_based(ipaddr, lladdr)) | ||
145 | val = 3; /* 0-bits */ | ||
146 | else if (lowpan_is_iid_16_bit_compressable(ipaddr)) { | ||
147 | /* compress IID to 16 bits xxxx::XXXX */ | ||
148 | memcpy(*hc06_ptr, &ipaddr->s6_addr16[7], 2); | ||
149 | *hc06_ptr += 2; | ||
150 | val = 2; /* 16-bits */ | ||
151 | } else { | ||
152 | /* do not compress IID => xxxx::IID */ | ||
153 | memcpy(*hc06_ptr, &ipaddr->s6_addr16[4], 8); | ||
154 | *hc06_ptr += 8; | ||
155 | val = 1; /* 64-bits */ | ||
156 | } | ||
157 | |||
158 | return rol8(val, shift); | ||
159 | } | ||
160 | |||
161 | /* | ||
162 | * Uncompress address function for source and | ||
163 | * destination address(non-multicast). | ||
164 | * | ||
165 | * address_mode is sam value or dam value. | ||
166 | */ | ||
167 | static int | ||
168 | lowpan_uncompress_addr(struct sk_buff *skb, | ||
169 | struct in6_addr *ipaddr, | ||
170 | const u8 address_mode, | ||
171 | const struct ieee802154_addr *lladdr) | ||
172 | { | ||
173 | bool fail; | ||
174 | |||
175 | switch (address_mode) { | ||
176 | case LOWPAN_IPHC_ADDR_00: | ||
177 | /* for global link addresses */ | ||
178 | fail = lowpan_fetch_skb(skb, ipaddr->s6_addr, 16); | ||
179 | break; | ||
180 | case LOWPAN_IPHC_ADDR_01: | ||
181 | /* fe:80::XXXX:XXXX:XXXX:XXXX */ | ||
182 | ipaddr->s6_addr[0] = 0xFE; | ||
183 | ipaddr->s6_addr[1] = 0x80; | ||
184 | fail = lowpan_fetch_skb(skb, &ipaddr->s6_addr[8], 8); | ||
185 | break; | ||
186 | case LOWPAN_IPHC_ADDR_02: | ||
187 | /* fe:80::ff:fe00:XXXX */ | ||
188 | ipaddr->s6_addr[0] = 0xFE; | ||
189 | ipaddr->s6_addr[1] = 0x80; | ||
190 | ipaddr->s6_addr[11] = 0xFF; | ||
191 | ipaddr->s6_addr[12] = 0xFE; | ||
192 | fail = lowpan_fetch_skb(skb, &ipaddr->s6_addr[14], 2); | ||
193 | break; | ||
194 | case LOWPAN_IPHC_ADDR_03: | ||
195 | fail = false; | ||
196 | switch (lladdr->addr_type) { | ||
197 | case IEEE802154_ADDR_LONG: | ||
198 | /* fe:80::XXXX:XXXX:XXXX:XXXX | ||
199 | * \_________________/ | ||
200 | * hwaddr | ||
201 | */ | ||
202 | ipaddr->s6_addr[0] = 0xFE; | ||
203 | ipaddr->s6_addr[1] = 0x80; | ||
204 | memcpy(&ipaddr->s6_addr[8], lladdr->hwaddr, | ||
205 | IEEE802154_ADDR_LEN); | ||
206 | /* second bit-flip (Universe/Local) | ||
207 | * is done according RFC2464 | ||
208 | */ | ||
209 | ipaddr->s6_addr[8] ^= 0x02; | ||
210 | break; | ||
211 | case IEEE802154_ADDR_SHORT: | ||
212 | /* fe:80::ff:fe00:XXXX | ||
213 | * \__/ | ||
214 | * short_addr | ||
215 | * | ||
216 | * Universe/Local bit is zero. | ||
217 | */ | ||
218 | ipaddr->s6_addr[0] = 0xFE; | ||
219 | ipaddr->s6_addr[1] = 0x80; | ||
220 | ipaddr->s6_addr[11] = 0xFF; | ||
221 | ipaddr->s6_addr[12] = 0xFE; | ||
222 | ipaddr->s6_addr16[7] = htons(lladdr->short_addr); | ||
223 | break; | ||
224 | default: | ||
225 | pr_debug("Invalid addr_type set\n"); | ||
226 | return -EINVAL; | ||
227 | } | ||
228 | break; | ||
229 | default: | ||
230 | pr_debug("Invalid address mode value: 0x%x\n", address_mode); | ||
231 | return -EINVAL; | ||
232 | } | ||
233 | |||
234 | if (fail) { | ||
235 | pr_debug("Failed to fetch skb data\n"); | ||
236 | return -EIO; | ||
237 | } | ||
238 | |||
239 | lowpan_raw_dump_inline(NULL, "Reconstructed ipv6 addr is:\n", | ||
240 | ipaddr->s6_addr, 16); | ||
241 | |||
242 | return 0; | ||
243 | } | ||
244 | |||
245 | /* Uncompress address function for source context | ||
246 | * based address(non-multicast). | ||
247 | */ | ||
248 | static int | ||
249 | lowpan_uncompress_context_based_src_addr(struct sk_buff *skb, | ||
250 | struct in6_addr *ipaddr, | ||
251 | const u8 sam) | ||
252 | { | ||
253 | switch (sam) { | ||
254 | case LOWPAN_IPHC_ADDR_00: | ||
255 | /* unspec address :: | ||
256 | * Do nothing, address is already :: | ||
257 | */ | ||
258 | break; | ||
259 | case LOWPAN_IPHC_ADDR_01: | ||
260 | /* TODO */ | ||
261 | case LOWPAN_IPHC_ADDR_02: | ||
262 | /* TODO */ | ||
263 | case LOWPAN_IPHC_ADDR_03: | ||
264 | /* TODO */ | ||
265 | netdev_warn(skb->dev, "SAM value 0x%x not supported\n", sam); | ||
266 | return -EINVAL; | ||
267 | default: | ||
268 | pr_debug("Invalid sam value: 0x%x\n", sam); | ||
269 | return -EINVAL; | ||
270 | } | ||
271 | |||
272 | lowpan_raw_dump_inline(NULL, | ||
273 | "Reconstructed context based ipv6 src addr is:\n", | ||
274 | ipaddr->s6_addr, 16); | ||
275 | |||
276 | return 0; | ||
277 | } | ||
278 | |||
279 | /* Uncompress function for multicast destination address, | ||
280 | * when M bit is set. | ||
281 | */ | ||
282 | static int | ||
283 | lowpan_uncompress_multicast_daddr(struct sk_buff *skb, | ||
284 | struct in6_addr *ipaddr, | ||
285 | const u8 dam) | ||
286 | { | ||
287 | bool fail; | ||
288 | |||
289 | switch (dam) { | ||
290 | case LOWPAN_IPHC_DAM_00: | ||
291 | /* 00: 128 bits. The full address | ||
292 | * is carried in-line. | ||
293 | */ | ||
294 | fail = lowpan_fetch_skb(skb, ipaddr->s6_addr, 16); | ||
295 | break; | ||
296 | case LOWPAN_IPHC_DAM_01: | ||
297 | /* 01: 48 bits. The address takes | ||
298 | * the form ffXX::00XX:XXXX:XXXX. | ||
299 | */ | ||
300 | ipaddr->s6_addr[0] = 0xFF; | ||
301 | fail = lowpan_fetch_skb(skb, &ipaddr->s6_addr[1], 1); | ||
302 | fail |= lowpan_fetch_skb(skb, &ipaddr->s6_addr[11], 5); | ||
303 | break; | ||
304 | case LOWPAN_IPHC_DAM_10: | ||
305 | /* 10: 32 bits. The address takes | ||
306 | * the form ffXX::00XX:XXXX. | ||
307 | */ | ||
308 | ipaddr->s6_addr[0] = 0xFF; | ||
309 | fail = lowpan_fetch_skb(skb, &ipaddr->s6_addr[1], 1); | ||
310 | fail |= lowpan_fetch_skb(skb, &ipaddr->s6_addr[13], 3); | ||
311 | break; | ||
312 | case LOWPAN_IPHC_DAM_11: | ||
313 | /* 11: 8 bits. The address takes | ||
314 | * the form ff02::00XX. | ||
315 | */ | ||
316 | ipaddr->s6_addr[0] = 0xFF; | ||
317 | ipaddr->s6_addr[1] = 0x02; | ||
318 | fail = lowpan_fetch_skb(skb, &ipaddr->s6_addr[15], 1); | ||
319 | break; | ||
320 | default: | ||
321 | pr_debug("DAM value has a wrong value: 0x%x\n", dam); | ||
322 | return -EINVAL; | ||
323 | } | ||
324 | |||
325 | if (fail) { | ||
326 | pr_debug("Failed to fetch skb data\n"); | ||
327 | return -EIO; | ||
328 | } | ||
329 | |||
330 | lowpan_raw_dump_inline(NULL, "Reconstructed ipv6 multicast addr is:\n", | ||
331 | ipaddr->s6_addr, 16); | ||
332 | |||
333 | return 0; | ||
334 | } | ||
335 | |||
336 | static void | ||
337 | lowpan_compress_udp_header(u8 **hc06_ptr, struct sk_buff *skb) | ||
338 | { | ||
339 | struct udphdr *uh = udp_hdr(skb); | ||
340 | |||
341 | if (((uh->source & LOWPAN_NHC_UDP_4BIT_MASK) == | ||
342 | LOWPAN_NHC_UDP_4BIT_PORT) && | ||
343 | ((uh->dest & LOWPAN_NHC_UDP_4BIT_MASK) == | ||
344 | LOWPAN_NHC_UDP_4BIT_PORT)) { | ||
345 | pr_debug("UDP header: both ports compression to 4 bits\n"); | ||
346 | **hc06_ptr = LOWPAN_NHC_UDP_CS_P_11; | ||
347 | **(hc06_ptr + 1) = /* subtraction is faster */ | ||
348 | (u8)((uh->dest - LOWPAN_NHC_UDP_4BIT_PORT) + | ||
349 | ((uh->source & LOWPAN_NHC_UDP_4BIT_PORT) << 4)); | ||
350 | *hc06_ptr += 2; | ||
351 | } else if ((uh->dest & LOWPAN_NHC_UDP_8BIT_MASK) == | ||
352 | LOWPAN_NHC_UDP_8BIT_PORT) { | ||
353 | pr_debug("UDP header: remove 8 bits of dest\n"); | ||
354 | **hc06_ptr = LOWPAN_NHC_UDP_CS_P_01; | ||
355 | memcpy(*hc06_ptr + 1, &uh->source, 2); | ||
356 | **(hc06_ptr + 3) = (u8)(uh->dest - LOWPAN_NHC_UDP_8BIT_PORT); | ||
357 | *hc06_ptr += 4; | ||
358 | } else if ((uh->source & LOWPAN_NHC_UDP_8BIT_MASK) == | ||
359 | LOWPAN_NHC_UDP_8BIT_PORT) { | ||
360 | pr_debug("UDP header: remove 8 bits of source\n"); | ||
361 | **hc06_ptr = LOWPAN_NHC_UDP_CS_P_10; | ||
362 | memcpy(*hc06_ptr + 1, &uh->dest, 2); | ||
363 | **(hc06_ptr + 3) = (u8)(uh->source - LOWPAN_NHC_UDP_8BIT_PORT); | ||
364 | *hc06_ptr += 4; | ||
365 | } else { | ||
366 | pr_debug("UDP header: can't compress\n"); | ||
367 | **hc06_ptr = LOWPAN_NHC_UDP_CS_P_00; | ||
368 | memcpy(*hc06_ptr + 1, &uh->source, 2); | ||
369 | memcpy(*hc06_ptr + 3, &uh->dest, 2); | ||
370 | *hc06_ptr += 5; | ||
371 | } | ||
372 | |||
373 | /* checksum is always inline */ | ||
374 | memcpy(*hc06_ptr, &uh->check, 2); | ||
375 | *hc06_ptr += 2; | ||
376 | |||
377 | /* skip the UDP header */ | ||
378 | skb_pull(skb, sizeof(struct udphdr)); | ||
379 | } | ||
380 | |||
381 | static inline int lowpan_fetch_skb_u8(struct sk_buff *skb, u8 *val) | ||
382 | { | ||
383 | if (unlikely(!pskb_may_pull(skb, 1))) | ||
384 | return -EINVAL; | ||
385 | |||
386 | *val = skb->data[0]; | ||
387 | skb_pull(skb, 1); | ||
388 | |||
389 | return 0; | ||
390 | } | ||
391 | |||
392 | static inline int lowpan_fetch_skb_u16(struct sk_buff *skb, u16 *val) | ||
393 | { | ||
394 | if (unlikely(!pskb_may_pull(skb, 2))) | ||
395 | return -EINVAL; | ||
396 | |||
397 | *val = (skb->data[0] << 8) | skb->data[1]; | ||
398 | skb_pull(skb, 2); | ||
399 | |||
400 | return 0; | ||
401 | } | ||
402 | |||
403 | static int | ||
404 | lowpan_uncompress_udp_header(struct sk_buff *skb, struct udphdr *uh) | ||
405 | { | ||
406 | u8 tmp; | ||
407 | |||
408 | if (!uh) | ||
409 | goto err; | ||
410 | |||
411 | if (lowpan_fetch_skb_u8(skb, &tmp)) | ||
412 | goto err; | ||
413 | |||
414 | if ((tmp & LOWPAN_NHC_UDP_MASK) == LOWPAN_NHC_UDP_ID) { | ||
415 | pr_debug("UDP header uncompression\n"); | ||
416 | switch (tmp & LOWPAN_NHC_UDP_CS_P_11) { | ||
417 | case LOWPAN_NHC_UDP_CS_P_00: | ||
418 | memcpy(&uh->source, &skb->data[0], 2); | ||
419 | memcpy(&uh->dest, &skb->data[2], 2); | ||
420 | skb_pull(skb, 4); | ||
421 | break; | ||
422 | case LOWPAN_NHC_UDP_CS_P_01: | ||
423 | memcpy(&uh->source, &skb->data[0], 2); | ||
424 | uh->dest = | ||
425 | skb->data[2] + LOWPAN_NHC_UDP_8BIT_PORT; | ||
426 | skb_pull(skb, 3); | ||
427 | break; | ||
428 | case LOWPAN_NHC_UDP_CS_P_10: | ||
429 | uh->source = skb->data[0] + LOWPAN_NHC_UDP_8BIT_PORT; | ||
430 | memcpy(&uh->dest, &skb->data[1], 2); | ||
431 | skb_pull(skb, 3); | ||
432 | break; | ||
433 | case LOWPAN_NHC_UDP_CS_P_11: | ||
434 | uh->source = | ||
435 | LOWPAN_NHC_UDP_4BIT_PORT + (skb->data[0] >> 4); | ||
436 | uh->dest = | ||
437 | LOWPAN_NHC_UDP_4BIT_PORT + (skb->data[0] & 0x0f); | ||
438 | skb_pull(skb, 1); | ||
439 | break; | ||
440 | default: | ||
441 | pr_debug("ERROR: unknown UDP format\n"); | ||
442 | goto err; | ||
443 | } | ||
444 | |||
445 | pr_debug("uncompressed UDP ports: src = %d, dst = %d\n", | ||
446 | uh->source, uh->dest); | ||
447 | |||
448 | /* copy checksum */ | ||
449 | memcpy(&uh->check, &skb->data[0], 2); | ||
450 | skb_pull(skb, 2); | ||
451 | |||
452 | /* | ||
453 | * UDP lenght needs to be infered from the lower layers | ||
454 | * here, we obtain the hint from the remaining size of the | ||
455 | * frame | ||
456 | */ | ||
457 | uh->len = htons(skb->len + sizeof(struct udphdr)); | ||
458 | pr_debug("uncompressed UDP length: src = %d", uh->len); | ||
459 | } else { | ||
460 | pr_debug("ERROR: unsupported NH format\n"); | ||
461 | goto err; | ||
462 | } | ||
463 | |||
464 | return 0; | ||
465 | err: | ||
466 | return -EINVAL; | ||
467 | } | ||
468 | |||
469 | static int lowpan_header_create(struct sk_buff *skb, | 104 | static int lowpan_header_create(struct sk_buff *skb, |
470 | struct net_device *dev, | 105 | struct net_device *dev, |
471 | unsigned short type, const void *_daddr, | 106 | unsigned short type, const void *_daddr, |
472 | const void *_saddr, unsigned int len) | 107 | const void *_saddr, unsigned int len) |
473 | { | 108 | { |
474 | u8 tmp, iphc0, iphc1, *hc06_ptr; | ||
475 | struct ipv6hdr *hdr; | 109 | struct ipv6hdr *hdr; |
476 | const u8 *saddr = _saddr; | 110 | const u8 *saddr = _saddr; |
477 | const u8 *daddr = _daddr; | 111 | const u8 *daddr = _daddr; |
478 | u8 head[100]; | ||
479 | struct ieee802154_addr sa, da; | 112 | struct ieee802154_addr sa, da; |
480 | 113 | ||
481 | /* TODO: | 114 | /* TODO: |
@@ -485,181 +118,14 @@ static int lowpan_header_create(struct sk_buff *skb, | |||
485 | return 0; | 118 | return 0; |
486 | 119 | ||
487 | hdr = ipv6_hdr(skb); | 120 | hdr = ipv6_hdr(skb); |
488 | hc06_ptr = head + 2; | ||
489 | |||
490 | pr_debug("IPv6 header dump:\n\tversion = %d\n\tlength = %d\n" | ||
491 | "\tnexthdr = 0x%02x\n\thop_lim = %d\n", hdr->version, | ||
492 | ntohs(hdr->payload_len), hdr->nexthdr, hdr->hop_limit); | ||
493 | |||
494 | lowpan_raw_dump_table(__func__, "raw skb network header dump", | ||
495 | skb_network_header(skb), sizeof(struct ipv6hdr)); | ||
496 | 121 | ||
497 | if (!saddr) | 122 | if (!saddr) |
498 | saddr = dev->dev_addr; | 123 | saddr = dev->dev_addr; |
499 | 124 | ||
500 | lowpan_raw_dump_inline(__func__, "saddr", (unsigned char *)saddr, 8); | 125 | raw_dump_inline(__func__, "saddr", (unsigned char *)saddr, 8); |
501 | 126 | raw_dump_inline(__func__, "daddr", (unsigned char *)daddr, 8); | |
502 | /* | ||
503 | * As we copy some bit-length fields, in the IPHC encoding bytes, | ||
504 | * we sometimes use |= | ||
505 | * If the field is 0, and the current bit value in memory is 1, | ||
506 | * this does not work. We therefore reset the IPHC encoding here | ||
507 | */ | ||
508 | iphc0 = LOWPAN_DISPATCH_IPHC; | ||
509 | iphc1 = 0; | ||
510 | |||
511 | /* TODO: context lookup */ | ||
512 | 127 | ||
513 | lowpan_raw_dump_inline(__func__, "daddr", (unsigned char *)daddr, 8); | 128 | lowpan_header_compress(skb, dev, type, daddr, saddr, len); |
514 | |||
515 | /* | ||
516 | * Traffic class, flow label | ||
517 | * If flow label is 0, compress it. If traffic class is 0, compress it | ||
518 | * We have to process both in the same time as the offset of traffic | ||
519 | * class depends on the presence of version and flow label | ||
520 | */ | ||
521 | |||
522 | /* hc06 format of TC is ECN | DSCP , original one is DSCP | ECN */ | ||
523 | tmp = (hdr->priority << 4) | (hdr->flow_lbl[0] >> 4); | ||
524 | tmp = ((tmp & 0x03) << 6) | (tmp >> 2); | ||
525 | |||
526 | if (((hdr->flow_lbl[0] & 0x0F) == 0) && | ||
527 | (hdr->flow_lbl[1] == 0) && (hdr->flow_lbl[2] == 0)) { | ||
528 | /* flow label can be compressed */ | ||
529 | iphc0 |= LOWPAN_IPHC_FL_C; | ||
530 | if ((hdr->priority == 0) && | ||
531 | ((hdr->flow_lbl[0] & 0xF0) == 0)) { | ||
532 | /* compress (elide) all */ | ||
533 | iphc0 |= LOWPAN_IPHC_TC_C; | ||
534 | } else { | ||
535 | /* compress only the flow label */ | ||
536 | *hc06_ptr = tmp; | ||
537 | hc06_ptr += 1; | ||
538 | } | ||
539 | } else { | ||
540 | /* Flow label cannot be compressed */ | ||
541 | if ((hdr->priority == 0) && | ||
542 | ((hdr->flow_lbl[0] & 0xF0) == 0)) { | ||
543 | /* compress only traffic class */ | ||
544 | iphc0 |= LOWPAN_IPHC_TC_C; | ||
545 | *hc06_ptr = (tmp & 0xc0) | (hdr->flow_lbl[0] & 0x0F); | ||
546 | memcpy(hc06_ptr + 1, &hdr->flow_lbl[1], 2); | ||
547 | hc06_ptr += 3; | ||
548 | } else { | ||
549 | /* compress nothing */ | ||
550 | memcpy(hc06_ptr, hdr, 4); | ||
551 | /* replace the top byte with new ECN | DSCP format */ | ||
552 | *hc06_ptr = tmp; | ||
553 | hc06_ptr += 4; | ||
554 | } | ||
555 | } | ||
556 | |||
557 | /* NOTE: payload length is always compressed */ | ||
558 | |||
559 | /* Next Header is compress if UDP */ | ||
560 | if (hdr->nexthdr == UIP_PROTO_UDP) | ||
561 | iphc0 |= LOWPAN_IPHC_NH_C; | ||
562 | |||
563 | if ((iphc0 & LOWPAN_IPHC_NH_C) == 0) { | ||
564 | *hc06_ptr = hdr->nexthdr; | ||
565 | hc06_ptr += 1; | ||
566 | } | ||
567 | |||
568 | /* | ||
569 | * Hop limit | ||
570 | * if 1: compress, encoding is 01 | ||
571 | * if 64: compress, encoding is 10 | ||
572 | * if 255: compress, encoding is 11 | ||
573 | * else do not compress | ||
574 | */ | ||
575 | switch (hdr->hop_limit) { | ||
576 | case 1: | ||
577 | iphc0 |= LOWPAN_IPHC_TTL_1; | ||
578 | break; | ||
579 | case 64: | ||
580 | iphc0 |= LOWPAN_IPHC_TTL_64; | ||
581 | break; | ||
582 | case 255: | ||
583 | iphc0 |= LOWPAN_IPHC_TTL_255; | ||
584 | break; | ||
585 | default: | ||
586 | *hc06_ptr = hdr->hop_limit; | ||
587 | hc06_ptr += 1; | ||
588 | break; | ||
589 | } | ||
590 | |||
591 | /* source address compression */ | ||
592 | if (is_addr_unspecified(&hdr->saddr)) { | ||
593 | pr_debug("source address is unspecified, setting SAC\n"); | ||
594 | iphc1 |= LOWPAN_IPHC_SAC; | ||
595 | /* TODO: context lookup */ | ||
596 | } else if (is_addr_link_local(&hdr->saddr)) { | ||
597 | pr_debug("source address is link-local\n"); | ||
598 | iphc1 |= lowpan_compress_addr_64(&hc06_ptr, | ||
599 | LOWPAN_IPHC_SAM_BIT, &hdr->saddr, saddr); | ||
600 | } else { | ||
601 | pr_debug("send the full source address\n"); | ||
602 | memcpy(hc06_ptr, &hdr->saddr.s6_addr16[0], 16); | ||
603 | hc06_ptr += 16; | ||
604 | } | ||
605 | |||
606 | /* destination address compression */ | ||
607 | if (is_addr_mcast(&hdr->daddr)) { | ||
608 | pr_debug("destination address is multicast: "); | ||
609 | iphc1 |= LOWPAN_IPHC_M; | ||
610 | if (lowpan_is_mcast_addr_compressable8(&hdr->daddr)) { | ||
611 | pr_debug("compressed to 1 octet\n"); | ||
612 | iphc1 |= LOWPAN_IPHC_DAM_11; | ||
613 | /* use last byte */ | ||
614 | *hc06_ptr = hdr->daddr.s6_addr[15]; | ||
615 | hc06_ptr += 1; | ||
616 | } else if (lowpan_is_mcast_addr_compressable32(&hdr->daddr)) { | ||
617 | pr_debug("compressed to 4 octets\n"); | ||
618 | iphc1 |= LOWPAN_IPHC_DAM_10; | ||
619 | /* second byte + the last three */ | ||
620 | *hc06_ptr = hdr->daddr.s6_addr[1]; | ||
621 | memcpy(hc06_ptr + 1, &hdr->daddr.s6_addr[13], 3); | ||
622 | hc06_ptr += 4; | ||
623 | } else if (lowpan_is_mcast_addr_compressable48(&hdr->daddr)) { | ||
624 | pr_debug("compressed to 6 octets\n"); | ||
625 | iphc1 |= LOWPAN_IPHC_DAM_01; | ||
626 | /* second byte + the last five */ | ||
627 | *hc06_ptr = hdr->daddr.s6_addr[1]; | ||
628 | memcpy(hc06_ptr + 1, &hdr->daddr.s6_addr[11], 5); | ||
629 | hc06_ptr += 6; | ||
630 | } else { | ||
631 | pr_debug("using full address\n"); | ||
632 | iphc1 |= LOWPAN_IPHC_DAM_00; | ||
633 | memcpy(hc06_ptr, &hdr->daddr.s6_addr[0], 16); | ||
634 | hc06_ptr += 16; | ||
635 | } | ||
636 | } else { | ||
637 | /* TODO: context lookup */ | ||
638 | if (is_addr_link_local(&hdr->daddr)) { | ||
639 | pr_debug("dest address is unicast and link-local\n"); | ||
640 | iphc1 |= lowpan_compress_addr_64(&hc06_ptr, | ||
641 | LOWPAN_IPHC_DAM_BIT, &hdr->daddr, daddr); | ||
642 | } else { | ||
643 | pr_debug("dest address is unicast: using full one\n"); | ||
644 | memcpy(hc06_ptr, &hdr->daddr.s6_addr16[0], 16); | ||
645 | hc06_ptr += 16; | ||
646 | } | ||
647 | } | ||
648 | |||
649 | /* UDP header compression */ | ||
650 | if (hdr->nexthdr == UIP_PROTO_UDP) | ||
651 | lowpan_compress_udp_header(&hc06_ptr, skb); | ||
652 | |||
653 | head[0] = iphc0; | ||
654 | head[1] = iphc1; | ||
655 | |||
656 | skb_pull(skb, sizeof(struct ipv6hdr)); | ||
657 | skb_reset_transport_header(skb); | ||
658 | memcpy(skb_push(skb, hc06_ptr - head), head, hc06_ptr - head); | ||
659 | skb_reset_network_header(skb); | ||
660 | |||
661 | lowpan_raw_dump_table(__func__, "raw skb data dump", skb->data, | ||
662 | skb->len); | ||
663 | 129 | ||
664 | /* | 130 | /* |
665 | * NOTE1: I'm still unsure about the fact that compression and WPAN | 131 | * NOTE1: I'm still unsure about the fact that compression and WPAN |
@@ -671,39 +137,38 @@ static int lowpan_header_create(struct sk_buff *skb, | |||
671 | * from MAC subif of the 'dev' and 'real_dev' network devices, but | 137 | * from MAC subif of the 'dev' and 'real_dev' network devices, but |
672 | * this isn't implemented in mainline yet, so currently we assign 0xff | 138 | * this isn't implemented in mainline yet, so currently we assign 0xff |
673 | */ | 139 | */ |
674 | { | 140 | mac_cb(skb)->flags = IEEE802154_FC_TYPE_DATA; |
675 | mac_cb(skb)->flags = IEEE802154_FC_TYPE_DATA; | 141 | mac_cb(skb)->seq = ieee802154_mlme_ops(dev)->get_dsn(dev); |
676 | mac_cb(skb)->seq = ieee802154_mlme_ops(dev)->get_dsn(dev); | ||
677 | 142 | ||
678 | /* prepare wpan address data */ | 143 | /* prepare wpan address data */ |
679 | sa.addr_type = IEEE802154_ADDR_LONG; | 144 | sa.addr_type = IEEE802154_ADDR_LONG; |
680 | sa.pan_id = ieee802154_mlme_ops(dev)->get_pan_id(dev); | 145 | sa.pan_id = ieee802154_mlme_ops(dev)->get_pan_id(dev); |
681 | 146 | ||
682 | memcpy(&(sa.hwaddr), saddr, 8); | 147 | memcpy(&(sa.hwaddr), saddr, 8); |
683 | /* intra-PAN communications */ | 148 | /* intra-PAN communications */ |
684 | da.pan_id = ieee802154_mlme_ops(dev)->get_pan_id(dev); | 149 | da.pan_id = ieee802154_mlme_ops(dev)->get_pan_id(dev); |
685 | 150 | ||
686 | /* | 151 | /* |
687 | * if the destination address is the broadcast address, use the | 152 | * if the destination address is the broadcast address, use the |
688 | * corresponding short address | 153 | * corresponding short address |
689 | */ | 154 | */ |
690 | if (lowpan_is_addr_broadcast(daddr)) { | 155 | if (lowpan_is_addr_broadcast(daddr)) { |
691 | da.addr_type = IEEE802154_ADDR_SHORT; | 156 | da.addr_type = IEEE802154_ADDR_SHORT; |
692 | da.short_addr = IEEE802154_ADDR_BROADCAST; | 157 | da.short_addr = IEEE802154_ADDR_BROADCAST; |
693 | } else { | 158 | } else { |
694 | da.addr_type = IEEE802154_ADDR_LONG; | 159 | da.addr_type = IEEE802154_ADDR_LONG; |
695 | memcpy(&(da.hwaddr), daddr, IEEE802154_ADDR_LEN); | 160 | memcpy(&(da.hwaddr), daddr, IEEE802154_ADDR_LEN); |
696 | |||
697 | /* request acknowledgment */ | ||
698 | mac_cb(skb)->flags |= MAC_CB_FLAG_ACKREQ; | ||
699 | } | ||
700 | 161 | ||
701 | return dev_hard_header(skb, lowpan_dev_info(dev)->real_dev, | 162 | /* request acknowledgment */ |
702 | type, (void *)&da, (void *)&sa, skb->len); | 163 | mac_cb(skb)->flags |= MAC_CB_FLAG_ACKREQ; |
703 | } | 164 | } |
165 | |||
166 | return dev_hard_header(skb, lowpan_dev_info(dev)->real_dev, | ||
167 | type, (void *)&da, (void *)&sa, skb->len); | ||
704 | } | 168 | } |
705 | 169 | ||
706 | static int lowpan_give_skb_to_devices(struct sk_buff *skb) | 170 | static int lowpan_give_skb_to_devices(struct sk_buff *skb, |
171 | struct net_device *dev) | ||
707 | { | 172 | { |
708 | struct lowpan_dev_record *entry; | 173 | struct lowpan_dev_record *entry; |
709 | struct sk_buff *skb_cp; | 174 | struct sk_buff *skb_cp; |
@@ -726,31 +191,6 @@ static int lowpan_give_skb_to_devices(struct sk_buff *skb) | |||
726 | return stat; | 191 | return stat; |
727 | } | 192 | } |
728 | 193 | ||
729 | static int lowpan_skb_deliver(struct sk_buff *skb, struct ipv6hdr *hdr) | ||
730 | { | ||
731 | struct sk_buff *new; | ||
732 | int stat = NET_RX_SUCCESS; | ||
733 | |||
734 | new = skb_copy_expand(skb, sizeof(struct ipv6hdr), skb_tailroom(skb), | ||
735 | GFP_ATOMIC); | ||
736 | kfree_skb(skb); | ||
737 | |||
738 | if (!new) | ||
739 | return -ENOMEM; | ||
740 | |||
741 | skb_push(new, sizeof(struct ipv6hdr)); | ||
742 | skb_copy_to_linear_data(new, hdr, sizeof(struct ipv6hdr)); | ||
743 | |||
744 | new->protocol = htons(ETH_P_IPV6); | ||
745 | new->pkt_type = PACKET_HOST; | ||
746 | |||
747 | stat = lowpan_give_skb_to_devices(new); | ||
748 | |||
749 | kfree_skb(new); | ||
750 | |||
751 | return stat; | ||
752 | } | ||
753 | |||
754 | static void lowpan_fragment_timer_expired(unsigned long entry_addr) | 194 | static void lowpan_fragment_timer_expired(unsigned long entry_addr) |
755 | { | 195 | { |
756 | struct lowpan_fragment *entry = (struct lowpan_fragment *)entry_addr; | 196 | struct lowpan_fragment *entry = (struct lowpan_fragment *)entry_addr; |
@@ -814,16 +254,12 @@ frame_err: | |||
814 | return NULL; | 254 | return NULL; |
815 | } | 255 | } |
816 | 256 | ||
817 | static int | 257 | static int process_data(struct sk_buff *skb) |
818 | lowpan_process_data(struct sk_buff *skb) | ||
819 | { | 258 | { |
820 | struct ipv6hdr hdr = {}; | 259 | u8 iphc0, iphc1; |
821 | u8 tmp, iphc0, iphc1, num_context = 0; | ||
822 | const struct ieee802154_addr *_saddr, *_daddr; | 260 | const struct ieee802154_addr *_saddr, *_daddr; |
823 | int err; | ||
824 | 261 | ||
825 | lowpan_raw_dump_table(__func__, "raw skb data dump", skb->data, | 262 | raw_dump_table(__func__, "raw skb data dump", skb->data, skb->len); |
826 | skb->len); | ||
827 | /* at least two bytes will be used for the encoding */ | 263 | /* at least two bytes will be used for the encoding */ |
828 | if (skb->len < 2) | 264 | if (skb->len < 2) |
829 | goto drop; | 265 | goto drop; |
@@ -925,162 +361,11 @@ lowpan_process_data(struct sk_buff *skb) | |||
925 | _saddr = &mac_cb(skb)->sa; | 361 | _saddr = &mac_cb(skb)->sa; |
926 | _daddr = &mac_cb(skb)->da; | 362 | _daddr = &mac_cb(skb)->da; |
927 | 363 | ||
928 | pr_debug("iphc0 = %02x, iphc1 = %02x\n", iphc0, iphc1); | 364 | return lowpan_process_data(skb, skb->dev, (u8 *)_saddr->hwaddr, |
929 | 365 | _saddr->addr_type, IEEE802154_ADDR_LEN, | |
930 | /* another if the CID flag is set */ | 366 | (u8 *)_daddr->hwaddr, _daddr->addr_type, |
931 | if (iphc1 & LOWPAN_IPHC_CID) { | 367 | IEEE802154_ADDR_LEN, iphc0, iphc1, |
932 | pr_debug("CID flag is set, increase header with one\n"); | 368 | lowpan_give_skb_to_devices); |
933 | if (lowpan_fetch_skb_u8(skb, &num_context)) | ||
934 | goto drop; | ||
935 | } | ||
936 | |||
937 | hdr.version = 6; | ||
938 | |||
939 | /* Traffic Class and Flow Label */ | ||
940 | switch ((iphc0 & LOWPAN_IPHC_TF) >> 3) { | ||
941 | /* | ||
942 | * Traffic Class and FLow Label carried in-line | ||
943 | * ECN + DSCP + 4-bit Pad + Flow Label (4 bytes) | ||
944 | */ | ||
945 | case 0: /* 00b */ | ||
946 | if (lowpan_fetch_skb_u8(skb, &tmp)) | ||
947 | goto drop; | ||
948 | |||
949 | memcpy(&hdr.flow_lbl, &skb->data[0], 3); | ||
950 | skb_pull(skb, 3); | ||
951 | hdr.priority = ((tmp >> 2) & 0x0f); | ||
952 | hdr.flow_lbl[0] = ((tmp >> 2) & 0x30) | (tmp << 6) | | ||
953 | (hdr.flow_lbl[0] & 0x0f); | ||
954 | break; | ||
955 | /* | ||
956 | * Traffic class carried in-line | ||
957 | * ECN + DSCP (1 byte), Flow Label is elided | ||
958 | */ | ||
959 | case 2: /* 10b */ | ||
960 | if (lowpan_fetch_skb_u8(skb, &tmp)) | ||
961 | goto drop; | ||
962 | |||
963 | hdr.priority = ((tmp >> 2) & 0x0f); | ||
964 | hdr.flow_lbl[0] = ((tmp << 6) & 0xC0) | ((tmp >> 2) & 0x30); | ||
965 | break; | ||
966 | /* | ||
967 | * Flow Label carried in-line | ||
968 | * ECN + 2-bit Pad + Flow Label (3 bytes), DSCP is elided | ||
969 | */ | ||
970 | case 1: /* 01b */ | ||
971 | if (lowpan_fetch_skb_u8(skb, &tmp)) | ||
972 | goto drop; | ||
973 | |||
974 | hdr.flow_lbl[0] = (skb->data[0] & 0x0F) | ((tmp >> 2) & 0x30); | ||
975 | memcpy(&hdr.flow_lbl[1], &skb->data[0], 2); | ||
976 | skb_pull(skb, 2); | ||
977 | break; | ||
978 | /* Traffic Class and Flow Label are elided */ | ||
979 | case 3: /* 11b */ | ||
980 | break; | ||
981 | default: | ||
982 | break; | ||
983 | } | ||
984 | |||
985 | /* Next Header */ | ||
986 | if ((iphc0 & LOWPAN_IPHC_NH_C) == 0) { | ||
987 | /* Next header is carried inline */ | ||
988 | if (lowpan_fetch_skb_u8(skb, &(hdr.nexthdr))) | ||
989 | goto drop; | ||
990 | |||
991 | pr_debug("NH flag is set, next header carried inline: %02x\n", | ||
992 | hdr.nexthdr); | ||
993 | } | ||
994 | |||
995 | /* Hop Limit */ | ||
996 | if ((iphc0 & 0x03) != LOWPAN_IPHC_TTL_I) | ||
997 | hdr.hop_limit = lowpan_ttl_values[iphc0 & 0x03]; | ||
998 | else { | ||
999 | if (lowpan_fetch_skb_u8(skb, &(hdr.hop_limit))) | ||
1000 | goto drop; | ||
1001 | } | ||
1002 | |||
1003 | /* Extract SAM to the tmp variable */ | ||
1004 | tmp = ((iphc1 & LOWPAN_IPHC_SAM) >> LOWPAN_IPHC_SAM_BIT) & 0x03; | ||
1005 | |||
1006 | if (iphc1 & LOWPAN_IPHC_SAC) { | ||
1007 | /* Source address context based uncompression */ | ||
1008 | pr_debug("SAC bit is set. Handle context based source address.\n"); | ||
1009 | err = lowpan_uncompress_context_based_src_addr( | ||
1010 | skb, &hdr.saddr, tmp); | ||
1011 | } else { | ||
1012 | /* Source address uncompression */ | ||
1013 | pr_debug("source address stateless compression\n"); | ||
1014 | err = lowpan_uncompress_addr(skb, &hdr.saddr, tmp, _saddr); | ||
1015 | } | ||
1016 | |||
1017 | /* Check on error of previous branch */ | ||
1018 | if (err) | ||
1019 | goto drop; | ||
1020 | |||
1021 | /* Extract DAM to the tmp variable */ | ||
1022 | tmp = ((iphc1 & LOWPAN_IPHC_DAM_11) >> LOWPAN_IPHC_DAM_BIT) & 0x03; | ||
1023 | |||
1024 | /* check for Multicast Compression */ | ||
1025 | if (iphc1 & LOWPAN_IPHC_M) { | ||
1026 | if (iphc1 & LOWPAN_IPHC_DAC) { | ||
1027 | pr_debug("dest: context-based mcast compression\n"); | ||
1028 | /* TODO: implement this */ | ||
1029 | } else { | ||
1030 | err = lowpan_uncompress_multicast_daddr( | ||
1031 | skb, &hdr.daddr, tmp); | ||
1032 | if (err) | ||
1033 | goto drop; | ||
1034 | } | ||
1035 | } else { | ||
1036 | pr_debug("dest: stateless compression\n"); | ||
1037 | err = lowpan_uncompress_addr(skb, &hdr.daddr, tmp, _daddr); | ||
1038 | if (err) | ||
1039 | goto drop; | ||
1040 | } | ||
1041 | |||
1042 | /* UDP data uncompression */ | ||
1043 | if (iphc0 & LOWPAN_IPHC_NH_C) { | ||
1044 | struct udphdr uh; | ||
1045 | struct sk_buff *new; | ||
1046 | if (lowpan_uncompress_udp_header(skb, &uh)) | ||
1047 | goto drop; | ||
1048 | |||
1049 | /* | ||
1050 | * replace the compressed UDP head by the uncompressed UDP | ||
1051 | * header | ||
1052 | */ | ||
1053 | new = skb_copy_expand(skb, sizeof(struct udphdr), | ||
1054 | skb_tailroom(skb), GFP_ATOMIC); | ||
1055 | kfree_skb(skb); | ||
1056 | |||
1057 | if (!new) | ||
1058 | return -ENOMEM; | ||
1059 | |||
1060 | skb = new; | ||
1061 | |||
1062 | skb_push(skb, sizeof(struct udphdr)); | ||
1063 | skb_copy_to_linear_data(skb, &uh, sizeof(struct udphdr)); | ||
1064 | |||
1065 | lowpan_raw_dump_table(__func__, "raw UDP header dump", | ||
1066 | (u8 *)&uh, sizeof(uh)); | ||
1067 | |||
1068 | hdr.nexthdr = UIP_PROTO_UDP; | ||
1069 | } | ||
1070 | |||
1071 | /* Not fragmented package */ | ||
1072 | hdr.payload_len = htons(skb->len); | ||
1073 | |||
1074 | pr_debug("skb headroom size = %d, data length = %d\n", | ||
1075 | skb_headroom(skb), skb->len); | ||
1076 | |||
1077 | pr_debug("IPv6 header dump:\n\tversion = %d\n\tlength = %d\n\t" | ||
1078 | "nexthdr = 0x%02x\n\thop_lim = %d\n", hdr.version, | ||
1079 | ntohs(hdr.payload_len), hdr.nexthdr, hdr.hop_limit); | ||
1080 | |||
1081 | lowpan_raw_dump_table(__func__, "raw header dump", (u8 *)&hdr, | ||
1082 | sizeof(hdr)); | ||
1083 | return lowpan_skb_deliver(skb, &hdr); | ||
1084 | 369 | ||
1085 | unlock_and_drop: | 370 | unlock_and_drop: |
1086 | spin_unlock_bh(&flist_lock); | 371 | spin_unlock_bh(&flist_lock); |
@@ -1112,7 +397,7 @@ lowpan_fragment_xmit(struct sk_buff *skb, u8 *head, | |||
1112 | hlen = (type == LOWPAN_DISPATCH_FRAG1) ? | 397 | hlen = (type == LOWPAN_DISPATCH_FRAG1) ? |
1113 | LOWPAN_FRAG1_HEAD_SIZE : LOWPAN_FRAGN_HEAD_SIZE; | 398 | LOWPAN_FRAG1_HEAD_SIZE : LOWPAN_FRAGN_HEAD_SIZE; |
1114 | 399 | ||
1115 | lowpan_raw_dump_inline(__func__, "6lowpan fragment header", head, hlen); | 400 | raw_dump_inline(__func__, "6lowpan fragment header", head, hlen); |
1116 | 401 | ||
1117 | frag = netdev_alloc_skb(skb->dev, | 402 | frag = netdev_alloc_skb(skb->dev, |
1118 | hlen + mlen + plen + IEEE802154_MFR_SIZE); | 403 | hlen + mlen + plen + IEEE802154_MFR_SIZE); |
@@ -1132,8 +417,7 @@ lowpan_fragment_xmit(struct sk_buff *skb, u8 *head, | |||
1132 | skb_copy_to_linear_data_offset(frag, mlen + hlen, | 417 | skb_copy_to_linear_data_offset(frag, mlen + hlen, |
1133 | skb_network_header(skb) + offset, plen); | 418 | skb_network_header(skb) + offset, plen); |
1134 | 419 | ||
1135 | lowpan_raw_dump_table(__func__, " raw fragment dump", frag->data, | 420 | raw_dump_table(__func__, " raw fragment dump", frag->data, frag->len); |
1136 | frag->len); | ||
1137 | 421 | ||
1138 | return dev_queue_xmit(frag); | 422 | return dev_queue_xmit(frag); |
1139 | } | 423 | } |
@@ -1316,7 +600,7 @@ static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev, | |||
1316 | /* Pull off the 1-byte of 6lowpan header. */ | 600 | /* Pull off the 1-byte of 6lowpan header. */ |
1317 | skb_pull(local_skb, 1); | 601 | skb_pull(local_skb, 1); |
1318 | 602 | ||
1319 | lowpan_give_skb_to_devices(local_skb); | 603 | lowpan_give_skb_to_devices(local_skb, NULL); |
1320 | 604 | ||
1321 | kfree_skb(local_skb); | 605 | kfree_skb(local_skb); |
1322 | kfree_skb(skb); | 606 | kfree_skb(skb); |
@@ -1328,7 +612,7 @@ static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev, | |||
1328 | local_skb = skb_clone(skb, GFP_ATOMIC); | 612 | local_skb = skb_clone(skb, GFP_ATOMIC); |
1329 | if (!local_skb) | 613 | if (!local_skb) |
1330 | goto drop; | 614 | goto drop; |
1331 | lowpan_process_data(local_skb); | 615 | process_data(local_skb); |
1332 | 616 | ||
1333 | kfree_skb(skb); | 617 | kfree_skb(skb); |
1334 | break; | 618 | break; |
diff --git a/net/ieee802154/6lowpan.h b/net/ieee802154/6lowpan.h index 2869c0526dad..2b835db3bda8 100644 --- a/net/ieee802154/6lowpan.h +++ b/net/ieee802154/6lowpan.h | |||
@@ -231,6 +231,61 @@ | |||
231 | #define LOWPAN_NHC_UDP_CS_P_10 0xF2 /* source = 0xF0 + 8bit inline, | 231 | #define LOWPAN_NHC_UDP_CS_P_10 0xF2 /* source = 0xF0 + 8bit inline, |
232 | dest = 16 bit inline */ | 232 | dest = 16 bit inline */ |
233 | #define LOWPAN_NHC_UDP_CS_P_11 0xF3 /* source & dest = 0xF0B + 4bit inline */ | 233 | #define LOWPAN_NHC_UDP_CS_P_11 0xF3 /* source & dest = 0xF0B + 4bit inline */ |
234 | #define LOWPAN_NHC_UDP_CS_C 0x04 /* checksum elided */ | ||
235 | |||
236 | #ifdef DEBUG | ||
237 | /* print data in line */ | ||
238 | static inline void raw_dump_inline(const char *caller, char *msg, | ||
239 | unsigned char *buf, int len) | ||
240 | { | ||
241 | if (msg) | ||
242 | pr_debug("%s():%s: ", caller, msg); | ||
243 | |||
244 | print_hex_dump_debug("", DUMP_PREFIX_NONE, 16, 1, buf, len, false); | ||
245 | } | ||
246 | |||
247 | /* print data in a table format: | ||
248 | * | ||
249 | * addr: xx xx xx xx xx xx | ||
250 | * addr: xx xx xx xx xx xx | ||
251 | * ... | ||
252 | */ | ||
253 | static inline void raw_dump_table(const char *caller, char *msg, | ||
254 | unsigned char *buf, int len) | ||
255 | { | ||
256 | if (msg) | ||
257 | pr_debug("%s():%s:\n", caller, msg); | ||
258 | |||
259 | print_hex_dump_debug("\t", DUMP_PREFIX_OFFSET, 16, 1, buf, len, false); | ||
260 | } | ||
261 | #else | ||
262 | static inline void raw_dump_table(const char *caller, char *msg, | ||
263 | unsigned char *buf, int len) { } | ||
264 | static inline void raw_dump_inline(const char *caller, char *msg, | ||
265 | unsigned char *buf, int len) { } | ||
266 | #endif | ||
267 | |||
268 | static inline int lowpan_fetch_skb_u8(struct sk_buff *skb, u8 *val) | ||
269 | { | ||
270 | if (unlikely(!pskb_may_pull(skb, 1))) | ||
271 | return -EINVAL; | ||
272 | |||
273 | *val = skb->data[0]; | ||
274 | skb_pull(skb, 1); | ||
275 | |||
276 | return 0; | ||
277 | } | ||
278 | |||
279 | static inline int lowpan_fetch_skb_u16(struct sk_buff *skb, u16 *val) | ||
280 | { | ||
281 | if (unlikely(!pskb_may_pull(skb, 2))) | ||
282 | return -EINVAL; | ||
283 | |||
284 | *val = (skb->data[0] << 8) | skb->data[1]; | ||
285 | skb_pull(skb, 2); | ||
286 | |||
287 | return 0; | ||
288 | } | ||
234 | 289 | ||
235 | static inline bool lowpan_fetch_skb(struct sk_buff *skb, | 290 | static inline bool lowpan_fetch_skb(struct sk_buff *skb, |
236 | void *data, const unsigned int len) | 291 | void *data, const unsigned int len) |
@@ -244,4 +299,21 @@ static inline bool lowpan_fetch_skb(struct sk_buff *skb, | |||
244 | return false; | 299 | return false; |
245 | } | 300 | } |
246 | 301 | ||
302 | static inline void lowpan_push_hc_data(u8 **hc_ptr, const void *data, | ||
303 | const size_t len) | ||
304 | { | ||
305 | memcpy(*hc_ptr, data, len); | ||
306 | *hc_ptr += len; | ||
307 | } | ||
308 | |||
309 | typedef int (*skb_delivery_cb)(struct sk_buff *skb, struct net_device *dev); | ||
310 | |||
311 | int lowpan_process_data(struct sk_buff *skb, struct net_device *dev, | ||
312 | const u8 *saddr, const u8 saddr_type, const u8 saddr_len, | ||
313 | const u8 *daddr, const u8 daddr_type, const u8 daddr_len, | ||
314 | u8 iphc0, u8 iphc1, skb_delivery_cb skb_deliver); | ||
315 | int lowpan_header_compress(struct sk_buff *skb, struct net_device *dev, | ||
316 | unsigned short type, const void *_daddr, | ||
317 | const void *_saddr, unsigned int len); | ||
318 | |||
247 | #endif /* __6LOWPAN_H__ */ | 319 | #endif /* __6LOWPAN_H__ */ |
diff --git a/net/ieee802154/6lowpan_iphc.c b/net/ieee802154/6lowpan_iphc.c new file mode 100644 index 000000000000..11840f9e46da --- /dev/null +++ b/net/ieee802154/6lowpan_iphc.c | |||
@@ -0,0 +1,799 @@ | |||
1 | /* | ||
2 | * Copyright 2011, Siemens AG | ||
3 | * written by Alexander Smirnov <alex.bluesman.smirnov@gmail.com> | ||
4 | */ | ||
5 | |||
6 | /* | ||
7 | * Based on patches from Jon Smirl <jonsmirl@gmail.com> | ||
8 | * Copyright (c) 2011 Jon Smirl <jonsmirl@gmail.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 | ||
12 | * as published by the Free Software Foundation. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License along | ||
20 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
21 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
22 | */ | ||
23 | |||
24 | /* Jon's code is based on 6lowpan implementation for Contiki which is: | ||
25 | * Copyright (c) 2008, Swedish Institute of Computer Science. | ||
26 | * All rights reserved. | ||
27 | * | ||
28 | * Redistribution and use in source and binary forms, with or without | ||
29 | * modification, are permitted provided that the following conditions | ||
30 | * are met: | ||
31 | * 1. Redistributions of source code must retain the above copyright | ||
32 | * notice, this list of conditions and the following disclaimer. | ||
33 | * 2. Redistributions in binary form must reproduce the above copyright | ||
34 | * notice, this list of conditions and the following disclaimer in the | ||
35 | * documentation and/or other materials provided with the distribution. | ||
36 | * 3. Neither the name of the Institute nor the names of its contributors | ||
37 | * may be used to endorse or promote products derived from this software | ||
38 | * without specific prior written permission. | ||
39 | * | ||
40 | * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND | ||
41 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
42 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
43 | * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE | ||
44 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
45 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
46 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
47 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
48 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
49 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
50 | * SUCH DAMAGE. | ||
51 | */ | ||
52 | |||
53 | #include <linux/bitops.h> | ||
54 | #include <linux/if_arp.h> | ||
55 | #include <linux/netdevice.h> | ||
56 | #include <net/ipv6.h> | ||
57 | #include <net/af_ieee802154.h> | ||
58 | |||
59 | #include "6lowpan.h" | ||
60 | |||
61 | /* | ||
62 | * Uncompress address function for source and | ||
63 | * destination address(non-multicast). | ||
64 | * | ||
65 | * address_mode is sam value or dam value. | ||
66 | */ | ||
67 | static int uncompress_addr(struct sk_buff *skb, | ||
68 | struct in6_addr *ipaddr, const u8 address_mode, | ||
69 | const u8 *lladdr, const u8 addr_type, | ||
70 | const u8 addr_len) | ||
71 | { | ||
72 | bool fail; | ||
73 | |||
74 | switch (address_mode) { | ||
75 | case LOWPAN_IPHC_ADDR_00: | ||
76 | /* for global link addresses */ | ||
77 | fail = lowpan_fetch_skb(skb, ipaddr->s6_addr, 16); | ||
78 | break; | ||
79 | case LOWPAN_IPHC_ADDR_01: | ||
80 | /* fe:80::XXXX:XXXX:XXXX:XXXX */ | ||
81 | ipaddr->s6_addr[0] = 0xFE; | ||
82 | ipaddr->s6_addr[1] = 0x80; | ||
83 | fail = lowpan_fetch_skb(skb, &ipaddr->s6_addr[8], 8); | ||
84 | break; | ||
85 | case LOWPAN_IPHC_ADDR_02: | ||
86 | /* fe:80::ff:fe00:XXXX */ | ||
87 | ipaddr->s6_addr[0] = 0xFE; | ||
88 | ipaddr->s6_addr[1] = 0x80; | ||
89 | ipaddr->s6_addr[11] = 0xFF; | ||
90 | ipaddr->s6_addr[12] = 0xFE; | ||
91 | fail = lowpan_fetch_skb(skb, &ipaddr->s6_addr[14], 2); | ||
92 | break; | ||
93 | case LOWPAN_IPHC_ADDR_03: | ||
94 | fail = false; | ||
95 | switch (addr_type) { | ||
96 | case IEEE802154_ADDR_LONG: | ||
97 | /* fe:80::XXXX:XXXX:XXXX:XXXX | ||
98 | * \_________________/ | ||
99 | * hwaddr | ||
100 | */ | ||
101 | ipaddr->s6_addr[0] = 0xFE; | ||
102 | ipaddr->s6_addr[1] = 0x80; | ||
103 | memcpy(&ipaddr->s6_addr[8], lladdr, addr_len); | ||
104 | /* second bit-flip (Universe/Local) | ||
105 | * is done according RFC2464 | ||
106 | */ | ||
107 | ipaddr->s6_addr[8] ^= 0x02; | ||
108 | break; | ||
109 | case IEEE802154_ADDR_SHORT: | ||
110 | /* fe:80::ff:fe00:XXXX | ||
111 | * \__/ | ||
112 | * short_addr | ||
113 | * | ||
114 | * Universe/Local bit is zero. | ||
115 | */ | ||
116 | ipaddr->s6_addr[0] = 0xFE; | ||
117 | ipaddr->s6_addr[1] = 0x80; | ||
118 | ipaddr->s6_addr[11] = 0xFF; | ||
119 | ipaddr->s6_addr[12] = 0xFE; | ||
120 | ipaddr->s6_addr16[7] = htons(*((u16 *)lladdr)); | ||
121 | break; | ||
122 | default: | ||
123 | pr_debug("Invalid addr_type set\n"); | ||
124 | return -EINVAL; | ||
125 | } | ||
126 | break; | ||
127 | default: | ||
128 | pr_debug("Invalid address mode value: 0x%x\n", address_mode); | ||
129 | return -EINVAL; | ||
130 | } | ||
131 | |||
132 | if (fail) { | ||
133 | pr_debug("Failed to fetch skb data\n"); | ||
134 | return -EIO; | ||
135 | } | ||
136 | |||
137 | raw_dump_inline(NULL, "Reconstructed ipv6 addr is", | ||
138 | ipaddr->s6_addr, 16); | ||
139 | |||
140 | return 0; | ||
141 | } | ||
142 | |||
143 | /* | ||
144 | * Uncompress address function for source context | ||
145 | * based address(non-multicast). | ||
146 | */ | ||
147 | static int uncompress_context_based_src_addr(struct sk_buff *skb, | ||
148 | struct in6_addr *ipaddr, | ||
149 | const u8 sam) | ||
150 | { | ||
151 | switch (sam) { | ||
152 | case LOWPAN_IPHC_ADDR_00: | ||
153 | /* unspec address :: | ||
154 | * Do nothing, address is already :: | ||
155 | */ | ||
156 | break; | ||
157 | case LOWPAN_IPHC_ADDR_01: | ||
158 | /* TODO */ | ||
159 | case LOWPAN_IPHC_ADDR_02: | ||
160 | /* TODO */ | ||
161 | case LOWPAN_IPHC_ADDR_03: | ||
162 | /* TODO */ | ||
163 | netdev_warn(skb->dev, "SAM value 0x%x not supported\n", sam); | ||
164 | return -EINVAL; | ||
165 | default: | ||
166 | pr_debug("Invalid sam value: 0x%x\n", sam); | ||
167 | return -EINVAL; | ||
168 | } | ||
169 | |||
170 | raw_dump_inline(NULL, | ||
171 | "Reconstructed context based ipv6 src addr is", | ||
172 | ipaddr->s6_addr, 16); | ||
173 | |||
174 | return 0; | ||
175 | } | ||
176 | |||
177 | static int skb_deliver(struct sk_buff *skb, struct ipv6hdr *hdr, | ||
178 | struct net_device *dev, skb_delivery_cb deliver_skb) | ||
179 | { | ||
180 | struct sk_buff *new; | ||
181 | int stat; | ||
182 | |||
183 | new = skb_copy_expand(skb, sizeof(struct ipv6hdr), skb_tailroom(skb), | ||
184 | GFP_ATOMIC); | ||
185 | kfree_skb(skb); | ||
186 | |||
187 | if (!new) | ||
188 | return -ENOMEM; | ||
189 | |||
190 | skb_push(new, sizeof(struct ipv6hdr)); | ||
191 | skb_reset_network_header(new); | ||
192 | skb_copy_to_linear_data(new, hdr, sizeof(struct ipv6hdr)); | ||
193 | |||
194 | new->protocol = htons(ETH_P_IPV6); | ||
195 | new->pkt_type = PACKET_HOST; | ||
196 | new->dev = dev; | ||
197 | |||
198 | raw_dump_table(__func__, "raw skb data dump before receiving", | ||
199 | new->data, new->len); | ||
200 | |||
201 | stat = deliver_skb(new, dev); | ||
202 | |||
203 | kfree_skb(new); | ||
204 | |||
205 | return stat; | ||
206 | } | ||
207 | |||
208 | /* Uncompress function for multicast destination address, | ||
209 | * when M bit is set. | ||
210 | */ | ||
211 | static int | ||
212 | lowpan_uncompress_multicast_daddr(struct sk_buff *skb, | ||
213 | struct in6_addr *ipaddr, | ||
214 | const u8 dam) | ||
215 | { | ||
216 | bool fail; | ||
217 | |||
218 | switch (dam) { | ||
219 | case LOWPAN_IPHC_DAM_00: | ||
220 | /* 00: 128 bits. The full address | ||
221 | * is carried in-line. | ||
222 | */ | ||
223 | fail = lowpan_fetch_skb(skb, ipaddr->s6_addr, 16); | ||
224 | break; | ||
225 | case LOWPAN_IPHC_DAM_01: | ||
226 | /* 01: 48 bits. The address takes | ||
227 | * the form ffXX::00XX:XXXX:XXXX. | ||
228 | */ | ||
229 | ipaddr->s6_addr[0] = 0xFF; | ||
230 | fail = lowpan_fetch_skb(skb, &ipaddr->s6_addr[1], 1); | ||
231 | fail |= lowpan_fetch_skb(skb, &ipaddr->s6_addr[11], 5); | ||
232 | break; | ||
233 | case LOWPAN_IPHC_DAM_10: | ||
234 | /* 10: 32 bits. The address takes | ||
235 | * the form ffXX::00XX:XXXX. | ||
236 | */ | ||
237 | ipaddr->s6_addr[0] = 0xFF; | ||
238 | fail = lowpan_fetch_skb(skb, &ipaddr->s6_addr[1], 1); | ||
239 | fail |= lowpan_fetch_skb(skb, &ipaddr->s6_addr[13], 3); | ||
240 | break; | ||
241 | case LOWPAN_IPHC_DAM_11: | ||
242 | /* 11: 8 bits. The address takes | ||
243 | * the form ff02::00XX. | ||
244 | */ | ||
245 | ipaddr->s6_addr[0] = 0xFF; | ||
246 | ipaddr->s6_addr[1] = 0x02; | ||
247 | fail = lowpan_fetch_skb(skb, &ipaddr->s6_addr[15], 1); | ||
248 | break; | ||
249 | default: | ||
250 | pr_debug("DAM value has a wrong value: 0x%x\n", dam); | ||
251 | return -EINVAL; | ||
252 | } | ||
253 | |||
254 | if (fail) { | ||
255 | pr_debug("Failed to fetch skb data\n"); | ||
256 | return -EIO; | ||
257 | } | ||
258 | |||
259 | raw_dump_inline(NULL, "Reconstructed ipv6 multicast addr is", | ||
260 | ipaddr->s6_addr, 16); | ||
261 | |||
262 | return 0; | ||
263 | } | ||
264 | |||
265 | static int | ||
266 | uncompress_udp_header(struct sk_buff *skb, struct udphdr *uh) | ||
267 | { | ||
268 | bool fail; | ||
269 | u8 tmp = 0, val = 0; | ||
270 | |||
271 | if (!uh) | ||
272 | goto err; | ||
273 | |||
274 | fail = lowpan_fetch_skb(skb, &tmp, 1); | ||
275 | |||
276 | if ((tmp & LOWPAN_NHC_UDP_MASK) == LOWPAN_NHC_UDP_ID) { | ||
277 | pr_debug("UDP header uncompression\n"); | ||
278 | switch (tmp & LOWPAN_NHC_UDP_CS_P_11) { | ||
279 | case LOWPAN_NHC_UDP_CS_P_00: | ||
280 | fail |= lowpan_fetch_skb(skb, &uh->source, 2); | ||
281 | fail |= lowpan_fetch_skb(skb, &uh->dest, 2); | ||
282 | break; | ||
283 | case LOWPAN_NHC_UDP_CS_P_01: | ||
284 | fail |= lowpan_fetch_skb(skb, &uh->source, 2); | ||
285 | fail |= lowpan_fetch_skb(skb, &val, 1); | ||
286 | uh->dest = htons(val + LOWPAN_NHC_UDP_8BIT_PORT); | ||
287 | break; | ||
288 | case LOWPAN_NHC_UDP_CS_P_10: | ||
289 | fail |= lowpan_fetch_skb(skb, &val, 1); | ||
290 | uh->source = htons(val + LOWPAN_NHC_UDP_8BIT_PORT); | ||
291 | fail |= lowpan_fetch_skb(skb, &uh->dest, 2); | ||
292 | break; | ||
293 | case LOWPAN_NHC_UDP_CS_P_11: | ||
294 | fail |= lowpan_fetch_skb(skb, &val, 1); | ||
295 | uh->source = htons(LOWPAN_NHC_UDP_4BIT_PORT + | ||
296 | (val >> 4)); | ||
297 | uh->dest = htons(LOWPAN_NHC_UDP_4BIT_PORT + | ||
298 | (val & 0x0f)); | ||
299 | break; | ||
300 | default: | ||
301 | pr_debug("ERROR: unknown UDP format\n"); | ||
302 | goto err; | ||
303 | break; | ||
304 | } | ||
305 | |||
306 | pr_debug("uncompressed UDP ports: src = %d, dst = %d\n", | ||
307 | ntohs(uh->source), ntohs(uh->dest)); | ||
308 | |||
309 | /* checksum */ | ||
310 | if (tmp & LOWPAN_NHC_UDP_CS_C) { | ||
311 | pr_debug_ratelimited("checksum elided currently not supported\n"); | ||
312 | goto err; | ||
313 | } else { | ||
314 | fail |= lowpan_fetch_skb(skb, &uh->check, 2); | ||
315 | } | ||
316 | |||
317 | /* | ||
318 | * UDP lenght needs to be infered from the lower layers | ||
319 | * here, we obtain the hint from the remaining size of the | ||
320 | * frame | ||
321 | */ | ||
322 | uh->len = htons(skb->len + sizeof(struct udphdr)); | ||
323 | pr_debug("uncompressed UDP length: src = %d", ntohs(uh->len)); | ||
324 | } else { | ||
325 | pr_debug("ERROR: unsupported NH format\n"); | ||
326 | goto err; | ||
327 | } | ||
328 | |||
329 | if (fail) | ||
330 | goto err; | ||
331 | |||
332 | return 0; | ||
333 | err: | ||
334 | return -EINVAL; | ||
335 | } | ||
336 | |||
337 | /* TTL uncompression values */ | ||
338 | static const u8 lowpan_ttl_values[] = { 0, 1, 64, 255 }; | ||
339 | |||
340 | int lowpan_process_data(struct sk_buff *skb, struct net_device *dev, | ||
341 | const u8 *saddr, const u8 saddr_type, const u8 saddr_len, | ||
342 | const u8 *daddr, const u8 daddr_type, const u8 daddr_len, | ||
343 | u8 iphc0, u8 iphc1, skb_delivery_cb deliver_skb) | ||
344 | { | ||
345 | struct ipv6hdr hdr = {}; | ||
346 | u8 tmp, num_context = 0; | ||
347 | int err; | ||
348 | |||
349 | raw_dump_table(__func__, "raw skb data dump uncompressed", | ||
350 | skb->data, skb->len); | ||
351 | |||
352 | /* another if the CID flag is set */ | ||
353 | if (iphc1 & LOWPAN_IPHC_CID) { | ||
354 | pr_debug("CID flag is set, increase header with one\n"); | ||
355 | if (lowpan_fetch_skb_u8(skb, &num_context)) | ||
356 | goto drop; | ||
357 | } | ||
358 | |||
359 | hdr.version = 6; | ||
360 | |||
361 | /* Traffic Class and Flow Label */ | ||
362 | switch ((iphc0 & LOWPAN_IPHC_TF) >> 3) { | ||
363 | /* | ||
364 | * Traffic Class and FLow Label carried in-line | ||
365 | * ECN + DSCP + 4-bit Pad + Flow Label (4 bytes) | ||
366 | */ | ||
367 | case 0: /* 00b */ | ||
368 | if (lowpan_fetch_skb_u8(skb, &tmp)) | ||
369 | goto drop; | ||
370 | |||
371 | memcpy(&hdr.flow_lbl, &skb->data[0], 3); | ||
372 | skb_pull(skb, 3); | ||
373 | hdr.priority = ((tmp >> 2) & 0x0f); | ||
374 | hdr.flow_lbl[0] = ((tmp >> 2) & 0x30) | (tmp << 6) | | ||
375 | (hdr.flow_lbl[0] & 0x0f); | ||
376 | break; | ||
377 | /* | ||
378 | * Traffic class carried in-line | ||
379 | * ECN + DSCP (1 byte), Flow Label is elided | ||
380 | */ | ||
381 | case 2: /* 10b */ | ||
382 | if (lowpan_fetch_skb_u8(skb, &tmp)) | ||
383 | goto drop; | ||
384 | |||
385 | hdr.priority = ((tmp >> 2) & 0x0f); | ||
386 | hdr.flow_lbl[0] = ((tmp << 6) & 0xC0) | ((tmp >> 2) & 0x30); | ||
387 | break; | ||
388 | /* | ||
389 | * Flow Label carried in-line | ||
390 | * ECN + 2-bit Pad + Flow Label (3 bytes), DSCP is elided | ||
391 | */ | ||
392 | case 1: /* 01b */ | ||
393 | if (lowpan_fetch_skb_u8(skb, &tmp)) | ||
394 | goto drop; | ||
395 | |||
396 | hdr.flow_lbl[0] = (skb->data[0] & 0x0F) | ((tmp >> 2) & 0x30); | ||
397 | memcpy(&hdr.flow_lbl[1], &skb->data[0], 2); | ||
398 | skb_pull(skb, 2); | ||
399 | break; | ||
400 | /* Traffic Class and Flow Label are elided */ | ||
401 | case 3: /* 11b */ | ||
402 | break; | ||
403 | default: | ||
404 | break; | ||
405 | } | ||
406 | |||
407 | /* Next Header */ | ||
408 | if ((iphc0 & LOWPAN_IPHC_NH_C) == 0) { | ||
409 | /* Next header is carried inline */ | ||
410 | if (lowpan_fetch_skb_u8(skb, &(hdr.nexthdr))) | ||
411 | goto drop; | ||
412 | |||
413 | pr_debug("NH flag is set, next header carried inline: %02x\n", | ||
414 | hdr.nexthdr); | ||
415 | } | ||
416 | |||
417 | /* Hop Limit */ | ||
418 | if ((iphc0 & 0x03) != LOWPAN_IPHC_TTL_I) | ||
419 | hdr.hop_limit = lowpan_ttl_values[iphc0 & 0x03]; | ||
420 | else { | ||
421 | if (lowpan_fetch_skb_u8(skb, &(hdr.hop_limit))) | ||
422 | goto drop; | ||
423 | } | ||
424 | |||
425 | /* Extract SAM to the tmp variable */ | ||
426 | tmp = ((iphc1 & LOWPAN_IPHC_SAM) >> LOWPAN_IPHC_SAM_BIT) & 0x03; | ||
427 | |||
428 | if (iphc1 & LOWPAN_IPHC_SAC) { | ||
429 | /* Source address context based uncompression */ | ||
430 | pr_debug("SAC bit is set. Handle context based source address.\n"); | ||
431 | err = uncompress_context_based_src_addr( | ||
432 | skb, &hdr.saddr, tmp); | ||
433 | } else { | ||
434 | /* Source address uncompression */ | ||
435 | pr_debug("source address stateless compression\n"); | ||
436 | err = uncompress_addr(skb, &hdr.saddr, tmp, saddr, | ||
437 | saddr_type, saddr_len); | ||
438 | } | ||
439 | |||
440 | /* Check on error of previous branch */ | ||
441 | if (err) | ||
442 | goto drop; | ||
443 | |||
444 | /* Extract DAM to the tmp variable */ | ||
445 | tmp = ((iphc1 & LOWPAN_IPHC_DAM_11) >> LOWPAN_IPHC_DAM_BIT) & 0x03; | ||
446 | |||
447 | /* check for Multicast Compression */ | ||
448 | if (iphc1 & LOWPAN_IPHC_M) { | ||
449 | if (iphc1 & LOWPAN_IPHC_DAC) { | ||
450 | pr_debug("dest: context-based mcast compression\n"); | ||
451 | /* TODO: implement this */ | ||
452 | } else { | ||
453 | err = lowpan_uncompress_multicast_daddr( | ||
454 | skb, &hdr.daddr, tmp); | ||
455 | if (err) | ||
456 | goto drop; | ||
457 | } | ||
458 | } else { | ||
459 | err = uncompress_addr(skb, &hdr.daddr, tmp, daddr, | ||
460 | daddr_type, daddr_len); | ||
461 | pr_debug("dest: stateless compression mode %d dest %pI6c\n", | ||
462 | tmp, &hdr.daddr); | ||
463 | if (err) | ||
464 | goto drop; | ||
465 | } | ||
466 | |||
467 | /* UDP data uncompression */ | ||
468 | if (iphc0 & LOWPAN_IPHC_NH_C) { | ||
469 | struct udphdr uh; | ||
470 | struct sk_buff *new; | ||
471 | if (uncompress_udp_header(skb, &uh)) | ||
472 | goto drop; | ||
473 | |||
474 | /* | ||
475 | * replace the compressed UDP head by the uncompressed UDP | ||
476 | * header | ||
477 | */ | ||
478 | new = skb_copy_expand(skb, sizeof(struct udphdr), | ||
479 | skb_tailroom(skb), GFP_ATOMIC); | ||
480 | kfree_skb(skb); | ||
481 | |||
482 | if (!new) | ||
483 | return -ENOMEM; | ||
484 | |||
485 | skb = new; | ||
486 | |||
487 | skb_push(skb, sizeof(struct udphdr)); | ||
488 | skb_reset_transport_header(skb); | ||
489 | skb_copy_to_linear_data(skb, &uh, sizeof(struct udphdr)); | ||
490 | |||
491 | raw_dump_table(__func__, "raw UDP header dump", | ||
492 | (u8 *)&uh, sizeof(uh)); | ||
493 | |||
494 | hdr.nexthdr = UIP_PROTO_UDP; | ||
495 | } | ||
496 | |||
497 | hdr.payload_len = htons(skb->len); | ||
498 | |||
499 | pr_debug("skb headroom size = %d, data length = %d\n", | ||
500 | skb_headroom(skb), skb->len); | ||
501 | |||
502 | pr_debug("IPv6 header dump:\n\tversion = %d\n\tlength = %d\n\t" | ||
503 | "nexthdr = 0x%02x\n\thop_lim = %d\n\tdest = %pI6c\n", | ||
504 | hdr.version, ntohs(hdr.payload_len), hdr.nexthdr, | ||
505 | hdr.hop_limit, &hdr.daddr); | ||
506 | |||
507 | raw_dump_table(__func__, "raw header dump", (u8 *)&hdr, | ||
508 | sizeof(hdr)); | ||
509 | |||
510 | return skb_deliver(skb, &hdr, dev, deliver_skb); | ||
511 | |||
512 | drop: | ||
513 | kfree_skb(skb); | ||
514 | return -EINVAL; | ||
515 | } | ||
516 | EXPORT_SYMBOL_GPL(lowpan_process_data); | ||
517 | |||
518 | static u8 lowpan_compress_addr_64(u8 **hc06_ptr, u8 shift, | ||
519 | const struct in6_addr *ipaddr, | ||
520 | const unsigned char *lladdr) | ||
521 | { | ||
522 | u8 val = 0; | ||
523 | |||
524 | if (is_addr_mac_addr_based(ipaddr, lladdr)) { | ||
525 | val = 3; /* 0-bits */ | ||
526 | pr_debug("address compression 0 bits\n"); | ||
527 | } else if (lowpan_is_iid_16_bit_compressable(ipaddr)) { | ||
528 | /* compress IID to 16 bits xxxx::XXXX */ | ||
529 | memcpy(*hc06_ptr, &ipaddr->s6_addr16[7], 2); | ||
530 | *hc06_ptr += 2; | ||
531 | val = 2; /* 16-bits */ | ||
532 | raw_dump_inline(NULL, "Compressed ipv6 addr is (16 bits)", | ||
533 | *hc06_ptr - 2, 2); | ||
534 | } else { | ||
535 | /* do not compress IID => xxxx::IID */ | ||
536 | memcpy(*hc06_ptr, &ipaddr->s6_addr16[4], 8); | ||
537 | *hc06_ptr += 8; | ||
538 | val = 1; /* 64-bits */ | ||
539 | raw_dump_inline(NULL, "Compressed ipv6 addr is (64 bits)", | ||
540 | *hc06_ptr - 8, 8); | ||
541 | } | ||
542 | |||
543 | return rol8(val, shift); | ||
544 | } | ||
545 | |||
546 | static void compress_udp_header(u8 **hc06_ptr, struct sk_buff *skb) | ||
547 | { | ||
548 | struct udphdr *uh = udp_hdr(skb); | ||
549 | u8 tmp; | ||
550 | |||
551 | if (((ntohs(uh->source) & LOWPAN_NHC_UDP_4BIT_MASK) == | ||
552 | LOWPAN_NHC_UDP_4BIT_PORT) && | ||
553 | ((ntohs(uh->dest) & LOWPAN_NHC_UDP_4BIT_MASK) == | ||
554 | LOWPAN_NHC_UDP_4BIT_PORT)) { | ||
555 | pr_debug("UDP header: both ports compression to 4 bits\n"); | ||
556 | /* compression value */ | ||
557 | tmp = LOWPAN_NHC_UDP_CS_P_11; | ||
558 | lowpan_push_hc_data(hc06_ptr, &tmp, sizeof(tmp)); | ||
559 | /* source and destination port */ | ||
560 | tmp = ntohs(uh->dest) - LOWPAN_NHC_UDP_4BIT_PORT + | ||
561 | ((ntohs(uh->source) - LOWPAN_NHC_UDP_4BIT_PORT) << 4); | ||
562 | lowpan_push_hc_data(hc06_ptr, &tmp, sizeof(tmp)); | ||
563 | } else if ((ntohs(uh->dest) & LOWPAN_NHC_UDP_8BIT_MASK) == | ||
564 | LOWPAN_NHC_UDP_8BIT_PORT) { | ||
565 | pr_debug("UDP header: remove 8 bits of dest\n"); | ||
566 | /* compression value */ | ||
567 | tmp = LOWPAN_NHC_UDP_CS_P_01; | ||
568 | lowpan_push_hc_data(hc06_ptr, &tmp, sizeof(tmp)); | ||
569 | /* source port */ | ||
570 | lowpan_push_hc_data(hc06_ptr, &uh->source, sizeof(uh->source)); | ||
571 | /* destination port */ | ||
572 | tmp = ntohs(uh->dest) - LOWPAN_NHC_UDP_8BIT_PORT; | ||
573 | lowpan_push_hc_data(hc06_ptr, &tmp, sizeof(tmp)); | ||
574 | } else if ((ntohs(uh->source) & LOWPAN_NHC_UDP_8BIT_MASK) == | ||
575 | LOWPAN_NHC_UDP_8BIT_PORT) { | ||
576 | pr_debug("UDP header: remove 8 bits of source\n"); | ||
577 | /* compression value */ | ||
578 | tmp = LOWPAN_NHC_UDP_CS_P_10; | ||
579 | lowpan_push_hc_data(hc06_ptr, &tmp, sizeof(tmp)); | ||
580 | /* source port */ | ||
581 | tmp = ntohs(uh->source) - LOWPAN_NHC_UDP_8BIT_PORT; | ||
582 | lowpan_push_hc_data(hc06_ptr, &tmp, sizeof(tmp)); | ||
583 | /* destination port */ | ||
584 | lowpan_push_hc_data(hc06_ptr, &uh->dest, sizeof(uh->dest)); | ||
585 | } else { | ||
586 | pr_debug("UDP header: can't compress\n"); | ||
587 | /* compression value */ | ||
588 | tmp = LOWPAN_NHC_UDP_CS_P_00; | ||
589 | lowpan_push_hc_data(hc06_ptr, &tmp, sizeof(tmp)); | ||
590 | /* source port */ | ||
591 | lowpan_push_hc_data(hc06_ptr, &uh->source, sizeof(uh->source)); | ||
592 | /* destination port */ | ||
593 | lowpan_push_hc_data(hc06_ptr, &uh->dest, sizeof(uh->dest)); | ||
594 | } | ||
595 | |||
596 | /* checksum is always inline */ | ||
597 | lowpan_push_hc_data(hc06_ptr, &uh->check, sizeof(uh->check)); | ||
598 | |||
599 | /* skip the UDP header */ | ||
600 | skb_pull(skb, sizeof(struct udphdr)); | ||
601 | } | ||
602 | |||
603 | int lowpan_header_compress(struct sk_buff *skb, struct net_device *dev, | ||
604 | unsigned short type, const void *_daddr, | ||
605 | const void *_saddr, unsigned int len) | ||
606 | { | ||
607 | u8 tmp, iphc0, iphc1, *hc06_ptr; | ||
608 | struct ipv6hdr *hdr; | ||
609 | u8 head[100] = {}; | ||
610 | |||
611 | if (type != ETH_P_IPV6) | ||
612 | return -EINVAL; | ||
613 | |||
614 | hdr = ipv6_hdr(skb); | ||
615 | hc06_ptr = head + 2; | ||
616 | |||
617 | pr_debug("IPv6 header dump:\n\tversion = %d\n\tlength = %d\n" | ||
618 | "\tnexthdr = 0x%02x\n\thop_lim = %d\n\tdest = %pI6c\n", | ||
619 | hdr->version, ntohs(hdr->payload_len), hdr->nexthdr, | ||
620 | hdr->hop_limit, &hdr->daddr); | ||
621 | |||
622 | raw_dump_table(__func__, "raw skb network header dump", | ||
623 | skb_network_header(skb), sizeof(struct ipv6hdr)); | ||
624 | |||
625 | /* | ||
626 | * As we copy some bit-length fields, in the IPHC encoding bytes, | ||
627 | * we sometimes use |= | ||
628 | * If the field is 0, and the current bit value in memory is 1, | ||
629 | * this does not work. We therefore reset the IPHC encoding here | ||
630 | */ | ||
631 | iphc0 = LOWPAN_DISPATCH_IPHC; | ||
632 | iphc1 = 0; | ||
633 | |||
634 | /* TODO: context lookup */ | ||
635 | |||
636 | raw_dump_inline(__func__, "saddr", | ||
637 | (unsigned char *)_saddr, IEEE802154_ADDR_LEN); | ||
638 | raw_dump_inline(__func__, "daddr", | ||
639 | (unsigned char *)_daddr, IEEE802154_ADDR_LEN); | ||
640 | |||
641 | raw_dump_table(__func__, | ||
642 | "sending raw skb network uncompressed packet", | ||
643 | skb->data, skb->len); | ||
644 | |||
645 | /* | ||
646 | * Traffic class, flow label | ||
647 | * If flow label is 0, compress it. If traffic class is 0, compress it | ||
648 | * We have to process both in the same time as the offset of traffic | ||
649 | * class depends on the presence of version and flow label | ||
650 | */ | ||
651 | |||
652 | /* hc06 format of TC is ECN | DSCP , original one is DSCP | ECN */ | ||
653 | tmp = (hdr->priority << 4) | (hdr->flow_lbl[0] >> 4); | ||
654 | tmp = ((tmp & 0x03) << 6) | (tmp >> 2); | ||
655 | |||
656 | if (((hdr->flow_lbl[0] & 0x0F) == 0) && | ||
657 | (hdr->flow_lbl[1] == 0) && (hdr->flow_lbl[2] == 0)) { | ||
658 | /* flow label can be compressed */ | ||
659 | iphc0 |= LOWPAN_IPHC_FL_C; | ||
660 | if ((hdr->priority == 0) && | ||
661 | ((hdr->flow_lbl[0] & 0xF0) == 0)) { | ||
662 | /* compress (elide) all */ | ||
663 | iphc0 |= LOWPAN_IPHC_TC_C; | ||
664 | } else { | ||
665 | /* compress only the flow label */ | ||
666 | *hc06_ptr = tmp; | ||
667 | hc06_ptr += 1; | ||
668 | } | ||
669 | } else { | ||
670 | /* Flow label cannot be compressed */ | ||
671 | if ((hdr->priority == 0) && | ||
672 | ((hdr->flow_lbl[0] & 0xF0) == 0)) { | ||
673 | /* compress only traffic class */ | ||
674 | iphc0 |= LOWPAN_IPHC_TC_C; | ||
675 | *hc06_ptr = (tmp & 0xc0) | (hdr->flow_lbl[0] & 0x0F); | ||
676 | memcpy(hc06_ptr + 1, &hdr->flow_lbl[1], 2); | ||
677 | hc06_ptr += 3; | ||
678 | } else { | ||
679 | /* compress nothing */ | ||
680 | memcpy(hc06_ptr, &hdr, 4); | ||
681 | /* replace the top byte with new ECN | DSCP format */ | ||
682 | *hc06_ptr = tmp; | ||
683 | hc06_ptr += 4; | ||
684 | } | ||
685 | } | ||
686 | |||
687 | /* NOTE: payload length is always compressed */ | ||
688 | |||
689 | /* Next Header is compress if UDP */ | ||
690 | if (hdr->nexthdr == UIP_PROTO_UDP) | ||
691 | iphc0 |= LOWPAN_IPHC_NH_C; | ||
692 | |||
693 | if ((iphc0 & LOWPAN_IPHC_NH_C) == 0) { | ||
694 | *hc06_ptr = hdr->nexthdr; | ||
695 | hc06_ptr += 1; | ||
696 | } | ||
697 | |||
698 | /* | ||
699 | * Hop limit | ||
700 | * if 1: compress, encoding is 01 | ||
701 | * if 64: compress, encoding is 10 | ||
702 | * if 255: compress, encoding is 11 | ||
703 | * else do not compress | ||
704 | */ | ||
705 | switch (hdr->hop_limit) { | ||
706 | case 1: | ||
707 | iphc0 |= LOWPAN_IPHC_TTL_1; | ||
708 | break; | ||
709 | case 64: | ||
710 | iphc0 |= LOWPAN_IPHC_TTL_64; | ||
711 | break; | ||
712 | case 255: | ||
713 | iphc0 |= LOWPAN_IPHC_TTL_255; | ||
714 | break; | ||
715 | default: | ||
716 | *hc06_ptr = hdr->hop_limit; | ||
717 | hc06_ptr += 1; | ||
718 | break; | ||
719 | } | ||
720 | |||
721 | /* source address compression */ | ||
722 | if (is_addr_unspecified(&hdr->saddr)) { | ||
723 | pr_debug("source address is unspecified, setting SAC\n"); | ||
724 | iphc1 |= LOWPAN_IPHC_SAC; | ||
725 | /* TODO: context lookup */ | ||
726 | } else if (is_addr_link_local(&hdr->saddr)) { | ||
727 | iphc1 |= lowpan_compress_addr_64(&hc06_ptr, | ||
728 | LOWPAN_IPHC_SAM_BIT, &hdr->saddr, _saddr); | ||
729 | pr_debug("source address unicast link-local %pI6c " | ||
730 | "iphc1 0x%02x\n", &hdr->saddr, iphc1); | ||
731 | } else { | ||
732 | pr_debug("send the full source address\n"); | ||
733 | memcpy(hc06_ptr, &hdr->saddr.s6_addr16[0], 16); | ||
734 | hc06_ptr += 16; | ||
735 | } | ||
736 | |||
737 | /* destination address compression */ | ||
738 | if (is_addr_mcast(&hdr->daddr)) { | ||
739 | pr_debug("destination address is multicast: "); | ||
740 | iphc1 |= LOWPAN_IPHC_M; | ||
741 | if (lowpan_is_mcast_addr_compressable8(&hdr->daddr)) { | ||
742 | pr_debug("compressed to 1 octet\n"); | ||
743 | iphc1 |= LOWPAN_IPHC_DAM_11; | ||
744 | /* use last byte */ | ||
745 | *hc06_ptr = hdr->daddr.s6_addr[15]; | ||
746 | hc06_ptr += 1; | ||
747 | } else if (lowpan_is_mcast_addr_compressable32(&hdr->daddr)) { | ||
748 | pr_debug("compressed to 4 octets\n"); | ||
749 | iphc1 |= LOWPAN_IPHC_DAM_10; | ||
750 | /* second byte + the last three */ | ||
751 | *hc06_ptr = hdr->daddr.s6_addr[1]; | ||
752 | memcpy(hc06_ptr + 1, &hdr->daddr.s6_addr[13], 3); | ||
753 | hc06_ptr += 4; | ||
754 | } else if (lowpan_is_mcast_addr_compressable48(&hdr->daddr)) { | ||
755 | pr_debug("compressed to 6 octets\n"); | ||
756 | iphc1 |= LOWPAN_IPHC_DAM_01; | ||
757 | /* second byte + the last five */ | ||
758 | *hc06_ptr = hdr->daddr.s6_addr[1]; | ||
759 | memcpy(hc06_ptr + 1, &hdr->daddr.s6_addr[11], 5); | ||
760 | hc06_ptr += 6; | ||
761 | } else { | ||
762 | pr_debug("using full address\n"); | ||
763 | iphc1 |= LOWPAN_IPHC_DAM_00; | ||
764 | memcpy(hc06_ptr, &hdr->daddr.s6_addr[0], 16); | ||
765 | hc06_ptr += 16; | ||
766 | } | ||
767 | } else { | ||
768 | /* TODO: context lookup */ | ||
769 | if (is_addr_link_local(&hdr->daddr)) { | ||
770 | iphc1 |= lowpan_compress_addr_64(&hc06_ptr, | ||
771 | LOWPAN_IPHC_DAM_BIT, &hdr->daddr, _daddr); | ||
772 | pr_debug("dest address unicast link-local %pI6c " | ||
773 | "iphc1 0x%02x\n", &hdr->daddr, iphc1); | ||
774 | } else { | ||
775 | pr_debug("dest address unicast %pI6c\n", &hdr->daddr); | ||
776 | memcpy(hc06_ptr, &hdr->daddr.s6_addr16[0], 16); | ||
777 | hc06_ptr += 16; | ||
778 | } | ||
779 | } | ||
780 | |||
781 | /* UDP header compression */ | ||
782 | if (hdr->nexthdr == UIP_PROTO_UDP) | ||
783 | compress_udp_header(&hc06_ptr, skb); | ||
784 | |||
785 | head[0] = iphc0; | ||
786 | head[1] = iphc1; | ||
787 | |||
788 | skb_pull(skb, sizeof(struct ipv6hdr)); | ||
789 | skb_reset_transport_header(skb); | ||
790 | memcpy(skb_push(skb, hc06_ptr - head), head, hc06_ptr - head); | ||
791 | skb_reset_network_header(skb); | ||
792 | |||
793 | pr_debug("header len %d skb %u\n", (int)(hc06_ptr - head), skb->len); | ||
794 | |||
795 | raw_dump_table(__func__, "raw skb data dump compressed", | ||
796 | skb->data, skb->len); | ||
797 | return 0; | ||
798 | } | ||
799 | EXPORT_SYMBOL_GPL(lowpan_header_compress); | ||
diff --git a/net/ieee802154/Makefile b/net/ieee802154/Makefile index d7716d64c6bb..951a83ee8af4 100644 --- a/net/ieee802154/Makefile +++ b/net/ieee802154/Makefile | |||
@@ -1,5 +1,5 @@ | |||
1 | obj-$(CONFIG_IEEE802154) += ieee802154.o af_802154.o | 1 | obj-$(CONFIG_IEEE802154) += ieee802154.o af_802154.o |
2 | obj-$(CONFIG_IEEE802154_6LOWPAN) += 6lowpan.o | 2 | obj-$(CONFIG_IEEE802154_6LOWPAN) += 6lowpan.o 6lowpan_iphc.o |
3 | 3 | ||
4 | ieee802154-y := netlink.o nl-mac.o nl-phy.o nl_policy.o wpan-class.o | 4 | ieee802154-y := netlink.o nl-mac.o nl-phy.o nl_policy.o wpan-class.o |
5 | af_802154-y := af_ieee802154.o raw.o dgram.o | 5 | af_802154-y := af_ieee802154.o raw.o dgram.o |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 31f75ea9cb60..a9fa6c1feed5 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -1822,6 +1822,7 @@ static int ipv6_generate_eui64(u8 *eui, struct net_device *dev) | |||
1822 | return addrconf_ifid_sit(eui, dev); | 1822 | return addrconf_ifid_sit(eui, dev); |
1823 | case ARPHRD_IPGRE: | 1823 | case ARPHRD_IPGRE: |
1824 | return addrconf_ifid_gre(eui, dev); | 1824 | return addrconf_ifid_gre(eui, dev); |
1825 | case ARPHRD_6LOWPAN: | ||
1825 | case ARPHRD_IEEE802154: | 1826 | case ARPHRD_IEEE802154: |
1826 | return addrconf_ifid_eui64(eui, dev); | 1827 | return addrconf_ifid_eui64(eui, dev); |
1827 | case ARPHRD_IEEE1394: | 1828 | case ARPHRD_IEEE1394: |
@@ -2677,7 +2678,8 @@ static void addrconf_dev_config(struct net_device *dev) | |||
2677 | (dev->type != ARPHRD_INFINIBAND) && | 2678 | (dev->type != ARPHRD_INFINIBAND) && |
2678 | (dev->type != ARPHRD_IEEE802154) && | 2679 | (dev->type != ARPHRD_IEEE802154) && |
2679 | (dev->type != ARPHRD_IEEE1394) && | 2680 | (dev->type != ARPHRD_IEEE1394) && |
2680 | (dev->type != ARPHRD_TUNNEL6)) { | 2681 | (dev->type != ARPHRD_TUNNEL6) && |
2682 | (dev->type != ARPHRD_6LOWPAN)) { | ||
2681 | /* Alas, we support only Ethernet autoconfiguration. */ | 2683 | /* Alas, we support only Ethernet autoconfiguration. */ |
2682 | return; | 2684 | return; |
2683 | } | 2685 | } |
diff --git a/net/mac80211/aes_cmac.c b/net/mac80211/aes_cmac.c index 537488cbf941..9b9009f99551 100644 --- a/net/mac80211/aes_cmac.c +++ b/net/mac80211/aes_cmac.c | |||
@@ -111,7 +111,7 @@ void ieee80211_aes_cmac(struct crypto_cipher *tfm, const u8 *aad, | |||
111 | } | 111 | } |
112 | 112 | ||
113 | 113 | ||
114 | struct crypto_cipher * ieee80211_aes_cmac_key_setup(const u8 key[]) | 114 | struct crypto_cipher *ieee80211_aes_cmac_key_setup(const u8 key[]) |
115 | { | 115 | { |
116 | struct crypto_cipher *tfm; | 116 | struct crypto_cipher *tfm; |
117 | 117 | ||
diff --git a/net/mac80211/aes_cmac.h b/net/mac80211/aes_cmac.h index 20785a647254..0ce6487af795 100644 --- a/net/mac80211/aes_cmac.h +++ b/net/mac80211/aes_cmac.h | |||
@@ -11,7 +11,7 @@ | |||
11 | 11 | ||
12 | #include <linux/crypto.h> | 12 | #include <linux/crypto.h> |
13 | 13 | ||
14 | struct crypto_cipher * ieee80211_aes_cmac_key_setup(const u8 key[]); | 14 | struct crypto_cipher *ieee80211_aes_cmac_key_setup(const u8 key[]); |
15 | void ieee80211_aes_cmac(struct crypto_cipher *tfm, const u8 *aad, | 15 | void ieee80211_aes_cmac(struct crypto_cipher *tfm, const u8 *aad, |
16 | const u8 *data, size_t data_len, u8 *mic); | 16 | const u8 *data, size_t data_len, u8 *mic); |
17 | void ieee80211_aes_cmac_key_free(struct crypto_cipher *tfm); | 17 | void ieee80211_aes_cmac_key_free(struct crypto_cipher *tfm); |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index ac185286842d..09d2e58a2ba7 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -828,6 +828,7 @@ static int ieee80211_set_monitor_channel(struct wiphy *wiphy, | |||
828 | if (cfg80211_chandef_identical(&local->monitor_chandef, chandef)) | 828 | if (cfg80211_chandef_identical(&local->monitor_chandef, chandef)) |
829 | return 0; | 829 | return 0; |
830 | 830 | ||
831 | mutex_lock(&local->mtx); | ||
831 | mutex_lock(&local->iflist_mtx); | 832 | mutex_lock(&local->iflist_mtx); |
832 | if (local->use_chanctx) { | 833 | if (local->use_chanctx) { |
833 | sdata = rcu_dereference_protected( | 834 | sdata = rcu_dereference_protected( |
@@ -846,6 +847,7 @@ static int ieee80211_set_monitor_channel(struct wiphy *wiphy, | |||
846 | if (ret == 0) | 847 | if (ret == 0) |
847 | local->monitor_chandef = *chandef; | 848 | local->monitor_chandef = *chandef; |
848 | mutex_unlock(&local->iflist_mtx); | 849 | mutex_unlock(&local->iflist_mtx); |
850 | mutex_unlock(&local->mtx); | ||
849 | 851 | ||
850 | return ret; | 852 | return ret; |
851 | } | 853 | } |
@@ -951,6 +953,7 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev, | |||
951 | struct cfg80211_ap_settings *params) | 953 | struct cfg80211_ap_settings *params) |
952 | { | 954 | { |
953 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 955 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
956 | struct ieee80211_local *local = sdata->local; | ||
954 | struct beacon_data *old; | 957 | struct beacon_data *old; |
955 | struct ieee80211_sub_if_data *vlan; | 958 | struct ieee80211_sub_if_data *vlan; |
956 | u32 changed = BSS_CHANGED_BEACON_INT | | 959 | u32 changed = BSS_CHANGED_BEACON_INT | |
@@ -969,8 +972,10 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev, | |||
969 | sdata->needed_rx_chains = sdata->local->rx_chains; | 972 | sdata->needed_rx_chains = sdata->local->rx_chains; |
970 | sdata->radar_required = params->radar_required; | 973 | sdata->radar_required = params->radar_required; |
971 | 974 | ||
975 | mutex_lock(&local->mtx); | ||
972 | err = ieee80211_vif_use_channel(sdata, ¶ms->chandef, | 976 | err = ieee80211_vif_use_channel(sdata, ¶ms->chandef, |
973 | IEEE80211_CHANCTX_SHARED); | 977 | IEEE80211_CHANCTX_SHARED); |
978 | mutex_unlock(&local->mtx); | ||
974 | if (err) | 979 | if (err) |
975 | return err; | 980 | return err; |
976 | ieee80211_vif_copy_chanctx_to_vlans(sdata, false); | 981 | ieee80211_vif_copy_chanctx_to_vlans(sdata, false); |
@@ -1121,7 +1126,9 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev) | |||
1121 | skb_queue_purge(&sdata->u.ap.ps.bc_buf); | 1126 | skb_queue_purge(&sdata->u.ap.ps.bc_buf); |
1122 | 1127 | ||
1123 | ieee80211_vif_copy_chanctx_to_vlans(sdata, true); | 1128 | ieee80211_vif_copy_chanctx_to_vlans(sdata, true); |
1129 | mutex_lock(&local->mtx); | ||
1124 | ieee80211_vif_release_channel(sdata); | 1130 | ieee80211_vif_release_channel(sdata); |
1131 | mutex_unlock(&local->mtx); | ||
1125 | 1132 | ||
1126 | return 0; | 1133 | return 0; |
1127 | } | 1134 | } |
@@ -1944,8 +1951,10 @@ static int ieee80211_join_mesh(struct wiphy *wiphy, struct net_device *dev, | |||
1944 | sdata->smps_mode = IEEE80211_SMPS_OFF; | 1951 | sdata->smps_mode = IEEE80211_SMPS_OFF; |
1945 | sdata->needed_rx_chains = sdata->local->rx_chains; | 1952 | sdata->needed_rx_chains = sdata->local->rx_chains; |
1946 | 1953 | ||
1954 | mutex_lock(&sdata->local->mtx); | ||
1947 | err = ieee80211_vif_use_channel(sdata, &setup->chandef, | 1955 | err = ieee80211_vif_use_channel(sdata, &setup->chandef, |
1948 | IEEE80211_CHANCTX_SHARED); | 1956 | IEEE80211_CHANCTX_SHARED); |
1957 | mutex_unlock(&sdata->local->mtx); | ||
1949 | if (err) | 1958 | if (err) |
1950 | return err; | 1959 | return err; |
1951 | 1960 | ||
@@ -1957,7 +1966,9 @@ static int ieee80211_leave_mesh(struct wiphy *wiphy, struct net_device *dev) | |||
1957 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 1966 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
1958 | 1967 | ||
1959 | ieee80211_stop_mesh(sdata); | 1968 | ieee80211_stop_mesh(sdata); |
1969 | mutex_lock(&sdata->local->mtx); | ||
1960 | ieee80211_vif_release_channel(sdata); | 1970 | ieee80211_vif_release_channel(sdata); |
1971 | mutex_unlock(&sdata->local->mtx); | ||
1961 | 1972 | ||
1962 | return 0; | 1973 | return 0; |
1963 | } | 1974 | } |
@@ -2895,26 +2906,29 @@ static int ieee80211_start_radar_detection(struct wiphy *wiphy, | |||
2895 | unsigned long timeout; | 2906 | unsigned long timeout; |
2896 | int err; | 2907 | int err; |
2897 | 2908 | ||
2898 | if (!list_empty(&local->roc_list) || local->scanning) | 2909 | mutex_lock(&local->mtx); |
2899 | return -EBUSY; | 2910 | if (!list_empty(&local->roc_list) || local->scanning) { |
2911 | err = -EBUSY; | ||
2912 | goto out_unlock; | ||
2913 | } | ||
2900 | 2914 | ||
2901 | /* whatever, but channel contexts should not complain about that one */ | 2915 | /* whatever, but channel contexts should not complain about that one */ |
2902 | sdata->smps_mode = IEEE80211_SMPS_OFF; | 2916 | sdata->smps_mode = IEEE80211_SMPS_OFF; |
2903 | sdata->needed_rx_chains = local->rx_chains; | 2917 | sdata->needed_rx_chains = local->rx_chains; |
2904 | sdata->radar_required = true; | 2918 | sdata->radar_required = true; |
2905 | 2919 | ||
2906 | mutex_lock(&local->iflist_mtx); | ||
2907 | err = ieee80211_vif_use_channel(sdata, chandef, | 2920 | err = ieee80211_vif_use_channel(sdata, chandef, |
2908 | IEEE80211_CHANCTX_SHARED); | 2921 | IEEE80211_CHANCTX_SHARED); |
2909 | mutex_unlock(&local->iflist_mtx); | ||
2910 | if (err) | 2922 | if (err) |
2911 | return err; | 2923 | goto out_unlock; |
2912 | 2924 | ||
2913 | timeout = msecs_to_jiffies(IEEE80211_DFS_MIN_CAC_TIME_MS); | 2925 | timeout = msecs_to_jiffies(IEEE80211_DFS_MIN_CAC_TIME_MS); |
2914 | ieee80211_queue_delayed_work(&sdata->local->hw, | 2926 | ieee80211_queue_delayed_work(&sdata->local->hw, |
2915 | &sdata->dfs_cac_timer_work, timeout); | 2927 | &sdata->dfs_cac_timer_work, timeout); |
2916 | 2928 | ||
2917 | return 0; | 2929 | out_unlock: |
2930 | mutex_unlock(&local->mtx); | ||
2931 | return err; | ||
2918 | } | 2932 | } |
2919 | 2933 | ||
2920 | static struct cfg80211_beacon_data * | 2934 | static struct cfg80211_beacon_data * |
@@ -2990,7 +3004,9 @@ void ieee80211_csa_finalize_work(struct work_struct *work) | |||
2990 | goto unlock; | 3004 | goto unlock; |
2991 | 3005 | ||
2992 | sdata->radar_required = sdata->csa_radar_required; | 3006 | sdata->radar_required = sdata->csa_radar_required; |
3007 | mutex_lock(&local->mtx); | ||
2993 | err = ieee80211_vif_change_channel(sdata, &changed); | 3008 | err = ieee80211_vif_change_channel(sdata, &changed); |
3009 | mutex_unlock(&local->mtx); | ||
2994 | if (WARN_ON(err < 0)) | 3010 | if (WARN_ON(err < 0)) |
2995 | goto unlock; | 3011 | goto unlock; |
2996 | 3012 | ||
@@ -3821,6 +3837,31 @@ static void ieee80211_set_wakeup(struct wiphy *wiphy, bool enabled) | |||
3821 | } | 3837 | } |
3822 | #endif | 3838 | #endif |
3823 | 3839 | ||
3840 | static int ieee80211_set_qos_map(struct wiphy *wiphy, | ||
3841 | struct net_device *dev, | ||
3842 | struct cfg80211_qos_map *qos_map) | ||
3843 | { | ||
3844 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
3845 | struct mac80211_qos_map *new_qos_map, *old_qos_map; | ||
3846 | |||
3847 | if (qos_map) { | ||
3848 | new_qos_map = kzalloc(sizeof(*new_qos_map), GFP_KERNEL); | ||
3849 | if (!new_qos_map) | ||
3850 | return -ENOMEM; | ||
3851 | memcpy(&new_qos_map->qos_map, qos_map, sizeof(*qos_map)); | ||
3852 | } else { | ||
3853 | /* A NULL qos_map was passed to disable QoS mapping */ | ||
3854 | new_qos_map = NULL; | ||
3855 | } | ||
3856 | |||
3857 | old_qos_map = rtnl_dereference(sdata->qos_map); | ||
3858 | rcu_assign_pointer(sdata->qos_map, new_qos_map); | ||
3859 | if (old_qos_map) | ||
3860 | kfree_rcu(old_qos_map, rcu_head); | ||
3861 | |||
3862 | return 0; | ||
3863 | } | ||
3864 | |||
3824 | struct cfg80211_ops mac80211_config_ops = { | 3865 | struct cfg80211_ops mac80211_config_ops = { |
3825 | .add_virtual_intf = ieee80211_add_iface, | 3866 | .add_virtual_intf = ieee80211_add_iface, |
3826 | .del_virtual_intf = ieee80211_del_iface, | 3867 | .del_virtual_intf = ieee80211_del_iface, |
@@ -3900,4 +3941,5 @@ struct cfg80211_ops mac80211_config_ops = { | |||
3900 | .get_channel = ieee80211_cfg_get_channel, | 3941 | .get_channel = ieee80211_cfg_get_channel, |
3901 | .start_radar_detection = ieee80211_start_radar_detection, | 3942 | .start_radar_detection = ieee80211_start_radar_detection, |
3902 | .channel_switch = ieee80211_channel_switch, | 3943 | .channel_switch = ieee80211_channel_switch, |
3944 | .set_qos_map = ieee80211_set_qos_map, | ||
3903 | }; | 3945 | }; |
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index a57d5d9466bc..f43613a97dd6 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c | |||
@@ -232,8 +232,8 @@ ieee80211_new_chanctx(struct ieee80211_local *local, | |||
232 | if (!local->use_chanctx) | 232 | if (!local->use_chanctx) |
233 | local->hw.conf.radar_enabled = ctx->conf.radar_enabled; | 233 | local->hw.conf.radar_enabled = ctx->conf.radar_enabled; |
234 | 234 | ||
235 | /* acquire mutex to prevent idle from changing */ | 235 | /* we hold the mutex to prevent idle from changing */ |
236 | mutex_lock(&local->mtx); | 236 | lockdep_assert_held(&local->mtx); |
237 | /* turn idle off *before* setting channel -- some drivers need that */ | 237 | /* turn idle off *before* setting channel -- some drivers need that */ |
238 | changed = ieee80211_idle_off(local); | 238 | changed = ieee80211_idle_off(local); |
239 | if (changed) | 239 | if (changed) |
@@ -246,19 +246,14 @@ ieee80211_new_chanctx(struct ieee80211_local *local, | |||
246 | err = drv_add_chanctx(local, ctx); | 246 | err = drv_add_chanctx(local, ctx); |
247 | if (err) { | 247 | if (err) { |
248 | kfree(ctx); | 248 | kfree(ctx); |
249 | ctx = ERR_PTR(err); | ||
250 | |||
251 | ieee80211_recalc_idle(local); | 249 | ieee80211_recalc_idle(local); |
252 | goto out; | 250 | return ERR_PTR(err); |
253 | } | 251 | } |
254 | } | 252 | } |
255 | 253 | ||
256 | /* and keep the mutex held until the new chanctx is on the list */ | 254 | /* and keep the mutex held until the new chanctx is on the list */ |
257 | list_add_rcu(&ctx->list, &local->chanctx_list); | 255 | list_add_rcu(&ctx->list, &local->chanctx_list); |
258 | 256 | ||
259 | out: | ||
260 | mutex_unlock(&local->mtx); | ||
261 | |||
262 | return ctx; | 257 | return ctx; |
263 | } | 258 | } |
264 | 259 | ||
@@ -294,9 +289,7 @@ static void ieee80211_free_chanctx(struct ieee80211_local *local, | |||
294 | /* throw a warning if this wasn't the only channel context. */ | 289 | /* throw a warning if this wasn't the only channel context. */ |
295 | WARN_ON(check_single_channel && !list_empty(&local->chanctx_list)); | 290 | WARN_ON(check_single_channel && !list_empty(&local->chanctx_list)); |
296 | 291 | ||
297 | mutex_lock(&local->mtx); | ||
298 | ieee80211_recalc_idle(local); | 292 | ieee80211_recalc_idle(local); |
299 | mutex_unlock(&local->mtx); | ||
300 | } | 293 | } |
301 | 294 | ||
302 | static int ieee80211_assign_vif_chanctx(struct ieee80211_sub_if_data *sdata, | 295 | static int ieee80211_assign_vif_chanctx(struct ieee80211_sub_if_data *sdata, |
@@ -358,6 +351,31 @@ static void ieee80211_recalc_chanctx_chantype(struct ieee80211_local *local, | |||
358 | ieee80211_change_chanctx(local, ctx, compat); | 351 | ieee80211_change_chanctx(local, ctx, compat); |
359 | } | 352 | } |
360 | 353 | ||
354 | static void ieee80211_recalc_radar_chanctx(struct ieee80211_local *local, | ||
355 | struct ieee80211_chanctx *chanctx) | ||
356 | { | ||
357 | bool radar_enabled; | ||
358 | |||
359 | lockdep_assert_held(&local->chanctx_mtx); | ||
360 | /* for setting local->radar_detect_enabled */ | ||
361 | lockdep_assert_held(&local->mtx); | ||
362 | |||
363 | radar_enabled = ieee80211_is_radar_required(local); | ||
364 | |||
365 | if (radar_enabled == chanctx->conf.radar_enabled) | ||
366 | return; | ||
367 | |||
368 | chanctx->conf.radar_enabled = radar_enabled; | ||
369 | local->radar_detect_enabled = chanctx->conf.radar_enabled; | ||
370 | |||
371 | if (!local->use_chanctx) { | ||
372 | local->hw.conf.radar_enabled = chanctx->conf.radar_enabled; | ||
373 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); | ||
374 | } | ||
375 | |||
376 | drv_change_chanctx(local, chanctx, IEEE80211_CHANCTX_CHANGE_RADAR); | ||
377 | } | ||
378 | |||
361 | static void ieee80211_unassign_vif_chanctx(struct ieee80211_sub_if_data *sdata, | 379 | static void ieee80211_unassign_vif_chanctx(struct ieee80211_sub_if_data *sdata, |
362 | struct ieee80211_chanctx *ctx) | 380 | struct ieee80211_chanctx *ctx) |
363 | { | 381 | { |
@@ -404,29 +422,6 @@ static void __ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata) | |||
404 | ieee80211_free_chanctx(local, ctx); | 422 | ieee80211_free_chanctx(local, ctx); |
405 | } | 423 | } |
406 | 424 | ||
407 | void ieee80211_recalc_radar_chanctx(struct ieee80211_local *local, | ||
408 | struct ieee80211_chanctx *chanctx) | ||
409 | { | ||
410 | bool radar_enabled; | ||
411 | |||
412 | lockdep_assert_held(&local->chanctx_mtx); | ||
413 | |||
414 | radar_enabled = ieee80211_is_radar_required(local); | ||
415 | |||
416 | if (radar_enabled == chanctx->conf.radar_enabled) | ||
417 | return; | ||
418 | |||
419 | chanctx->conf.radar_enabled = radar_enabled; | ||
420 | local->radar_detect_enabled = chanctx->conf.radar_enabled; | ||
421 | |||
422 | if (!local->use_chanctx) { | ||
423 | local->hw.conf.radar_enabled = chanctx->conf.radar_enabled; | ||
424 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); | ||
425 | } | ||
426 | |||
427 | drv_change_chanctx(local, chanctx, IEEE80211_CHANCTX_CHANGE_RADAR); | ||
428 | } | ||
429 | |||
430 | void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local, | 425 | void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local, |
431 | struct ieee80211_chanctx *chanctx) | 426 | struct ieee80211_chanctx *chanctx) |
432 | { | 427 | { |
@@ -518,6 +513,8 @@ int ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata, | |||
518 | struct ieee80211_chanctx *ctx; | 513 | struct ieee80211_chanctx *ctx; |
519 | int ret; | 514 | int ret; |
520 | 515 | ||
516 | lockdep_assert_held(&local->mtx); | ||
517 | |||
521 | WARN_ON(sdata->dev && netif_carrier_ok(sdata->dev)); | 518 | WARN_ON(sdata->dev && netif_carrier_ok(sdata->dev)); |
522 | 519 | ||
523 | mutex_lock(&local->chanctx_mtx); | 520 | mutex_lock(&local->chanctx_mtx); |
@@ -558,6 +555,8 @@ int ieee80211_vif_change_channel(struct ieee80211_sub_if_data *sdata, | |||
558 | int ret; | 555 | int ret; |
559 | u32 chanctx_changed = 0; | 556 | u32 chanctx_changed = 0; |
560 | 557 | ||
558 | lockdep_assert_held(&local->mtx); | ||
559 | |||
561 | /* should never be called if not performing a channel switch. */ | 560 | /* should never be called if not performing a channel switch. */ |
562 | if (WARN_ON(!sdata->vif.csa_active)) | 561 | if (WARN_ON(!sdata->vif.csa_active)) |
563 | return -EINVAL; | 562 | return -EINVAL; |
@@ -655,6 +654,8 @@ void ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata) | |||
655 | { | 654 | { |
656 | WARN_ON(sdata->dev && netif_carrier_ok(sdata->dev)); | 655 | WARN_ON(sdata->dev && netif_carrier_ok(sdata->dev)); |
657 | 656 | ||
657 | lockdep_assert_held(&sdata->local->mtx); | ||
658 | |||
658 | mutex_lock(&sdata->local->chanctx_mtx); | 659 | mutex_lock(&sdata->local->chanctx_mtx); |
659 | __ieee80211_vif_release_channel(sdata); | 660 | __ieee80211_vif_release_channel(sdata); |
660 | mutex_unlock(&sdata->local->chanctx_mtx); | 661 | mutex_unlock(&sdata->local->chanctx_mtx); |
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index d6ba841437b6..771080ec7212 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
@@ -293,14 +293,17 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
293 | radar_required = true; | 293 | radar_required = true; |
294 | } | 294 | } |
295 | 295 | ||
296 | mutex_lock(&local->mtx); | ||
296 | ieee80211_vif_release_channel(sdata); | 297 | ieee80211_vif_release_channel(sdata); |
297 | if (ieee80211_vif_use_channel(sdata, &chandef, | 298 | if (ieee80211_vif_use_channel(sdata, &chandef, |
298 | ifibss->fixed_channel ? | 299 | ifibss->fixed_channel ? |
299 | IEEE80211_CHANCTX_SHARED : | 300 | IEEE80211_CHANCTX_SHARED : |
300 | IEEE80211_CHANCTX_EXCLUSIVE)) { | 301 | IEEE80211_CHANCTX_EXCLUSIVE)) { |
301 | sdata_info(sdata, "Failed to join IBSS, no channel context\n"); | 302 | sdata_info(sdata, "Failed to join IBSS, no channel context\n"); |
303 | mutex_unlock(&local->mtx); | ||
302 | return; | 304 | return; |
303 | } | 305 | } |
306 | mutex_unlock(&local->mtx); | ||
304 | 307 | ||
305 | memcpy(ifibss->bssid, bssid, ETH_ALEN); | 308 | memcpy(ifibss->bssid, bssid, ETH_ALEN); |
306 | 309 | ||
@@ -363,7 +366,9 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
363 | sdata->vif.bss_conf.ssid_len = 0; | 366 | sdata->vif.bss_conf.ssid_len = 0; |
364 | RCU_INIT_POINTER(ifibss->presp, NULL); | 367 | RCU_INIT_POINTER(ifibss->presp, NULL); |
365 | kfree_rcu(presp, rcu_head); | 368 | kfree_rcu(presp, rcu_head); |
369 | mutex_lock(&local->mtx); | ||
366 | ieee80211_vif_release_channel(sdata); | 370 | ieee80211_vif_release_channel(sdata); |
371 | mutex_unlock(&local->mtx); | ||
367 | sdata_info(sdata, "Failed to join IBSS, driver failure: %d\n", | 372 | sdata_info(sdata, "Failed to join IBSS, driver failure: %d\n", |
368 | err); | 373 | err); |
369 | return; | 374 | return; |
@@ -747,7 +752,9 @@ static void ieee80211_ibss_disconnect(struct ieee80211_sub_if_data *sdata) | |||
747 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED | | 752 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED | |
748 | BSS_CHANGED_IBSS); | 753 | BSS_CHANGED_IBSS); |
749 | drv_leave_ibss(local, sdata); | 754 | drv_leave_ibss(local, sdata); |
755 | mutex_lock(&local->mtx); | ||
750 | ieee80211_vif_release_channel(sdata); | 756 | ieee80211_vif_release_channel(sdata); |
757 | mutex_unlock(&local->mtx); | ||
751 | } | 758 | } |
752 | 759 | ||
753 | static void ieee80211_csa_connection_drop_work(struct work_struct *work) | 760 | static void ieee80211_csa_connection_drop_work(struct work_struct *work) |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index fb5dbcb79a12..953b9e294547 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -246,7 +246,8 @@ struct ps_data { | |||
246 | /* yes, this looks ugly, but guarantees that we can later use | 246 | /* yes, this looks ugly, but guarantees that we can later use |
247 | * bitmap_empty :) | 247 | * bitmap_empty :) |
248 | * NB: don't touch this bitmap, use sta_info_{set,clear}_tim_bit */ | 248 | * NB: don't touch this bitmap, use sta_info_{set,clear}_tim_bit */ |
249 | u8 tim[sizeof(unsigned long) * BITS_TO_LONGS(IEEE80211_MAX_AID + 1)]; | 249 | u8 tim[sizeof(unsigned long) * BITS_TO_LONGS(IEEE80211_MAX_AID + 1)] |
250 | __aligned(__alignof__(unsigned long)); | ||
250 | struct sk_buff_head bc_buf; | 251 | struct sk_buff_head bc_buf; |
251 | atomic_t num_sta_ps; /* number of stations in PS mode */ | 252 | atomic_t num_sta_ps; /* number of stations in PS mode */ |
252 | int dtim_count; | 253 | int dtim_count; |
@@ -693,6 +694,11 @@ struct ieee80211_chanctx { | |||
693 | struct ieee80211_chanctx_conf conf; | 694 | struct ieee80211_chanctx_conf conf; |
694 | }; | 695 | }; |
695 | 696 | ||
697 | struct mac80211_qos_map { | ||
698 | struct cfg80211_qos_map qos_map; | ||
699 | struct rcu_head rcu_head; | ||
700 | }; | ||
701 | |||
696 | struct ieee80211_sub_if_data { | 702 | struct ieee80211_sub_if_data { |
697 | struct list_head list; | 703 | struct list_head list; |
698 | 704 | ||
@@ -738,6 +744,7 @@ struct ieee80211_sub_if_data { | |||
738 | int encrypt_headroom; | 744 | int encrypt_headroom; |
739 | 745 | ||
740 | struct ieee80211_tx_queue_params tx_conf[IEEE80211_NUM_ACS]; | 746 | struct ieee80211_tx_queue_params tx_conf[IEEE80211_NUM_ACS]; |
747 | struct mac80211_qos_map __rcu *qos_map; | ||
741 | 748 | ||
742 | struct work_struct csa_finalize_work; | 749 | struct work_struct csa_finalize_work; |
743 | int csa_counter_offset_beacon; | 750 | int csa_counter_offset_beacon; |
@@ -1775,8 +1782,6 @@ void ieee80211_vif_copy_chanctx_to_vlans(struct ieee80211_sub_if_data *sdata, | |||
1775 | 1782 | ||
1776 | void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local, | 1783 | void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local, |
1777 | struct ieee80211_chanctx *chanctx); | 1784 | struct ieee80211_chanctx *chanctx); |
1778 | void ieee80211_recalc_radar_chanctx(struct ieee80211_local *local, | ||
1779 | struct ieee80211_chanctx *chanctx); | ||
1780 | void ieee80211_recalc_chanctx_min_def(struct ieee80211_local *local, | 1785 | void ieee80211_recalc_chanctx_min_def(struct ieee80211_local *local, |
1781 | struct ieee80211_chanctx *ctx); | 1786 | struct ieee80211_chanctx *ctx); |
1782 | 1787 | ||
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index d624ed49a7d9..b2c83c0f06d0 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -418,8 +418,10 @@ int ieee80211_add_virtual_monitor(struct ieee80211_local *local) | |||
418 | return ret; | 418 | return ret; |
419 | } | 419 | } |
420 | 420 | ||
421 | mutex_lock(&local->mtx); | ||
421 | ret = ieee80211_vif_use_channel(sdata, &local->monitor_chandef, | 422 | ret = ieee80211_vif_use_channel(sdata, &local->monitor_chandef, |
422 | IEEE80211_CHANCTX_EXCLUSIVE); | 423 | IEEE80211_CHANCTX_EXCLUSIVE); |
424 | mutex_unlock(&local->mtx); | ||
423 | if (ret) { | 425 | if (ret) { |
424 | drv_remove_interface(local, sdata); | 426 | drv_remove_interface(local, sdata); |
425 | kfree(sdata); | 427 | kfree(sdata); |
@@ -456,7 +458,9 @@ void ieee80211_del_virtual_monitor(struct ieee80211_local *local) | |||
456 | 458 | ||
457 | synchronize_net(); | 459 | synchronize_net(); |
458 | 460 | ||
461 | mutex_lock(&local->mtx); | ||
459 | ieee80211_vif_release_channel(sdata); | 462 | ieee80211_vif_release_channel(sdata); |
463 | mutex_unlock(&local->mtx); | ||
460 | 464 | ||
461 | drv_remove_interface(local, sdata); | 465 | drv_remove_interface(local, sdata); |
462 | 466 | ||
@@ -826,9 +830,9 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, | |||
826 | if (sdata->wdev.cac_started) { | 830 | if (sdata->wdev.cac_started) { |
827 | chandef = sdata->vif.bss_conf.chandef; | 831 | chandef = sdata->vif.bss_conf.chandef; |
828 | WARN_ON(local->suspended); | 832 | WARN_ON(local->suspended); |
829 | mutex_lock(&local->iflist_mtx); | 833 | mutex_lock(&local->mtx); |
830 | ieee80211_vif_release_channel(sdata); | 834 | ieee80211_vif_release_channel(sdata); |
831 | mutex_unlock(&local->iflist_mtx); | 835 | mutex_unlock(&local->mtx); |
832 | cfg80211_cac_event(sdata->dev, &chandef, | 836 | cfg80211_cac_event(sdata->dev, &chandef, |
833 | NL80211_RADAR_CAC_ABORTED, | 837 | NL80211_RADAR_CAC_ABORTED, |
834 | GFP_KERNEL); | 838 | GFP_KERNEL); |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 9c2c7ee2cc30..fc1d82465b3c 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -888,7 +888,9 @@ static void ieee80211_chswitch_work(struct work_struct *work) | |||
888 | if (!ifmgd->associated) | 888 | if (!ifmgd->associated) |
889 | goto out; | 889 | goto out; |
890 | 890 | ||
891 | mutex_lock(&local->mtx); | ||
891 | ret = ieee80211_vif_change_channel(sdata, &changed); | 892 | ret = ieee80211_vif_change_channel(sdata, &changed); |
893 | mutex_unlock(&local->mtx); | ||
892 | if (ret) { | 894 | if (ret) { |
893 | sdata_info(sdata, | 895 | sdata_info(sdata, |
894 | "vif channel switch failed, disconnecting\n"); | 896 | "vif channel switch failed, disconnecting\n"); |
@@ -1401,10 +1403,14 @@ void ieee80211_dfs_cac_timer_work(struct work_struct *work) | |||
1401 | dfs_cac_timer_work); | 1403 | dfs_cac_timer_work); |
1402 | struct cfg80211_chan_def chandef = sdata->vif.bss_conf.chandef; | 1404 | struct cfg80211_chan_def chandef = sdata->vif.bss_conf.chandef; |
1403 | 1405 | ||
1404 | ieee80211_vif_release_channel(sdata); | 1406 | mutex_lock(&sdata->local->mtx); |
1405 | cfg80211_cac_event(sdata->dev, &chandef, | 1407 | if (sdata->wdev.cac_started) { |
1406 | NL80211_RADAR_CAC_FINISHED, | 1408 | ieee80211_vif_release_channel(sdata); |
1407 | GFP_KERNEL); | 1409 | cfg80211_cac_event(sdata->dev, &chandef, |
1410 | NL80211_RADAR_CAC_FINISHED, | ||
1411 | GFP_KERNEL); | ||
1412 | } | ||
1413 | mutex_unlock(&sdata->local->mtx); | ||
1408 | } | 1414 | } |
1409 | 1415 | ||
1410 | /* MLME */ | 1416 | /* MLME */ |
@@ -1747,7 +1753,9 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
1747 | ifmgd->have_beacon = false; | 1753 | ifmgd->have_beacon = false; |
1748 | 1754 | ||
1749 | ifmgd->flags = 0; | 1755 | ifmgd->flags = 0; |
1756 | mutex_lock(&local->mtx); | ||
1750 | ieee80211_vif_release_channel(sdata); | 1757 | ieee80211_vif_release_channel(sdata); |
1758 | mutex_unlock(&local->mtx); | ||
1751 | 1759 | ||
1752 | sdata->encrypt_headroom = IEEE80211_ENCRYPT_HEADROOM; | 1760 | sdata->encrypt_headroom = IEEE80211_ENCRYPT_HEADROOM; |
1753 | } | 1761 | } |
@@ -2070,7 +2078,9 @@ static void ieee80211_destroy_auth_data(struct ieee80211_sub_if_data *sdata, | |||
2070 | memset(sdata->u.mgd.bssid, 0, ETH_ALEN); | 2078 | memset(sdata->u.mgd.bssid, 0, ETH_ALEN); |
2071 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID); | 2079 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID); |
2072 | sdata->u.mgd.flags = 0; | 2080 | sdata->u.mgd.flags = 0; |
2081 | mutex_lock(&sdata->local->mtx); | ||
2073 | ieee80211_vif_release_channel(sdata); | 2082 | ieee80211_vif_release_channel(sdata); |
2083 | mutex_unlock(&sdata->local->mtx); | ||
2074 | } | 2084 | } |
2075 | 2085 | ||
2076 | cfg80211_put_bss(sdata->local->hw.wiphy, auth_data->bss); | 2086 | cfg80211_put_bss(sdata->local->hw.wiphy, auth_data->bss); |
@@ -2319,7 +2329,9 @@ static void ieee80211_destroy_assoc_data(struct ieee80211_sub_if_data *sdata, | |||
2319 | memset(sdata->u.mgd.bssid, 0, ETH_ALEN); | 2329 | memset(sdata->u.mgd.bssid, 0, ETH_ALEN); |
2320 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID); | 2330 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID); |
2321 | sdata->u.mgd.flags = 0; | 2331 | sdata->u.mgd.flags = 0; |
2332 | mutex_lock(&sdata->local->mtx); | ||
2322 | ieee80211_vif_release_channel(sdata); | 2333 | ieee80211_vif_release_channel(sdata); |
2334 | mutex_unlock(&sdata->local->mtx); | ||
2323 | } | 2335 | } |
2324 | 2336 | ||
2325 | kfree(assoc_data); | 2337 | kfree(assoc_data); |
@@ -3670,6 +3682,7 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata, | |||
3670 | /* will change later if needed */ | 3682 | /* will change later if needed */ |
3671 | sdata->smps_mode = IEEE80211_SMPS_OFF; | 3683 | sdata->smps_mode = IEEE80211_SMPS_OFF; |
3672 | 3684 | ||
3685 | mutex_lock(&local->mtx); | ||
3673 | /* | 3686 | /* |
3674 | * If this fails (possibly due to channel context sharing | 3687 | * If this fails (possibly due to channel context sharing |
3675 | * on incompatible channels, e.g. 80+80 and 160 sharing the | 3688 | * on incompatible channels, e.g. 80+80 and 160 sharing the |
@@ -3681,13 +3694,15 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata, | |||
3681 | /* don't downgrade for 5 and 10 MHz channels, though. */ | 3694 | /* don't downgrade for 5 and 10 MHz channels, though. */ |
3682 | if (chandef.width == NL80211_CHAN_WIDTH_5 || | 3695 | if (chandef.width == NL80211_CHAN_WIDTH_5 || |
3683 | chandef.width == NL80211_CHAN_WIDTH_10) | 3696 | chandef.width == NL80211_CHAN_WIDTH_10) |
3684 | return ret; | 3697 | goto out; |
3685 | 3698 | ||
3686 | while (ret && chandef.width != NL80211_CHAN_WIDTH_20_NOHT) { | 3699 | while (ret && chandef.width != NL80211_CHAN_WIDTH_20_NOHT) { |
3687 | ifmgd->flags |= ieee80211_chandef_downgrade(&chandef); | 3700 | ifmgd->flags |= ieee80211_chandef_downgrade(&chandef); |
3688 | ret = ieee80211_vif_use_channel(sdata, &chandef, | 3701 | ret = ieee80211_vif_use_channel(sdata, &chandef, |
3689 | IEEE80211_CHANCTX_SHARED); | 3702 | IEEE80211_CHANCTX_SHARED); |
3690 | } | 3703 | } |
3704 | out: | ||
3705 | mutex_unlock(&local->mtx); | ||
3691 | return ret; | 3706 | return ret; |
3692 | } | 3707 | } |
3693 | 3708 | ||
diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c index d2f19f7e7091..f3d88b0c054c 100644 --- a/net/mac80211/rc80211_minstrel.c +++ b/net/mac80211/rc80211_minstrel.c | |||
@@ -135,7 +135,7 @@ minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi) | |||
135 | u32 usecs; | 135 | u32 usecs; |
136 | int i; | 136 | int i; |
137 | 137 | ||
138 | for (i=0; i < MAX_THR_RATES; i++) | 138 | for (i = 0; i < MAX_THR_RATES; i++) |
139 | tmp_tp_rate[i] = 0; | 139 | tmp_tp_rate[i] = 0; |
140 | 140 | ||
141 | for (i = 0; i < mi->n_rates; i++) { | 141 | for (i = 0; i < mi->n_rates; i++) { |
@@ -190,7 +190,7 @@ minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi) | |||
190 | * choose the maximum throughput rate as max_prob_rate | 190 | * choose the maximum throughput rate as max_prob_rate |
191 | * (2) if all success probabilities < 95%, the rate with | 191 | * (2) if all success probabilities < 95%, the rate with |
192 | * highest success probability is choosen as max_prob_rate */ | 192 | * highest success probability is choosen as max_prob_rate */ |
193 | if (mr->probability >= MINSTREL_FRAC(95,100)) { | 193 | if (mr->probability >= MINSTREL_FRAC(95, 100)) { |
194 | if (mr->cur_tp >= mi->r[tmp_prob_rate].cur_tp) | 194 | if (mr->cur_tp >= mi->r[tmp_prob_rate].cur_tp) |
195 | tmp_prob_rate = i; | 195 | tmp_prob_rate = i; |
196 | } else { | 196 | } else { |
@@ -220,7 +220,7 @@ minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi) | |||
220 | 220 | ||
221 | static void | 221 | static void |
222 | minstrel_tx_status(void *priv, struct ieee80211_supported_band *sband, | 222 | minstrel_tx_status(void *priv, struct ieee80211_supported_band *sband, |
223 | struct ieee80211_sta *sta, void *priv_sta, | 223 | struct ieee80211_sta *sta, void *priv_sta, |
224 | struct sk_buff *skb) | 224 | struct sk_buff *skb) |
225 | { | 225 | { |
226 | struct minstrel_priv *mp = priv; | 226 | struct minstrel_priv *mp = priv; |
@@ -260,7 +260,7 @@ minstrel_tx_status(void *priv, struct ieee80211_supported_band *sband, | |||
260 | 260 | ||
261 | static inline unsigned int | 261 | static inline unsigned int |
262 | minstrel_get_retry_count(struct minstrel_rate *mr, | 262 | minstrel_get_retry_count(struct minstrel_rate *mr, |
263 | struct ieee80211_tx_info *info) | 263 | struct ieee80211_tx_info *info) |
264 | { | 264 | { |
265 | unsigned int retry = mr->adjusted_retry_count; | 265 | unsigned int retry = mr->adjusted_retry_count; |
266 | 266 | ||
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index d2ed18d82fe1..c1b5b73c5b91 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c | |||
@@ -63,7 +63,7 @@ | |||
63 | 63 | ||
64 | #define CCK_DURATION(_bitrate, _short, _len) \ | 64 | #define CCK_DURATION(_bitrate, _short, _len) \ |
65 | (1000 * (10 /* SIFS */ + \ | 65 | (1000 * (10 /* SIFS */ + \ |
66 | (_short ? 72 + 24 : 144 + 48 ) + \ | 66 | (_short ? 72 + 24 : 144 + 48) + \ |
67 | (8 * (_len + 4) * 10) / (_bitrate))) | 67 | (8 * (_len + 4) * 10) / (_bitrate))) |
68 | 68 | ||
69 | #define CCK_ACK_DURATION(_bitrate, _short) \ | 69 | #define CCK_ACK_DURATION(_bitrate, _short) \ |
diff --git a/net/mac80211/tkip.c b/net/mac80211/tkip.c index 124b1fdc20d0..0ae207771a58 100644 --- a/net/mac80211/tkip.c +++ b/net/mac80211/tkip.c | |||
@@ -186,7 +186,7 @@ void ieee80211_get_tkip_p1k_iv(struct ieee80211_key_conf *keyconf, | |||
186 | EXPORT_SYMBOL(ieee80211_get_tkip_p1k_iv); | 186 | EXPORT_SYMBOL(ieee80211_get_tkip_p1k_iv); |
187 | 187 | ||
188 | void ieee80211_get_tkip_rx_p1k(struct ieee80211_key_conf *keyconf, | 188 | void ieee80211_get_tkip_rx_p1k(struct ieee80211_key_conf *keyconf, |
189 | const u8 *ta, u32 iv32, u16 *p1k) | 189 | const u8 *ta, u32 iv32, u16 *p1k) |
190 | { | 190 | { |
191 | const u8 *tk = &keyconf->key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY]; | 191 | const u8 *tk = &keyconf->key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY]; |
192 | struct tkip_ctx ctx; | 192 | struct tkip_ctx ctx; |
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h index 3a669d7ec7ad..da9366632f37 100644 --- a/net/mac80211/trace.h +++ b/net/mac80211/trace.h | |||
@@ -553,7 +553,7 @@ TRACE_EVENT(drv_update_tkip_key, | |||
553 | 553 | ||
554 | TP_printk( | 554 | TP_printk( |
555 | LOCAL_PR_FMT VIF_PR_FMT STA_PR_FMT " iv32:%#x", | 555 | LOCAL_PR_FMT VIF_PR_FMT STA_PR_FMT " iv32:%#x", |
556 | LOCAL_PR_ARG,VIF_PR_ARG,STA_PR_ARG, __entry->iv32 | 556 | LOCAL_PR_ARG, VIF_PR_ARG, STA_PR_ARG, __entry->iv32 |
557 | ) | 557 | ) |
558 | ); | 558 | ); |
559 | 559 | ||
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 2f0e176e7989..377cf974d97d 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -2161,7 +2161,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
2161 | if (ieee80211_is_data_qos(fc)) { | 2161 | if (ieee80211_is_data_qos(fc)) { |
2162 | __le16 *qos_control; | 2162 | __le16 *qos_control; |
2163 | 2163 | ||
2164 | qos_control = (__le16*) skb_push(skb, 2); | 2164 | qos_control = (__le16 *) skb_push(skb, 2); |
2165 | memcpy(skb_push(skb, hdrlen - 2), &hdr, hdrlen - 2); | 2165 | memcpy(skb_push(skb, hdrlen - 2), &hdr, hdrlen - 2); |
2166 | /* | 2166 | /* |
2167 | * Maybe we could actually set some fields here, for now just | 2167 | * Maybe we could actually set some fields here, for now just |
@@ -2323,7 +2323,7 @@ static void __ieee80211_beacon_add_tim(struct ieee80211_sub_if_data *sdata, | |||
2323 | if (atomic_read(&ps->num_sta_ps) > 0) | 2323 | if (atomic_read(&ps->num_sta_ps) > 0) |
2324 | /* in the hope that this is faster than | 2324 | /* in the hope that this is faster than |
2325 | * checking byte-for-byte */ | 2325 | * checking byte-for-byte */ |
2326 | have_bits = !bitmap_empty((unsigned long*)ps->tim, | 2326 | have_bits = !bitmap_empty((unsigned long *)ps->tim, |
2327 | IEEE80211_MAX_AID+1); | 2327 | IEEE80211_MAX_AID+1); |
2328 | 2328 | ||
2329 | if (ps->dtim_count == 0) | 2329 | if (ps->dtim_count == 0) |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 591b46b72462..df00f1978a77 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -76,7 +76,7 @@ u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len, | |||
76 | } | 76 | } |
77 | 77 | ||
78 | if (ieee80211_is_ctl(fc)) { | 78 | if (ieee80211_is_ctl(fc)) { |
79 | if(ieee80211_is_pspoll(fc)) | 79 | if (ieee80211_is_pspoll(fc)) |
80 | return hdr->addr1; | 80 | return hdr->addr1; |
81 | 81 | ||
82 | if (ieee80211_is_back_req(fc)) { | 82 | if (ieee80211_is_back_req(fc)) { |
@@ -2315,9 +2315,14 @@ void ieee80211_dfs_cac_cancel(struct ieee80211_local *local) | |||
2315 | struct ieee80211_sub_if_data *sdata; | 2315 | struct ieee80211_sub_if_data *sdata; |
2316 | struct cfg80211_chan_def chandef; | 2316 | struct cfg80211_chan_def chandef; |
2317 | 2317 | ||
2318 | mutex_lock(&local->mtx); | ||
2318 | mutex_lock(&local->iflist_mtx); | 2319 | mutex_lock(&local->iflist_mtx); |
2319 | list_for_each_entry(sdata, &local->interfaces, list) { | 2320 | list_for_each_entry(sdata, &local->interfaces, list) { |
2320 | cancel_delayed_work_sync(&sdata->dfs_cac_timer_work); | 2321 | /* it might be waiting for the local->mtx, but then |
2322 | * by the time it gets it, sdata->wdev.cac_started | ||
2323 | * will no longer be true | ||
2324 | */ | ||
2325 | cancel_delayed_work(&sdata->dfs_cac_timer_work); | ||
2321 | 2326 | ||
2322 | if (sdata->wdev.cac_started) { | 2327 | if (sdata->wdev.cac_started) { |
2323 | chandef = sdata->vif.bss_conf.chandef; | 2328 | chandef = sdata->vif.bss_conf.chandef; |
@@ -2329,6 +2334,7 @@ void ieee80211_dfs_cac_cancel(struct ieee80211_local *local) | |||
2329 | } | 2334 | } |
2330 | } | 2335 | } |
2331 | mutex_unlock(&local->iflist_mtx); | 2336 | mutex_unlock(&local->iflist_mtx); |
2337 | mutex_unlock(&local->mtx); | ||
2332 | } | 2338 | } |
2333 | 2339 | ||
2334 | void ieee80211_dfs_radar_detected_work(struct work_struct *work) | 2340 | void ieee80211_dfs_radar_detected_work(struct work_struct *work) |
@@ -2588,3 +2594,143 @@ int ieee80211_cs_headroom(struct ieee80211_local *local, | |||
2588 | 2594 | ||
2589 | return headroom; | 2595 | return headroom; |
2590 | } | 2596 | } |
2597 | |||
2598 | static bool | ||
2599 | ieee80211_extend_noa_desc(struct ieee80211_noa_data *data, u32 tsf, int i) | ||
2600 | { | ||
2601 | s32 end = data->desc[i].start + data->desc[i].duration - (tsf + 1); | ||
2602 | int skip; | ||
2603 | |||
2604 | if (end > 0) | ||
2605 | return false; | ||
2606 | |||
2607 | /* End time is in the past, check for repetitions */ | ||
2608 | skip = DIV_ROUND_UP(-end, data->desc[i].interval); | ||
2609 | if (data->count[i] < 255) { | ||
2610 | if (data->count[i] <= skip) { | ||
2611 | data->count[i] = 0; | ||
2612 | return false; | ||
2613 | } | ||
2614 | |||
2615 | data->count[i] -= skip; | ||
2616 | } | ||
2617 | |||
2618 | data->desc[i].start += skip * data->desc[i].interval; | ||
2619 | |||
2620 | return true; | ||
2621 | } | ||
2622 | |||
2623 | static bool | ||
2624 | ieee80211_extend_absent_time(struct ieee80211_noa_data *data, u32 tsf, | ||
2625 | s32 *offset) | ||
2626 | { | ||
2627 | bool ret = false; | ||
2628 | int i; | ||
2629 | |||
2630 | for (i = 0; i < IEEE80211_P2P_NOA_DESC_MAX; i++) { | ||
2631 | s32 cur; | ||
2632 | |||
2633 | if (!data->count[i]) | ||
2634 | continue; | ||
2635 | |||
2636 | if (ieee80211_extend_noa_desc(data, tsf + *offset, i)) | ||
2637 | ret = true; | ||
2638 | |||
2639 | cur = data->desc[i].start - tsf; | ||
2640 | if (cur > *offset) | ||
2641 | continue; | ||
2642 | |||
2643 | cur = data->desc[i].start + data->desc[i].duration - tsf; | ||
2644 | if (cur > *offset) | ||
2645 | *offset = cur; | ||
2646 | } | ||
2647 | |||
2648 | return ret; | ||
2649 | } | ||
2650 | |||
2651 | static u32 | ||
2652 | ieee80211_get_noa_absent_time(struct ieee80211_noa_data *data, u32 tsf) | ||
2653 | { | ||
2654 | s32 offset = 0; | ||
2655 | int tries = 0; | ||
2656 | /* | ||
2657 | * arbitrary limit, used to avoid infinite loops when combined NoA | ||
2658 | * descriptors cover the full time period. | ||
2659 | */ | ||
2660 | int max_tries = 5; | ||
2661 | |||
2662 | ieee80211_extend_absent_time(data, tsf, &offset); | ||
2663 | do { | ||
2664 | if (!ieee80211_extend_absent_time(data, tsf, &offset)) | ||
2665 | break; | ||
2666 | |||
2667 | tries++; | ||
2668 | } while (tries < max_tries); | ||
2669 | |||
2670 | return offset; | ||
2671 | } | ||
2672 | |||
2673 | void ieee80211_update_p2p_noa(struct ieee80211_noa_data *data, u32 tsf) | ||
2674 | { | ||
2675 | u32 next_offset = BIT(31) - 1; | ||
2676 | int i; | ||
2677 | |||
2678 | data->absent = 0; | ||
2679 | data->has_next_tsf = false; | ||
2680 | for (i = 0; i < IEEE80211_P2P_NOA_DESC_MAX; i++) { | ||
2681 | s32 start; | ||
2682 | |||
2683 | if (!data->count[i]) | ||
2684 | continue; | ||
2685 | |||
2686 | ieee80211_extend_noa_desc(data, tsf, i); | ||
2687 | start = data->desc[i].start - tsf; | ||
2688 | if (start <= 0) | ||
2689 | data->absent |= BIT(i); | ||
2690 | |||
2691 | if (next_offset > start) | ||
2692 | next_offset = start; | ||
2693 | |||
2694 | data->has_next_tsf = true; | ||
2695 | } | ||
2696 | |||
2697 | if (data->absent) | ||
2698 | next_offset = ieee80211_get_noa_absent_time(data, tsf); | ||
2699 | |||
2700 | data->next_tsf = tsf + next_offset; | ||
2701 | } | ||
2702 | EXPORT_SYMBOL(ieee80211_update_p2p_noa); | ||
2703 | |||
2704 | int ieee80211_parse_p2p_noa(const struct ieee80211_p2p_noa_attr *attr, | ||
2705 | struct ieee80211_noa_data *data, u32 tsf) | ||
2706 | { | ||
2707 | int ret = 0; | ||
2708 | int i; | ||
2709 | |||
2710 | memset(data, 0, sizeof(*data)); | ||
2711 | |||
2712 | for (i = 0; i < IEEE80211_P2P_NOA_DESC_MAX; i++) { | ||
2713 | const struct ieee80211_p2p_noa_desc *desc = &attr->desc[i]; | ||
2714 | |||
2715 | if (!desc->count || !desc->duration) | ||
2716 | continue; | ||
2717 | |||
2718 | data->count[i] = desc->count; | ||
2719 | data->desc[i].start = le32_to_cpu(desc->start_time); | ||
2720 | data->desc[i].duration = le32_to_cpu(desc->duration); | ||
2721 | data->desc[i].interval = le32_to_cpu(desc->interval); | ||
2722 | |||
2723 | if (data->count[i] > 1 && | ||
2724 | data->desc[i].interval < data->desc[i].duration) | ||
2725 | continue; | ||
2726 | |||
2727 | ieee80211_extend_noa_desc(data, tsf, i); | ||
2728 | ret++; | ||
2729 | } | ||
2730 | |||
2731 | if (ret) | ||
2732 | ieee80211_update_p2p_noa(data, tsf); | ||
2733 | |||
2734 | return ret; | ||
2735 | } | ||
2736 | EXPORT_SYMBOL(ieee80211_parse_p2p_noa); | ||
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c index afba19cb6f87..21211c60ca98 100644 --- a/net/mac80211/wme.c +++ b/net/mac80211/wme.c | |||
@@ -106,6 +106,7 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, | |||
106 | struct sta_info *sta = NULL; | 106 | struct sta_info *sta = NULL; |
107 | const u8 *ra = NULL; | 107 | const u8 *ra = NULL; |
108 | bool qos = false; | 108 | bool qos = false; |
109 | struct mac80211_qos_map *qos_map; | ||
109 | 110 | ||
110 | if (local->hw.queues < IEEE80211_NUM_ACS || skb->len < 6) { | 111 | if (local->hw.queues < IEEE80211_NUM_ACS || skb->len < 6) { |
111 | skb->priority = 0; /* required for correct WPA/11i MIC */ | 112 | skb->priority = 0; /* required for correct WPA/11i MIC */ |
@@ -155,7 +156,11 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, | |||
155 | 156 | ||
156 | /* use the data classifier to determine what 802.1d tag the | 157 | /* use the data classifier to determine what 802.1d tag the |
157 | * data frame has */ | 158 | * data frame has */ |
158 | skb->priority = cfg80211_classify8021d(skb); | 159 | rcu_read_lock(); |
160 | qos_map = rcu_dereference(sdata->qos_map); | ||
161 | skb->priority = cfg80211_classify8021d(skb, qos_map ? | ||
162 | &qos_map->qos_map : NULL); | ||
163 | rcu_read_unlock(); | ||
159 | 164 | ||
160 | return ieee80211_downgrade_queue(sdata, skb); | 165 | return ieee80211_downgrade_queue(sdata, skb); |
161 | } | 166 | } |
diff --git a/net/wireless/ap.c b/net/wireless/ap.c index 324e8d851dc4..11ee4ed04f73 100644 --- a/net/wireless/ap.c +++ b/net/wireless/ap.c | |||
@@ -29,6 +29,7 @@ static int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev, | |||
29 | wdev->beacon_interval = 0; | 29 | wdev->beacon_interval = 0; |
30 | wdev->channel = NULL; | 30 | wdev->channel = NULL; |
31 | wdev->ssid_len = 0; | 31 | wdev->ssid_len = 0; |
32 | rdev_set_qos_map(rdev, dev, NULL); | ||
32 | } | 33 | } |
33 | 34 | ||
34 | return err; | 35 | return err; |
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c index 730147ed8e65..f911c5f9f903 100644 --- a/net/wireless/ibss.c +++ b/net/wireless/ibss.c | |||
@@ -183,6 +183,8 @@ static void __cfg80211_clear_ibss(struct net_device *dev, bool nowext) | |||
183 | kfree(wdev->connect_keys); | 183 | kfree(wdev->connect_keys); |
184 | wdev->connect_keys = NULL; | 184 | wdev->connect_keys = NULL; |
185 | 185 | ||
186 | rdev_set_qos_map(rdev, dev, NULL); | ||
187 | |||
186 | /* | 188 | /* |
187 | * Delete all the keys ... pairwise keys can't really | 189 | * Delete all the keys ... pairwise keys can't really |
188 | * exist any more anyway, but default keys might. | 190 | * exist any more anyway, but default keys might. |
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c index 9c7a11ae7936..885862447b63 100644 --- a/net/wireless/mesh.c +++ b/net/wireless/mesh.c | |||
@@ -277,6 +277,7 @@ static int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, | |||
277 | if (!err) { | 277 | if (!err) { |
278 | wdev->mesh_id_len = 0; | 278 | wdev->mesh_id_len = 0; |
279 | wdev->channel = NULL; | 279 | wdev->channel = NULL; |
280 | rdev_set_qos_map(rdev, dev, NULL); | ||
280 | } | 281 | } |
281 | 282 | ||
282 | return err; | 283 | return err; |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 04681a46eda8..b4f40fe84a01 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -53,6 +53,7 @@ enum nl80211_multicast_groups { | |||
53 | NL80211_MCGRP_SCAN, | 53 | NL80211_MCGRP_SCAN, |
54 | NL80211_MCGRP_REGULATORY, | 54 | NL80211_MCGRP_REGULATORY, |
55 | NL80211_MCGRP_MLME, | 55 | NL80211_MCGRP_MLME, |
56 | NL80211_MCGRP_VENDOR, | ||
56 | NL80211_MCGRP_TESTMODE /* keep last - ifdef! */ | 57 | NL80211_MCGRP_TESTMODE /* keep last - ifdef! */ |
57 | }; | 58 | }; |
58 | 59 | ||
@@ -61,6 +62,7 @@ static const struct genl_multicast_group nl80211_mcgrps[] = { | |||
61 | [NL80211_MCGRP_SCAN] = { .name = "scan", }, | 62 | [NL80211_MCGRP_SCAN] = { .name = "scan", }, |
62 | [NL80211_MCGRP_REGULATORY] = { .name = "regulatory", }, | 63 | [NL80211_MCGRP_REGULATORY] = { .name = "regulatory", }, |
63 | [NL80211_MCGRP_MLME] = { .name = "mlme", }, | 64 | [NL80211_MCGRP_MLME] = { .name = "mlme", }, |
65 | [NL80211_MCGRP_VENDOR] = { .name = "vendor", }, | ||
64 | #ifdef CONFIG_NL80211_TESTMODE | 66 | #ifdef CONFIG_NL80211_TESTMODE |
65 | [NL80211_MCGRP_TESTMODE] = { .name = "testmode", } | 67 | [NL80211_MCGRP_TESTMODE] = { .name = "testmode", } |
66 | #endif | 68 | #endif |
@@ -380,6 +382,8 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { | |||
380 | [NL80211_ATTR_VENDOR_ID] = { .type = NLA_U32 }, | 382 | [NL80211_ATTR_VENDOR_ID] = { .type = NLA_U32 }, |
381 | [NL80211_ATTR_VENDOR_SUBCMD] = { .type = NLA_U32 }, | 383 | [NL80211_ATTR_VENDOR_SUBCMD] = { .type = NLA_U32 }, |
382 | [NL80211_ATTR_VENDOR_DATA] = { .type = NLA_BINARY }, | 384 | [NL80211_ATTR_VENDOR_DATA] = { .type = NLA_BINARY }, |
385 | [NL80211_ATTR_QOS_MAP] = { .type = NLA_BINARY, | ||
386 | .len = IEEE80211_QOS_MAP_LEN_MAX }, | ||
383 | }; | 387 | }; |
384 | 388 | ||
385 | /* policy for the key attributes */ | 389 | /* policy for the key attributes */ |
@@ -1188,7 +1192,6 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev, | |||
1188 | struct nlattr *nl_bands, *nl_band; | 1192 | struct nlattr *nl_bands, *nl_band; |
1189 | struct nlattr *nl_freqs, *nl_freq; | 1193 | struct nlattr *nl_freqs, *nl_freq; |
1190 | struct nlattr *nl_cmds; | 1194 | struct nlattr *nl_cmds; |
1191 | struct nlattr *nl_vendor_cmds; | ||
1192 | enum ieee80211_band band; | 1195 | enum ieee80211_band band; |
1193 | struct ieee80211_channel *chan; | 1196 | struct ieee80211_channel *chan; |
1194 | int i; | 1197 | int i; |
@@ -1455,6 +1458,7 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev, | |||
1455 | if (dev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH) | 1458 | if (dev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH) |
1456 | CMD(channel_switch, CHANNEL_SWITCH); | 1459 | CMD(channel_switch, CHANNEL_SWITCH); |
1457 | } | 1460 | } |
1461 | CMD(set_qos_map, SET_QOS_MAP); | ||
1458 | 1462 | ||
1459 | #ifdef CONFIG_NL80211_TESTMODE | 1463 | #ifdef CONFIG_NL80211_TESTMODE |
1460 | CMD(testmode_cmd, TESTMODE); | 1464 | CMD(testmode_cmd, TESTMODE); |
@@ -1587,16 +1591,38 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev, | |||
1587 | state->split_start++; | 1591 | state->split_start++; |
1588 | break; | 1592 | break; |
1589 | case 11: | 1593 | case 11: |
1590 | nl_vendor_cmds = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA); | 1594 | if (dev->wiphy.n_vendor_commands) { |
1591 | if (!nl_vendor_cmds) | 1595 | const struct nl80211_vendor_cmd_info *info; |
1592 | goto nla_put_failure; | 1596 | struct nlattr *nested; |
1597 | |||
1598 | nested = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA); | ||
1599 | if (!nested) | ||
1600 | goto nla_put_failure; | ||
1601 | |||
1602 | for (i = 0; i < dev->wiphy.n_vendor_commands; i++) { | ||
1603 | info = &dev->wiphy.vendor_commands[i].info; | ||
1604 | if (nla_put(msg, i + 1, sizeof(*info), info)) | ||
1605 | goto nla_put_failure; | ||
1606 | } | ||
1607 | nla_nest_end(msg, nested); | ||
1608 | } | ||
1609 | |||
1610 | if (dev->wiphy.n_vendor_events) { | ||
1611 | const struct nl80211_vendor_cmd_info *info; | ||
1612 | struct nlattr *nested; | ||
1593 | 1613 | ||
1594 | for (i = 0; i < dev->wiphy.n_vendor_commands; i++) | 1614 | nested = nla_nest_start(msg, |
1595 | if (nla_put(msg, i + 1, | 1615 | NL80211_ATTR_VENDOR_EVENTS); |
1596 | sizeof(struct nl80211_vendor_cmd_info), | 1616 | if (!nested) |
1597 | &dev->wiphy.vendor_commands[i].info)) | ||
1598 | goto nla_put_failure; | 1617 | goto nla_put_failure; |
1599 | nla_nest_end(msg, nl_vendor_cmds); | 1618 | |
1619 | for (i = 0; i < dev->wiphy.n_vendor_events; i++) { | ||
1620 | info = &dev->wiphy.vendor_events[i]; | ||
1621 | if (nla_put(msg, i + 1, sizeof(*info), info)) | ||
1622 | goto nla_put_failure; | ||
1623 | } | ||
1624 | nla_nest_end(msg, nested); | ||
1625 | } | ||
1600 | 1626 | ||
1601 | /* done */ | 1627 | /* done */ |
1602 | state->split_start = 0; | 1628 | state->split_start = 0; |
@@ -6726,7 +6752,9 @@ static struct sk_buff * | |||
6726 | __cfg80211_alloc_vendor_skb(struct cfg80211_registered_device *rdev, | 6752 | __cfg80211_alloc_vendor_skb(struct cfg80211_registered_device *rdev, |
6727 | int approxlen, u32 portid, u32 seq, | 6753 | int approxlen, u32 portid, u32 seq, |
6728 | enum nl80211_commands cmd, | 6754 | enum nl80211_commands cmd, |
6729 | enum nl80211_attrs attr, gfp_t gfp) | 6755 | enum nl80211_attrs attr, |
6756 | const struct nl80211_vendor_cmd_info *info, | ||
6757 | gfp_t gfp) | ||
6730 | { | 6758 | { |
6731 | struct sk_buff *skb; | 6759 | struct sk_buff *skb; |
6732 | void *hdr; | 6760 | void *hdr; |
@@ -6744,6 +6772,16 @@ __cfg80211_alloc_vendor_skb(struct cfg80211_registered_device *rdev, | |||
6744 | 6772 | ||
6745 | if (nla_put_u32(skb, NL80211_ATTR_WIPHY, rdev->wiphy_idx)) | 6773 | if (nla_put_u32(skb, NL80211_ATTR_WIPHY, rdev->wiphy_idx)) |
6746 | goto nla_put_failure; | 6774 | goto nla_put_failure; |
6775 | |||
6776 | if (info) { | ||
6777 | if (nla_put_u32(skb, NL80211_ATTR_VENDOR_ID, | ||
6778 | info->vendor_id)) | ||
6779 | goto nla_put_failure; | ||
6780 | if (nla_put_u32(skb, NL80211_ATTR_VENDOR_SUBCMD, | ||
6781 | info->subcmd)) | ||
6782 | goto nla_put_failure; | ||
6783 | } | ||
6784 | |||
6747 | data = nla_nest_start(skb, attr); | 6785 | data = nla_nest_start(skb, attr); |
6748 | 6786 | ||
6749 | ((void **)skb->cb)[0] = rdev; | 6787 | ((void **)skb->cb)[0] = rdev; |
@@ -6884,29 +6922,54 @@ static int nl80211_testmode_dump(struct sk_buff *skb, | |||
6884 | return err; | 6922 | return err; |
6885 | } | 6923 | } |
6886 | 6924 | ||
6887 | struct sk_buff *cfg80211_testmode_alloc_event_skb(struct wiphy *wiphy, | 6925 | struct sk_buff *__cfg80211_alloc_event_skb(struct wiphy *wiphy, |
6888 | int approxlen, gfp_t gfp) | 6926 | enum nl80211_commands cmd, |
6927 | enum nl80211_attrs attr, | ||
6928 | int vendor_event_idx, | ||
6929 | int approxlen, gfp_t gfp) | ||
6889 | { | 6930 | { |
6890 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 6931 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); |
6932 | const struct nl80211_vendor_cmd_info *info; | ||
6933 | |||
6934 | switch (cmd) { | ||
6935 | case NL80211_CMD_TESTMODE: | ||
6936 | if (WARN_ON(vendor_event_idx != -1)) | ||
6937 | return NULL; | ||
6938 | info = NULL; | ||
6939 | break; | ||
6940 | case NL80211_CMD_VENDOR: | ||
6941 | if (WARN_ON(vendor_event_idx < 0 || | ||
6942 | vendor_event_idx >= wiphy->n_vendor_events)) | ||
6943 | return NULL; | ||
6944 | info = &wiphy->vendor_events[vendor_event_idx]; | ||
6945 | break; | ||
6946 | default: | ||
6947 | WARN_ON(1); | ||
6948 | return NULL; | ||
6949 | } | ||
6891 | 6950 | ||
6892 | return __cfg80211_alloc_vendor_skb(rdev, approxlen, 0, 0, | 6951 | return __cfg80211_alloc_vendor_skb(rdev, approxlen, 0, 0, |
6893 | NL80211_CMD_TESTMODE, | 6952 | cmd, attr, info, gfp); |
6894 | NL80211_ATTR_TESTDATA, gfp); | ||
6895 | } | 6953 | } |
6896 | EXPORT_SYMBOL(cfg80211_testmode_alloc_event_skb); | 6954 | EXPORT_SYMBOL(__cfg80211_alloc_event_skb); |
6897 | 6955 | ||
6898 | void cfg80211_testmode_event(struct sk_buff *skb, gfp_t gfp) | 6956 | void __cfg80211_send_event_skb(struct sk_buff *skb, gfp_t gfp) |
6899 | { | 6957 | { |
6900 | struct cfg80211_registered_device *rdev = ((void **)skb->cb)[0]; | 6958 | struct cfg80211_registered_device *rdev = ((void **)skb->cb)[0]; |
6901 | void *hdr = ((void **)skb->cb)[1]; | 6959 | void *hdr = ((void **)skb->cb)[1]; |
6902 | struct nlattr *data = ((void **)skb->cb)[2]; | 6960 | struct nlattr *data = ((void **)skb->cb)[2]; |
6961 | enum nl80211_multicast_groups mcgrp = NL80211_MCGRP_TESTMODE; | ||
6903 | 6962 | ||
6904 | nla_nest_end(skb, data); | 6963 | nla_nest_end(skb, data); |
6905 | genlmsg_end(skb, hdr); | 6964 | genlmsg_end(skb, hdr); |
6965 | |||
6966 | if (data->nla_type == NL80211_ATTR_VENDOR_DATA) | ||
6967 | mcgrp = NL80211_MCGRP_VENDOR; | ||
6968 | |||
6906 | genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), skb, 0, | 6969 | genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), skb, 0, |
6907 | NL80211_MCGRP_TESTMODE, gfp); | 6970 | mcgrp, gfp); |
6908 | } | 6971 | } |
6909 | EXPORT_SYMBOL(cfg80211_testmode_event); | 6972 | EXPORT_SYMBOL(__cfg80211_send_event_skb); |
6910 | #endif | 6973 | #endif |
6911 | 6974 | ||
6912 | static int nl80211_connect(struct sk_buff *skb, struct genl_info *info) | 6975 | static int nl80211_connect(struct sk_buff *skb, struct genl_info *info) |
@@ -9039,7 +9102,7 @@ struct sk_buff *__cfg80211_alloc_reply_skb(struct wiphy *wiphy, | |||
9039 | return __cfg80211_alloc_vendor_skb(rdev, approxlen, | 9102 | return __cfg80211_alloc_vendor_skb(rdev, approxlen, |
9040 | rdev->cur_cmd_info->snd_portid, | 9103 | rdev->cur_cmd_info->snd_portid, |
9041 | rdev->cur_cmd_info->snd_seq, | 9104 | rdev->cur_cmd_info->snd_seq, |
9042 | cmd, attr, GFP_KERNEL); | 9105 | cmd, attr, NULL, GFP_KERNEL); |
9043 | } | 9106 | } |
9044 | EXPORT_SYMBOL(__cfg80211_alloc_reply_skb); | 9107 | EXPORT_SYMBOL(__cfg80211_alloc_reply_skb); |
9045 | 9108 | ||
@@ -9061,6 +9124,57 @@ int cfg80211_vendor_cmd_reply(struct sk_buff *skb) | |||
9061 | EXPORT_SYMBOL_GPL(cfg80211_vendor_cmd_reply); | 9124 | EXPORT_SYMBOL_GPL(cfg80211_vendor_cmd_reply); |
9062 | 9125 | ||
9063 | 9126 | ||
9127 | static int nl80211_set_qos_map(struct sk_buff *skb, | ||
9128 | struct genl_info *info) | ||
9129 | { | ||
9130 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | ||
9131 | struct cfg80211_qos_map *qos_map = NULL; | ||
9132 | struct net_device *dev = info->user_ptr[1]; | ||
9133 | u8 *pos, len, num_des, des_len, des; | ||
9134 | int ret; | ||
9135 | |||
9136 | if (!rdev->ops->set_qos_map) | ||
9137 | return -EOPNOTSUPP; | ||
9138 | |||
9139 | if (info->attrs[NL80211_ATTR_QOS_MAP]) { | ||
9140 | pos = nla_data(info->attrs[NL80211_ATTR_QOS_MAP]); | ||
9141 | len = nla_len(info->attrs[NL80211_ATTR_QOS_MAP]); | ||
9142 | |||
9143 | if (len % 2 || len < IEEE80211_QOS_MAP_LEN_MIN || | ||
9144 | len > IEEE80211_QOS_MAP_LEN_MAX) | ||
9145 | return -EINVAL; | ||
9146 | |||
9147 | qos_map = kzalloc(sizeof(struct cfg80211_qos_map), GFP_KERNEL); | ||
9148 | if (!qos_map) | ||
9149 | return -ENOMEM; | ||
9150 | |||
9151 | num_des = (len - IEEE80211_QOS_MAP_LEN_MIN) >> 1; | ||
9152 | if (num_des) { | ||
9153 | des_len = num_des * | ||
9154 | sizeof(struct cfg80211_dscp_exception); | ||
9155 | memcpy(qos_map->dscp_exception, pos, des_len); | ||
9156 | qos_map->num_des = num_des; | ||
9157 | for (des = 0; des < num_des; des++) { | ||
9158 | if (qos_map->dscp_exception[des].up > 7) { | ||
9159 | kfree(qos_map); | ||
9160 | return -EINVAL; | ||
9161 | } | ||
9162 | } | ||
9163 | pos += des_len; | ||
9164 | } | ||
9165 | memcpy(qos_map->up, pos, IEEE80211_QOS_MAP_LEN_MIN); | ||
9166 | } | ||
9167 | |||
9168 | wdev_lock(dev->ieee80211_ptr); | ||
9169 | ret = nl80211_key_allowed(dev->ieee80211_ptr); | ||
9170 | if (!ret) | ||
9171 | ret = rdev_set_qos_map(rdev, dev, qos_map); | ||
9172 | wdev_unlock(dev->ieee80211_ptr); | ||
9173 | |||
9174 | kfree(qos_map); | ||
9175 | return ret; | ||
9176 | } | ||
9177 | |||
9064 | #define NL80211_FLAG_NEED_WIPHY 0x01 | 9178 | #define NL80211_FLAG_NEED_WIPHY 0x01 |
9065 | #define NL80211_FLAG_NEED_NETDEV 0x02 | 9179 | #define NL80211_FLAG_NEED_NETDEV 0x02 |
9066 | #define NL80211_FLAG_NEED_RTNL 0x04 | 9180 | #define NL80211_FLAG_NEED_RTNL 0x04 |
@@ -9793,6 +9907,14 @@ static const struct genl_ops nl80211_ops[] = { | |||
9793 | .internal_flags = NL80211_FLAG_NEED_WIPHY | | 9907 | .internal_flags = NL80211_FLAG_NEED_WIPHY | |
9794 | NL80211_FLAG_NEED_RTNL, | 9908 | NL80211_FLAG_NEED_RTNL, |
9795 | }, | 9909 | }, |
9910 | { | ||
9911 | .cmd = NL80211_CMD_SET_QOS_MAP, | ||
9912 | .doit = nl80211_set_qos_map, | ||
9913 | .policy = nl80211_policy, | ||
9914 | .flags = GENL_ADMIN_PERM, | ||
9915 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | ||
9916 | NL80211_FLAG_NEED_RTNL, | ||
9917 | }, | ||
9796 | }; | 9918 | }; |
9797 | 9919 | ||
9798 | /* notification functions */ | 9920 | /* notification functions */ |
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h index a6c03ab14a0d..c8e225947adb 100644 --- a/net/wireless/rdev-ops.h +++ b/net/wireless/rdev-ops.h | |||
@@ -932,4 +932,19 @@ static inline int rdev_channel_switch(struct cfg80211_registered_device *rdev, | |||
932 | return ret; | 932 | return ret; |
933 | } | 933 | } |
934 | 934 | ||
935 | static inline int rdev_set_qos_map(struct cfg80211_registered_device *rdev, | ||
936 | struct net_device *dev, | ||
937 | struct cfg80211_qos_map *qos_map) | ||
938 | { | ||
939 | int ret = -EOPNOTSUPP; | ||
940 | |||
941 | if (rdev->ops->set_qos_map) { | ||
942 | trace_rdev_set_qos_map(&rdev->wiphy, dev, qos_map); | ||
943 | ret = rdev->ops->set_qos_map(&rdev->wiphy, dev, qos_map); | ||
944 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
945 | } | ||
946 | |||
947 | return ret; | ||
948 | } | ||
949 | |||
935 | #endif /* __CFG80211_RDEV_OPS */ | 950 | #endif /* __CFG80211_RDEV_OPS */ |
diff --git a/net/wireless/sme.c b/net/wireless/sme.c index d3c5bd7c6b51..5d6e7bb2fc89 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c | |||
@@ -872,6 +872,8 @@ void __cfg80211_disconnected(struct net_device *dev, const u8 *ie, | |||
872 | for (i = 0; i < 6; i++) | 872 | for (i = 0; i < 6; i++) |
873 | rdev_del_key(rdev, dev, i, false, NULL); | 873 | rdev_del_key(rdev, dev, i, false, NULL); |
874 | 874 | ||
875 | rdev_set_qos_map(rdev, dev, NULL); | ||
876 | |||
875 | #ifdef CONFIG_CFG80211_WEXT | 877 | #ifdef CONFIG_CFG80211_WEXT |
876 | memset(&wrqu, 0, sizeof(wrqu)); | 878 | memset(&wrqu, 0, sizeof(wrqu)); |
877 | wrqu.ap_addr.sa_family = ARPHRD_ETHER; | 879 | wrqu.ap_addr.sa_family = ARPHRD_ETHER; |
diff --git a/net/wireless/trace.h b/net/wireless/trace.h index f7aa7a72d9bc..fbcc23edee54 100644 --- a/net/wireless/trace.h +++ b/net/wireless/trace.h | |||
@@ -186,6 +186,28 @@ | |||
186 | 186 | ||
187 | #define BOOL_TO_STR(bo) (bo) ? "true" : "false" | 187 | #define BOOL_TO_STR(bo) (bo) ? "true" : "false" |
188 | 188 | ||
189 | #define QOS_MAP_ENTRY __field(u8, num_des) \ | ||
190 | __array(u8, dscp_exception, \ | ||
191 | 2 * IEEE80211_QOS_MAP_MAX_EX) \ | ||
192 | __array(u8, up, IEEE80211_QOS_MAP_LEN_MIN) | ||
193 | #define QOS_MAP_ASSIGN(qos_map) \ | ||
194 | do { \ | ||
195 | if ((qos_map)) { \ | ||
196 | __entry->num_des = (qos_map)->num_des; \ | ||
197 | memcpy(__entry->dscp_exception, \ | ||
198 | &(qos_map)->dscp_exception, \ | ||
199 | 2 * IEEE80211_QOS_MAP_MAX_EX); \ | ||
200 | memcpy(__entry->up, &(qos_map)->up, \ | ||
201 | IEEE80211_QOS_MAP_LEN_MIN); \ | ||
202 | } else { \ | ||
203 | __entry->num_des = 0; \ | ||
204 | memset(__entry->dscp_exception, 0, \ | ||
205 | 2 * IEEE80211_QOS_MAP_MAX_EX); \ | ||
206 | memset(__entry->up, 0, \ | ||
207 | IEEE80211_QOS_MAP_LEN_MIN); \ | ||
208 | } \ | ||
209 | } while (0) | ||
210 | |||
189 | /************************************************************* | 211 | /************************************************************* |
190 | * rdev->ops traces * | 212 | * rdev->ops traces * |
191 | *************************************************************/ | 213 | *************************************************************/ |
@@ -1875,6 +1897,24 @@ TRACE_EVENT(rdev_channel_switch, | |||
1875 | __entry->counter_offset_presp) | 1897 | __entry->counter_offset_presp) |
1876 | ); | 1898 | ); |
1877 | 1899 | ||
1900 | TRACE_EVENT(rdev_set_qos_map, | ||
1901 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, | ||
1902 | struct cfg80211_qos_map *qos_map), | ||
1903 | TP_ARGS(wiphy, netdev, qos_map), | ||
1904 | TP_STRUCT__entry( | ||
1905 | WIPHY_ENTRY | ||
1906 | NETDEV_ENTRY | ||
1907 | QOS_MAP_ENTRY | ||
1908 | ), | ||
1909 | TP_fast_assign( | ||
1910 | WIPHY_ASSIGN; | ||
1911 | NETDEV_ASSIGN; | ||
1912 | QOS_MAP_ASSIGN(qos_map); | ||
1913 | ), | ||
1914 | TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", num_des: %u", | ||
1915 | WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->num_des) | ||
1916 | ); | ||
1917 | |||
1878 | /************************************************************* | 1918 | /************************************************************* |
1879 | * cfg80211 exported functions traces * | 1919 | * cfg80211 exported functions traces * |
1880 | *************************************************************/ | 1920 | *************************************************************/ |
diff --git a/net/wireless/util.c b/net/wireless/util.c index 935dea9485da..5618888853b2 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c | |||
@@ -689,7 +689,8 @@ void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list, | |||
689 | EXPORT_SYMBOL(ieee80211_amsdu_to_8023s); | 689 | EXPORT_SYMBOL(ieee80211_amsdu_to_8023s); |
690 | 690 | ||
691 | /* Given a data frame determine the 802.1p/1d tag to use. */ | 691 | /* Given a data frame determine the 802.1p/1d tag to use. */ |
692 | unsigned int cfg80211_classify8021d(struct sk_buff *skb) | 692 | unsigned int cfg80211_classify8021d(struct sk_buff *skb, |
693 | struct cfg80211_qos_map *qos_map) | ||
693 | { | 694 | { |
694 | unsigned int dscp; | 695 | unsigned int dscp; |
695 | unsigned char vlan_priority; | 696 | unsigned char vlan_priority; |
@@ -720,6 +721,21 @@ unsigned int cfg80211_classify8021d(struct sk_buff *skb) | |||
720 | return 0; | 721 | return 0; |
721 | } | 722 | } |
722 | 723 | ||
724 | if (qos_map) { | ||
725 | unsigned int i, tmp_dscp = dscp >> 2; | ||
726 | |||
727 | for (i = 0; i < qos_map->num_des; i++) { | ||
728 | if (tmp_dscp == qos_map->dscp_exception[i].dscp) | ||
729 | return qos_map->dscp_exception[i].up; | ||
730 | } | ||
731 | |||
732 | for (i = 0; i < 8; i++) { | ||
733 | if (tmp_dscp >= qos_map->up[i].low && | ||
734 | tmp_dscp <= qos_map->up[i].high) | ||
735 | return i; | ||
736 | } | ||
737 | } | ||
738 | |||
723 | return dscp >> 5; | 739 | return dscp >> 5; |
724 | } | 740 | } |
725 | EXPORT_SYMBOL(cfg80211_classify8021d); | 741 | EXPORT_SYMBOL(cfg80211_classify8021d); |
@@ -863,6 +879,7 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, | |||
863 | 879 | ||
864 | dev->ieee80211_ptr->use_4addr = false; | 880 | dev->ieee80211_ptr->use_4addr = false; |
865 | dev->ieee80211_ptr->mesh_id_up_len = 0; | 881 | dev->ieee80211_ptr->mesh_id_up_len = 0; |
882 | rdev_set_qos_map(rdev, dev, NULL); | ||
866 | 883 | ||
867 | switch (otype) { | 884 | switch (otype) { |
868 | case NL80211_IFTYPE_AP: | 885 | case NL80211_IFTYPE_AP: |