diff options
author | John W. Linville <linville@tuxdriver.com> | 2011-11-17 13:11:43 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-11-17 13:11:43 -0500 |
commit | e11c259f745889b55bc5596ca78271f2f5cf08d2 (patch) | |
tree | 5025f0bf9093e84d0643beb9097249c176dbbea7 /net | |
parent | 8d26784cf0d04c1238e906efdd5de76439cb0a1e (diff) | |
parent | b4487c2d0edaf1332d7a9f11b5661044955ef5e2 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem
Conflicts:
include/net/bluetooth/bluetooth.h
Diffstat (limited to 'net')
59 files changed, 3381 insertions, 1458 deletions
diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c index 91bcd3a961ec..a6cd856046ab 100644 --- a/net/bluetooth/bnep/core.c +++ b/net/bluetooth/bnep/core.c | |||
@@ -65,15 +65,13 @@ static DECLARE_RWSEM(bnep_session_sem); | |||
65 | static struct bnep_session *__bnep_get_session(u8 *dst) | 65 | static struct bnep_session *__bnep_get_session(u8 *dst) |
66 | { | 66 | { |
67 | struct bnep_session *s; | 67 | struct bnep_session *s; |
68 | struct list_head *p; | ||
69 | 68 | ||
70 | BT_DBG(""); | 69 | BT_DBG(""); |
71 | 70 | ||
72 | list_for_each(p, &bnep_session_list) { | 71 | list_for_each_entry(s, &bnep_session_list, list) |
73 | s = list_entry(p, struct bnep_session, list); | ||
74 | if (!compare_ether_addr(dst, s->eh.h_source)) | 72 | if (!compare_ether_addr(dst, s->eh.h_source)) |
75 | return s; | 73 | return s; |
76 | } | 74 | |
77 | return NULL; | 75 | return NULL; |
78 | } | 76 | } |
79 | 77 | ||
@@ -667,17 +665,14 @@ static void __bnep_copy_ci(struct bnep_conninfo *ci, struct bnep_session *s) | |||
667 | 665 | ||
668 | int bnep_get_connlist(struct bnep_connlist_req *req) | 666 | int bnep_get_connlist(struct bnep_connlist_req *req) |
669 | { | 667 | { |
670 | struct list_head *p; | 668 | struct bnep_session *s; |
671 | int err = 0, n = 0; | 669 | int err = 0, n = 0; |
672 | 670 | ||
673 | down_read(&bnep_session_sem); | 671 | down_read(&bnep_session_sem); |
674 | 672 | ||
675 | list_for_each(p, &bnep_session_list) { | 673 | list_for_each_entry(s, &bnep_session_list, list) { |
676 | struct bnep_session *s; | ||
677 | struct bnep_conninfo ci; | 674 | struct bnep_conninfo ci; |
678 | 675 | ||
679 | s = list_entry(p, struct bnep_session, list); | ||
680 | |||
681 | __bnep_copy_ci(&ci, s); | 676 | __bnep_copy_ci(&ci, s); |
682 | 677 | ||
683 | if (copy_to_user(req->ci, &ci, sizeof(ci))) { | 678 | if (copy_to_user(req->ci, &ci, sizeof(ci))) { |
diff --git a/net/bluetooth/cmtp/core.c b/net/bluetooth/cmtp/core.c index 7d00ddf9e9dc..9e8940b24bba 100644 --- a/net/bluetooth/cmtp/core.c +++ b/net/bluetooth/cmtp/core.c | |||
@@ -53,15 +53,13 @@ static LIST_HEAD(cmtp_session_list); | |||
53 | static struct cmtp_session *__cmtp_get_session(bdaddr_t *bdaddr) | 53 | static struct cmtp_session *__cmtp_get_session(bdaddr_t *bdaddr) |
54 | { | 54 | { |
55 | struct cmtp_session *session; | 55 | struct cmtp_session *session; |
56 | struct list_head *p; | ||
57 | 56 | ||
58 | BT_DBG(""); | 57 | BT_DBG(""); |
59 | 58 | ||
60 | list_for_each(p, &cmtp_session_list) { | 59 | list_for_each_entry(session, &cmtp_session_list, list) |
61 | session = list_entry(p, struct cmtp_session, list); | ||
62 | if (!bacmp(bdaddr, &session->bdaddr)) | 60 | if (!bacmp(bdaddr, &session->bdaddr)) |
63 | return session; | 61 | return session; |
64 | } | 62 | |
65 | return NULL; | 63 | return NULL; |
66 | } | 64 | } |
67 | 65 | ||
@@ -431,19 +429,16 @@ int cmtp_del_connection(struct cmtp_conndel_req *req) | |||
431 | 429 | ||
432 | int cmtp_get_connlist(struct cmtp_connlist_req *req) | 430 | int cmtp_get_connlist(struct cmtp_connlist_req *req) |
433 | { | 431 | { |
434 | struct list_head *p; | 432 | struct cmtp_session *session; |
435 | int err = 0, n = 0; | 433 | int err = 0, n = 0; |
436 | 434 | ||
437 | BT_DBG(""); | 435 | BT_DBG(""); |
438 | 436 | ||
439 | down_read(&cmtp_session_sem); | 437 | down_read(&cmtp_session_sem); |
440 | 438 | ||
441 | list_for_each(p, &cmtp_session_list) { | 439 | list_for_each_entry(session, &cmtp_session_list, list) { |
442 | struct cmtp_session *session; | ||
443 | struct cmtp_conninfo ci; | 440 | struct cmtp_conninfo ci; |
444 | 441 | ||
445 | session = list_entry(p, struct cmtp_session, list); | ||
446 | |||
447 | __cmtp_copy_session(session, &ci); | 442 | __cmtp_copy_session(session, &ci); |
448 | 443 | ||
449 | if (copy_to_user(req->ci, &ci, sizeof(ci))) { | 444 | if (copy_to_user(req->ci, &ci, sizeof(ci))) { |
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index c1c597e3e198..de0b93e45980 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c | |||
@@ -374,6 +374,8 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst) | |||
374 | 374 | ||
375 | skb_queue_head_init(&conn->data_q); | 375 | skb_queue_head_init(&conn->data_q); |
376 | 376 | ||
377 | hci_chan_hash_init(conn); | ||
378 | |||
377 | setup_timer(&conn->disc_timer, hci_conn_timeout, (unsigned long)conn); | 379 | setup_timer(&conn->disc_timer, hci_conn_timeout, (unsigned long)conn); |
378 | setup_timer(&conn->idle_timer, hci_conn_idle, (unsigned long)conn); | 380 | setup_timer(&conn->idle_timer, hci_conn_idle, (unsigned long)conn); |
379 | setup_timer(&conn->auto_accept_timer, hci_conn_auto_accept, | 381 | setup_timer(&conn->auto_accept_timer, hci_conn_auto_accept, |
@@ -432,6 +434,8 @@ int hci_conn_del(struct hci_conn *conn) | |||
432 | 434 | ||
433 | tasklet_disable(&hdev->tx_task); | 435 | tasklet_disable(&hdev->tx_task); |
434 | 436 | ||
437 | hci_chan_hash_flush(conn); | ||
438 | |||
435 | hci_conn_hash_del(hdev, conn); | 439 | hci_conn_hash_del(hdev, conn); |
436 | if (hdev->notify) | 440 | if (hdev->notify) |
437 | hdev->notify(hdev, HCI_NOTIFY_CONN_DEL); | 441 | hdev->notify(hdev, HCI_NOTIFY_CONN_DEL); |
@@ -453,16 +457,13 @@ int hci_conn_del(struct hci_conn *conn) | |||
453 | struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src) | 457 | struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src) |
454 | { | 458 | { |
455 | int use_src = bacmp(src, BDADDR_ANY); | 459 | int use_src = bacmp(src, BDADDR_ANY); |
456 | struct hci_dev *hdev = NULL; | 460 | struct hci_dev *hdev = NULL, *d; |
457 | struct list_head *p; | ||
458 | 461 | ||
459 | BT_DBG("%s -> %s", batostr(src), batostr(dst)); | 462 | BT_DBG("%s -> %s", batostr(src), batostr(dst)); |
460 | 463 | ||
461 | read_lock_bh(&hci_dev_list_lock); | 464 | read_lock_bh(&hci_dev_list_lock); |
462 | 465 | ||
463 | list_for_each(p, &hci_dev_list) { | 466 | list_for_each_entry(d, &hci_dev_list, list) { |
464 | struct hci_dev *d = list_entry(p, struct hci_dev, list); | ||
465 | |||
466 | if (!test_bit(HCI_UP, &d->flags) || test_bit(HCI_RAW, &d->flags)) | 467 | if (!test_bit(HCI_UP, &d->flags) || test_bit(HCI_RAW, &d->flags)) |
467 | continue; | 468 | continue; |
468 | 469 | ||
@@ -673,7 +674,7 @@ int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type) | |||
673 | goto encrypt; | 674 | goto encrypt; |
674 | 675 | ||
675 | auth: | 676 | auth: |
676 | if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) | 677 | if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) |
677 | return 0; | 678 | return 0; |
678 | 679 | ||
679 | if (!hci_conn_auth(conn, sec_level, auth_type)) | 680 | if (!hci_conn_auth(conn, sec_level, auth_type)) |
@@ -819,7 +820,7 @@ void hci_conn_hash_flush(struct hci_dev *hdev) | |||
819 | 820 | ||
820 | c->state = BT_CLOSED; | 821 | c->state = BT_CLOSED; |
821 | 822 | ||
822 | hci_proto_disconn_cfm(c, 0x16); | 823 | hci_proto_disconn_cfm(c, HCI_ERROR_LOCAL_HOST_TERM); |
823 | hci_conn_del(c); | 824 | hci_conn_del(c); |
824 | } | 825 | } |
825 | } | 826 | } |
@@ -855,10 +856,10 @@ EXPORT_SYMBOL(hci_conn_put_device); | |||
855 | 856 | ||
856 | int hci_get_conn_list(void __user *arg) | 857 | int hci_get_conn_list(void __user *arg) |
857 | { | 858 | { |
859 | register struct hci_conn *c; | ||
858 | struct hci_conn_list_req req, *cl; | 860 | struct hci_conn_list_req req, *cl; |
859 | struct hci_conn_info *ci; | 861 | struct hci_conn_info *ci; |
860 | struct hci_dev *hdev; | 862 | struct hci_dev *hdev; |
861 | struct list_head *p; | ||
862 | int n = 0, size, err; | 863 | int n = 0, size, err; |
863 | 864 | ||
864 | if (copy_from_user(&req, arg, sizeof(req))) | 865 | if (copy_from_user(&req, arg, sizeof(req))) |
@@ -882,10 +883,7 @@ int hci_get_conn_list(void __user *arg) | |||
882 | ci = cl->conn_info; | 883 | ci = cl->conn_info; |
883 | 884 | ||
884 | hci_dev_lock_bh(hdev); | 885 | hci_dev_lock_bh(hdev); |
885 | list_for_each(p, &hdev->conn_hash.list) { | 886 | list_for_each_entry(c, &hdev->conn_hash.list, list) { |
886 | register struct hci_conn *c; | ||
887 | c = list_entry(p, struct hci_conn, list); | ||
888 | |||
889 | bacpy(&(ci + n)->bdaddr, &c->dst); | 887 | bacpy(&(ci + n)->bdaddr, &c->dst); |
890 | (ci + n)->handle = c->handle; | 888 | (ci + n)->handle = c->handle; |
891 | (ci + n)->type = c->type; | 889 | (ci + n)->type = c->type; |
@@ -956,3 +954,52 @@ int hci_get_auth_info(struct hci_dev *hdev, void __user *arg) | |||
956 | 954 | ||
957 | return copy_to_user(arg, &req, sizeof(req)) ? -EFAULT : 0; | 955 | return copy_to_user(arg, &req, sizeof(req)) ? -EFAULT : 0; |
958 | } | 956 | } |
957 | |||
958 | struct hci_chan *hci_chan_create(struct hci_conn *conn) | ||
959 | { | ||
960 | struct hci_dev *hdev = conn->hdev; | ||
961 | struct hci_chan *chan; | ||
962 | |||
963 | BT_DBG("%s conn %p", hdev->name, conn); | ||
964 | |||
965 | chan = kzalloc(sizeof(struct hci_chan), GFP_ATOMIC); | ||
966 | if (!chan) | ||
967 | return NULL; | ||
968 | |||
969 | chan->conn = conn; | ||
970 | skb_queue_head_init(&chan->data_q); | ||
971 | |||
972 | tasklet_disable(&hdev->tx_task); | ||
973 | hci_chan_hash_add(conn, chan); | ||
974 | tasklet_enable(&hdev->tx_task); | ||
975 | |||
976 | return chan; | ||
977 | } | ||
978 | |||
979 | int hci_chan_del(struct hci_chan *chan) | ||
980 | { | ||
981 | struct hci_conn *conn = chan->conn; | ||
982 | struct hci_dev *hdev = conn->hdev; | ||
983 | |||
984 | BT_DBG("%s conn %p chan %p", hdev->name, conn, chan); | ||
985 | |||
986 | tasklet_disable(&hdev->tx_task); | ||
987 | hci_chan_hash_del(conn, chan); | ||
988 | tasklet_enable(&hdev->tx_task); | ||
989 | |||
990 | skb_queue_purge(&chan->data_q); | ||
991 | kfree(chan); | ||
992 | |||
993 | return 0; | ||
994 | } | ||
995 | |||
996 | void hci_chan_hash_flush(struct hci_conn *conn) | ||
997 | { | ||
998 | struct hci_chan_hash *h = &conn->chan_hash; | ||
999 | struct hci_chan *chan, *tmp; | ||
1000 | |||
1001 | BT_DBG("conn %p", conn); | ||
1002 | |||
1003 | list_for_each_entry_safe(chan, tmp, &h->list, list) | ||
1004 | hci_chan_del(chan); | ||
1005 | } | ||
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index be84ae33ae36..fb3feeb185d7 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c | |||
@@ -319,8 +319,7 @@ static void hci_linkpol_req(struct hci_dev *hdev, unsigned long opt) | |||
319 | * Device is held on return. */ | 319 | * Device is held on return. */ |
320 | struct hci_dev *hci_dev_get(int index) | 320 | struct hci_dev *hci_dev_get(int index) |
321 | { | 321 | { |
322 | struct hci_dev *hdev = NULL; | 322 | struct hci_dev *hdev = NULL, *d; |
323 | struct list_head *p; | ||
324 | 323 | ||
325 | BT_DBG("%d", index); | 324 | BT_DBG("%d", index); |
326 | 325 | ||
@@ -328,8 +327,7 @@ struct hci_dev *hci_dev_get(int index) | |||
328 | return NULL; | 327 | return NULL; |
329 | 328 | ||
330 | read_lock(&hci_dev_list_lock); | 329 | read_lock(&hci_dev_list_lock); |
331 | list_for_each(p, &hci_dev_list) { | 330 | list_for_each_entry(d, &hci_dev_list, list) { |
332 | struct hci_dev *d = list_entry(p, struct hci_dev, list); | ||
333 | if (d->id == index) { | 331 | if (d->id == index) { |
334 | hdev = hci_dev_hold(d); | 332 | hdev = hci_dev_hold(d); |
335 | break; | 333 | break; |
@@ -551,8 +549,11 @@ int hci_dev_open(__u16 dev) | |||
551 | hci_dev_hold(hdev); | 549 | hci_dev_hold(hdev); |
552 | set_bit(HCI_UP, &hdev->flags); | 550 | set_bit(HCI_UP, &hdev->flags); |
553 | hci_notify(hdev, HCI_DEV_UP); | 551 | hci_notify(hdev, HCI_DEV_UP); |
554 | if (!test_bit(HCI_SETUP, &hdev->flags)) | 552 | if (!test_bit(HCI_SETUP, &hdev->flags)) { |
555 | mgmt_powered(hdev->id, 1); | 553 | hci_dev_lock_bh(hdev); |
554 | mgmt_powered(hdev, 1); | ||
555 | hci_dev_unlock_bh(hdev); | ||
556 | } | ||
556 | } else { | 557 | } else { |
557 | /* Init failed, cleanup */ | 558 | /* Init failed, cleanup */ |
558 | tasklet_kill(&hdev->rx_task); | 559 | tasklet_kill(&hdev->rx_task); |
@@ -597,6 +598,14 @@ static int hci_dev_do_close(struct hci_dev *hdev) | |||
597 | tasklet_kill(&hdev->rx_task); | 598 | tasklet_kill(&hdev->rx_task); |
598 | tasklet_kill(&hdev->tx_task); | 599 | tasklet_kill(&hdev->tx_task); |
599 | 600 | ||
601 | if (hdev->discov_timeout > 0) { | ||
602 | cancel_delayed_work(&hdev->discov_off); | ||
603 | hdev->discov_timeout = 0; | ||
604 | } | ||
605 | |||
606 | if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->flags)) | ||
607 | cancel_delayed_work(&hdev->power_off); | ||
608 | |||
600 | hci_dev_lock_bh(hdev); | 609 | hci_dev_lock_bh(hdev); |
601 | inquiry_cache_flush(hdev); | 610 | inquiry_cache_flush(hdev); |
602 | hci_conn_hash_flush(hdev); | 611 | hci_conn_hash_flush(hdev); |
@@ -636,7 +645,9 @@ static int hci_dev_do_close(struct hci_dev *hdev) | |||
636 | * and no tasks are scheduled. */ | 645 | * and no tasks are scheduled. */ |
637 | hdev->close(hdev); | 646 | hdev->close(hdev); |
638 | 647 | ||
639 | mgmt_powered(hdev->id, 0); | 648 | hci_dev_lock_bh(hdev); |
649 | mgmt_powered(hdev, 0); | ||
650 | hci_dev_unlock_bh(hdev); | ||
640 | 651 | ||
641 | /* Clear flags */ | 652 | /* Clear flags */ |
642 | hdev->flags = 0; | 653 | hdev->flags = 0; |
@@ -794,9 +805,9 @@ int hci_dev_cmd(unsigned int cmd, void __user *arg) | |||
794 | 805 | ||
795 | int hci_get_dev_list(void __user *arg) | 806 | int hci_get_dev_list(void __user *arg) |
796 | { | 807 | { |
808 | struct hci_dev *hdev; | ||
797 | struct hci_dev_list_req *dl; | 809 | struct hci_dev_list_req *dl; |
798 | struct hci_dev_req *dr; | 810 | struct hci_dev_req *dr; |
799 | struct list_head *p; | ||
800 | int n = 0, size, err; | 811 | int n = 0, size, err; |
801 | __u16 dev_num; | 812 | __u16 dev_num; |
802 | 813 | ||
@@ -815,12 +826,9 @@ int hci_get_dev_list(void __user *arg) | |||
815 | dr = dl->dev_req; | 826 | dr = dl->dev_req; |
816 | 827 | ||
817 | read_lock_bh(&hci_dev_list_lock); | 828 | read_lock_bh(&hci_dev_list_lock); |
818 | list_for_each(p, &hci_dev_list) { | 829 | list_for_each_entry(hdev, &hci_dev_list, list) { |
819 | struct hci_dev *hdev; | 830 | if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->flags)) |
820 | 831 | cancel_delayed_work(&hdev->power_off); | |
821 | hdev = list_entry(p, struct hci_dev, list); | ||
822 | |||
823 | hci_del_off_timer(hdev); | ||
824 | 832 | ||
825 | if (!test_bit(HCI_MGMT, &hdev->flags)) | 833 | if (!test_bit(HCI_MGMT, &hdev->flags)) |
826 | set_bit(HCI_PAIRABLE, &hdev->flags); | 834 | set_bit(HCI_PAIRABLE, &hdev->flags); |
@@ -855,7 +863,8 @@ int hci_get_dev_info(void __user *arg) | |||
855 | if (!hdev) | 863 | if (!hdev) |
856 | return -ENODEV; | 864 | return -ENODEV; |
857 | 865 | ||
858 | hci_del_off_timer(hdev); | 866 | if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->flags)) |
867 | cancel_delayed_work_sync(&hdev->power_off); | ||
859 | 868 | ||
860 | if (!test_bit(HCI_MGMT, &hdev->flags)) | 869 | if (!test_bit(HCI_MGMT, &hdev->flags)) |
861 | set_bit(HCI_PAIRABLE, &hdev->flags); | 870 | set_bit(HCI_PAIRABLE, &hdev->flags); |
@@ -912,6 +921,7 @@ struct hci_dev *hci_alloc_dev(void) | |||
912 | if (!hdev) | 921 | if (!hdev) |
913 | return NULL; | 922 | return NULL; |
914 | 923 | ||
924 | hci_init_sysfs(hdev); | ||
915 | skb_queue_head_init(&hdev->driver_init); | 925 | skb_queue_head_init(&hdev->driver_init); |
916 | 926 | ||
917 | return hdev; | 927 | return hdev; |
@@ -938,39 +948,41 @@ static void hci_power_on(struct work_struct *work) | |||
938 | return; | 948 | return; |
939 | 949 | ||
940 | if (test_bit(HCI_AUTO_OFF, &hdev->flags)) | 950 | if (test_bit(HCI_AUTO_OFF, &hdev->flags)) |
941 | mod_timer(&hdev->off_timer, | 951 | queue_delayed_work(hdev->workqueue, &hdev->power_off, |
942 | jiffies + msecs_to_jiffies(AUTO_OFF_TIMEOUT)); | 952 | msecs_to_jiffies(AUTO_OFF_TIMEOUT)); |
943 | 953 | ||
944 | if (test_and_clear_bit(HCI_SETUP, &hdev->flags)) | 954 | if (test_and_clear_bit(HCI_SETUP, &hdev->flags)) |
945 | mgmt_index_added(hdev->id); | 955 | mgmt_index_added(hdev); |
946 | } | 956 | } |
947 | 957 | ||
948 | static void hci_power_off(struct work_struct *work) | 958 | static void hci_power_off(struct work_struct *work) |
949 | { | 959 | { |
950 | struct hci_dev *hdev = container_of(work, struct hci_dev, power_off); | 960 | struct hci_dev *hdev = container_of(work, struct hci_dev, |
961 | power_off.work); | ||
951 | 962 | ||
952 | BT_DBG("%s", hdev->name); | 963 | BT_DBG("%s", hdev->name); |
953 | 964 | ||
965 | clear_bit(HCI_AUTO_OFF, &hdev->flags); | ||
966 | |||
954 | hci_dev_close(hdev->id); | 967 | hci_dev_close(hdev->id); |
955 | } | 968 | } |
956 | 969 | ||
957 | static void hci_auto_off(unsigned long data) | 970 | static void hci_discov_off(struct work_struct *work) |
958 | { | 971 | { |
959 | struct hci_dev *hdev = (struct hci_dev *) data; | 972 | struct hci_dev *hdev; |
973 | u8 scan = SCAN_PAGE; | ||
974 | |||
975 | hdev = container_of(work, struct hci_dev, discov_off.work); | ||
960 | 976 | ||
961 | BT_DBG("%s", hdev->name); | 977 | BT_DBG("%s", hdev->name); |
962 | 978 | ||
963 | clear_bit(HCI_AUTO_OFF, &hdev->flags); | 979 | hci_dev_lock_bh(hdev); |
964 | 980 | ||
965 | queue_work(hdev->workqueue, &hdev->power_off); | 981 | hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, sizeof(scan), &scan); |
966 | } | ||
967 | 982 | ||
968 | void hci_del_off_timer(struct hci_dev *hdev) | 983 | hdev->discov_timeout = 0; |
969 | { | ||
970 | BT_DBG("%s", hdev->name); | ||
971 | 984 | ||
972 | clear_bit(HCI_AUTO_OFF, &hdev->flags); | 985 | hci_dev_unlock_bh(hdev); |
973 | del_timer(&hdev->off_timer); | ||
974 | } | 986 | } |
975 | 987 | ||
976 | int hci_uuids_clear(struct hci_dev *hdev) | 988 | int hci_uuids_clear(struct hci_dev *hdev) |
@@ -1007,16 +1019,11 @@ int hci_link_keys_clear(struct hci_dev *hdev) | |||
1007 | 1019 | ||
1008 | struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) | 1020 | struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) |
1009 | { | 1021 | { |
1010 | struct list_head *p; | 1022 | struct link_key *k; |
1011 | |||
1012 | list_for_each(p, &hdev->link_keys) { | ||
1013 | struct link_key *k; | ||
1014 | |||
1015 | k = list_entry(p, struct link_key, list); | ||
1016 | 1023 | ||
1024 | list_for_each_entry(k, &hdev->link_keys, list) | ||
1017 | if (bacmp(bdaddr, &k->bdaddr) == 0) | 1025 | if (bacmp(bdaddr, &k->bdaddr) == 0) |
1018 | return k; | 1026 | return k; |
1019 | } | ||
1020 | 1027 | ||
1021 | return NULL; | 1028 | return NULL; |
1022 | } | 1029 | } |
@@ -1138,7 +1145,7 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key, | |||
1138 | 1145 | ||
1139 | persistent = hci_persistent_key(hdev, conn, type, old_key_type); | 1146 | persistent = hci_persistent_key(hdev, conn, type, old_key_type); |
1140 | 1147 | ||
1141 | mgmt_new_key(hdev->id, key, persistent); | 1148 | mgmt_new_link_key(hdev, key, persistent); |
1142 | 1149 | ||
1143 | if (!persistent) { | 1150 | if (!persistent) { |
1144 | list_del(&key->list); | 1151 | list_del(&key->list); |
@@ -1181,7 +1188,7 @@ int hci_add_ltk(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr, | |||
1181 | memcpy(id->rand, rand, sizeof(id->rand)); | 1188 | memcpy(id->rand, rand, sizeof(id->rand)); |
1182 | 1189 | ||
1183 | if (new_key) | 1190 | if (new_key) |
1184 | mgmt_new_key(hdev->id, key, old_key_type); | 1191 | mgmt_new_link_key(hdev, key, old_key_type); |
1185 | 1192 | ||
1186 | return 0; | 1193 | return 0; |
1187 | } | 1194 | } |
@@ -1279,16 +1286,11 @@ int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash, | |||
1279 | struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, | 1286 | struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, |
1280 | bdaddr_t *bdaddr) | 1287 | bdaddr_t *bdaddr) |
1281 | { | 1288 | { |
1282 | struct list_head *p; | 1289 | struct bdaddr_list *b; |
1283 | |||
1284 | list_for_each(p, &hdev->blacklist) { | ||
1285 | struct bdaddr_list *b; | ||
1286 | |||
1287 | b = list_entry(p, struct bdaddr_list, list); | ||
1288 | 1290 | ||
1291 | list_for_each_entry(b, &hdev->blacklist, list) | ||
1289 | if (bacmp(bdaddr, &b->bdaddr) == 0) | 1292 | if (bacmp(bdaddr, &b->bdaddr) == 0) |
1290 | return b; | 1293 | return b; |
1291 | } | ||
1292 | 1294 | ||
1293 | return NULL; | 1295 | return NULL; |
1294 | } | 1296 | } |
@@ -1327,7 +1329,7 @@ int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr) | |||
1327 | 1329 | ||
1328 | list_add(&entry->list, &hdev->blacklist); | 1330 | list_add(&entry->list, &hdev->blacklist); |
1329 | 1331 | ||
1330 | return mgmt_device_blocked(hdev->id, bdaddr); | 1332 | return mgmt_device_blocked(hdev, bdaddr); |
1331 | } | 1333 | } |
1332 | 1334 | ||
1333 | int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr) | 1335 | int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr) |
@@ -1346,7 +1348,7 @@ int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr) | |||
1346 | list_del(&entry->list); | 1348 | list_del(&entry->list); |
1347 | kfree(entry); | 1349 | kfree(entry); |
1348 | 1350 | ||
1349 | return mgmt_device_unblocked(hdev->id, bdaddr); | 1351 | return mgmt_device_unblocked(hdev, bdaddr); |
1350 | } | 1352 | } |
1351 | 1353 | ||
1352 | static void hci_clear_adv_cache(unsigned long arg) | 1354 | static void hci_clear_adv_cache(unsigned long arg) |
@@ -1425,7 +1427,7 @@ int hci_add_adv_entry(struct hci_dev *hdev, | |||
1425 | int hci_register_dev(struct hci_dev *hdev) | 1427 | int hci_register_dev(struct hci_dev *hdev) |
1426 | { | 1428 | { |
1427 | struct list_head *head = &hci_dev_list, *p; | 1429 | struct list_head *head = &hci_dev_list, *p; |
1428 | int i, id = 0; | 1430 | int i, id, error; |
1429 | 1431 | ||
1430 | BT_DBG("%p name %s bus %d owner %p", hdev, hdev->name, | 1432 | BT_DBG("%p name %s bus %d owner %p", hdev, hdev->name, |
1431 | hdev->bus, hdev->owner); | 1433 | hdev->bus, hdev->owner); |
@@ -1433,6 +1435,11 @@ int hci_register_dev(struct hci_dev *hdev) | |||
1433 | if (!hdev->open || !hdev->close || !hdev->destruct) | 1435 | if (!hdev->open || !hdev->close || !hdev->destruct) |
1434 | return -EINVAL; | 1436 | return -EINVAL; |
1435 | 1437 | ||
1438 | /* Do not allow HCI_AMP devices to register at index 0, | ||
1439 | * so the index can be used as the AMP controller ID. | ||
1440 | */ | ||
1441 | id = (hdev->dev_type == HCI_BREDR) ? 0 : 1; | ||
1442 | |||
1436 | write_lock_bh(&hci_dev_list_lock); | 1443 | write_lock_bh(&hci_dev_list_lock); |
1437 | 1444 | ||
1438 | /* Find first available device id */ | 1445 | /* Find first available device id */ |
@@ -1479,6 +1486,8 @@ int hci_register_dev(struct hci_dev *hdev) | |||
1479 | 1486 | ||
1480 | hci_conn_hash_init(hdev); | 1487 | hci_conn_hash_init(hdev); |
1481 | 1488 | ||
1489 | INIT_LIST_HEAD(&hdev->mgmt_pending); | ||
1490 | |||
1482 | INIT_LIST_HEAD(&hdev->blacklist); | 1491 | INIT_LIST_HEAD(&hdev->blacklist); |
1483 | 1492 | ||
1484 | INIT_LIST_HEAD(&hdev->uuids); | 1493 | INIT_LIST_HEAD(&hdev->uuids); |
@@ -1492,8 +1501,9 @@ int hci_register_dev(struct hci_dev *hdev) | |||
1492 | (unsigned long) hdev); | 1501 | (unsigned long) hdev); |
1493 | 1502 | ||
1494 | INIT_WORK(&hdev->power_on, hci_power_on); | 1503 | INIT_WORK(&hdev->power_on, hci_power_on); |
1495 | INIT_WORK(&hdev->power_off, hci_power_off); | 1504 | INIT_DELAYED_WORK(&hdev->power_off, hci_power_off); |
1496 | setup_timer(&hdev->off_timer, hci_auto_off, (unsigned long) hdev); | 1505 | |
1506 | INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off); | ||
1497 | 1507 | ||
1498 | memset(&hdev->stat, 0, sizeof(struct hci_dev_stats)); | 1508 | memset(&hdev->stat, 0, sizeof(struct hci_dev_stats)); |
1499 | 1509 | ||
@@ -1502,10 +1512,14 @@ int hci_register_dev(struct hci_dev *hdev) | |||
1502 | write_unlock_bh(&hci_dev_list_lock); | 1512 | write_unlock_bh(&hci_dev_list_lock); |
1503 | 1513 | ||
1504 | hdev->workqueue = create_singlethread_workqueue(hdev->name); | 1514 | hdev->workqueue = create_singlethread_workqueue(hdev->name); |
1505 | if (!hdev->workqueue) | 1515 | if (!hdev->workqueue) { |
1506 | goto nomem; | 1516 | error = -ENOMEM; |
1517 | goto err; | ||
1518 | } | ||
1507 | 1519 | ||
1508 | hci_register_sysfs(hdev); | 1520 | error = hci_add_sysfs(hdev); |
1521 | if (error < 0) | ||
1522 | goto err_wqueue; | ||
1509 | 1523 | ||
1510 | hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev, | 1524 | hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev, |
1511 | RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, hdev); | 1525 | RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, hdev); |
@@ -1524,17 +1538,19 @@ int hci_register_dev(struct hci_dev *hdev) | |||
1524 | 1538 | ||
1525 | return id; | 1539 | return id; |
1526 | 1540 | ||
1527 | nomem: | 1541 | err_wqueue: |
1542 | destroy_workqueue(hdev->workqueue); | ||
1543 | err: | ||
1528 | write_lock_bh(&hci_dev_list_lock); | 1544 | write_lock_bh(&hci_dev_list_lock); |
1529 | list_del(&hdev->list); | 1545 | list_del(&hdev->list); |
1530 | write_unlock_bh(&hci_dev_list_lock); | 1546 | write_unlock_bh(&hci_dev_list_lock); |
1531 | 1547 | ||
1532 | return -ENOMEM; | 1548 | return error; |
1533 | } | 1549 | } |
1534 | EXPORT_SYMBOL(hci_register_dev); | 1550 | EXPORT_SYMBOL(hci_register_dev); |
1535 | 1551 | ||
1536 | /* Unregister HCI device */ | 1552 | /* Unregister HCI device */ |
1537 | int hci_unregister_dev(struct hci_dev *hdev) | 1553 | void hci_unregister_dev(struct hci_dev *hdev) |
1538 | { | 1554 | { |
1539 | int i; | 1555 | int i; |
1540 | 1556 | ||
@@ -1550,8 +1566,15 @@ int hci_unregister_dev(struct hci_dev *hdev) | |||
1550 | kfree_skb(hdev->reassembly[i]); | 1566 | kfree_skb(hdev->reassembly[i]); |
1551 | 1567 | ||
1552 | if (!test_bit(HCI_INIT, &hdev->flags) && | 1568 | if (!test_bit(HCI_INIT, &hdev->flags) && |
1553 | !test_bit(HCI_SETUP, &hdev->flags)) | 1569 | !test_bit(HCI_SETUP, &hdev->flags)) { |
1554 | mgmt_index_removed(hdev->id); | 1570 | hci_dev_lock_bh(hdev); |
1571 | mgmt_index_removed(hdev); | ||
1572 | hci_dev_unlock_bh(hdev); | ||
1573 | } | ||
1574 | |||
1575 | /* mgmt_index_removed should take care of emptying the | ||
1576 | * pending list */ | ||
1577 | BUG_ON(!list_empty(&hdev->mgmt_pending)); | ||
1555 | 1578 | ||
1556 | hci_notify(hdev, HCI_DEV_UNREG); | 1579 | hci_notify(hdev, HCI_DEV_UNREG); |
1557 | 1580 | ||
@@ -1560,9 +1583,8 @@ int hci_unregister_dev(struct hci_dev *hdev) | |||
1560 | rfkill_destroy(hdev->rfkill); | 1583 | rfkill_destroy(hdev->rfkill); |
1561 | } | 1584 | } |
1562 | 1585 | ||
1563 | hci_unregister_sysfs(hdev); | 1586 | hci_del_sysfs(hdev); |
1564 | 1587 | ||
1565 | hci_del_off_timer(hdev); | ||
1566 | del_timer(&hdev->adv_timer); | 1588 | del_timer(&hdev->adv_timer); |
1567 | 1589 | ||
1568 | destroy_workqueue(hdev->workqueue); | 1590 | destroy_workqueue(hdev->workqueue); |
@@ -1576,8 +1598,6 @@ int hci_unregister_dev(struct hci_dev *hdev) | |||
1576 | hci_dev_unlock_bh(hdev); | 1598 | hci_dev_unlock_bh(hdev); |
1577 | 1599 | ||
1578 | __hci_dev_put(hdev); | 1600 | __hci_dev_put(hdev); |
1579 | |||
1580 | return 0; | ||
1581 | } | 1601 | } |
1582 | EXPORT_SYMBOL(hci_unregister_dev); | 1602 | EXPORT_SYMBOL(hci_unregister_dev); |
1583 | 1603 | ||
@@ -1948,23 +1968,18 @@ static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags) | |||
1948 | hdr->dlen = cpu_to_le16(len); | 1968 | hdr->dlen = cpu_to_le16(len); |
1949 | } | 1969 | } |
1950 | 1970 | ||
1951 | void hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags) | 1971 | static void hci_queue_acl(struct hci_conn *conn, struct sk_buff_head *queue, |
1972 | struct sk_buff *skb, __u16 flags) | ||
1952 | { | 1973 | { |
1953 | struct hci_dev *hdev = conn->hdev; | 1974 | struct hci_dev *hdev = conn->hdev; |
1954 | struct sk_buff *list; | 1975 | struct sk_buff *list; |
1955 | 1976 | ||
1956 | BT_DBG("%s conn %p flags 0x%x", hdev->name, conn, flags); | ||
1957 | |||
1958 | skb->dev = (void *) hdev; | ||
1959 | bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; | ||
1960 | hci_add_acl_hdr(skb, conn->handle, flags); | ||
1961 | |||
1962 | list = skb_shinfo(skb)->frag_list; | 1977 | list = skb_shinfo(skb)->frag_list; |
1963 | if (!list) { | 1978 | if (!list) { |
1964 | /* Non fragmented */ | 1979 | /* Non fragmented */ |
1965 | BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len); | 1980 | BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len); |
1966 | 1981 | ||
1967 | skb_queue_tail(&conn->data_q, skb); | 1982 | skb_queue_tail(queue, skb); |
1968 | } else { | 1983 | } else { |
1969 | /* Fragmented */ | 1984 | /* Fragmented */ |
1970 | BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); | 1985 | BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); |
@@ -1972,9 +1987,9 @@ void hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags) | |||
1972 | skb_shinfo(skb)->frag_list = NULL; | 1987 | skb_shinfo(skb)->frag_list = NULL; |
1973 | 1988 | ||
1974 | /* Queue all fragments atomically */ | 1989 | /* Queue all fragments atomically */ |
1975 | spin_lock_bh(&conn->data_q.lock); | 1990 | spin_lock_bh(&queue->lock); |
1976 | 1991 | ||
1977 | __skb_queue_tail(&conn->data_q, skb); | 1992 | __skb_queue_tail(queue, skb); |
1978 | 1993 | ||
1979 | flags &= ~ACL_START; | 1994 | flags &= ~ACL_START; |
1980 | flags |= ACL_CONT; | 1995 | flags |= ACL_CONT; |
@@ -1987,11 +2002,25 @@ void hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags) | |||
1987 | 2002 | ||
1988 | BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); | 2003 | BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); |
1989 | 2004 | ||
1990 | __skb_queue_tail(&conn->data_q, skb); | 2005 | __skb_queue_tail(queue, skb); |
1991 | } while (list); | 2006 | } while (list); |
1992 | 2007 | ||
1993 | spin_unlock_bh(&conn->data_q.lock); | 2008 | spin_unlock_bh(&queue->lock); |
1994 | } | 2009 | } |
2010 | } | ||
2011 | |||
2012 | void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags) | ||
2013 | { | ||
2014 | struct hci_conn *conn = chan->conn; | ||
2015 | struct hci_dev *hdev = conn->hdev; | ||
2016 | |||
2017 | BT_DBG("%s chan %p flags 0x%x", hdev->name, chan, flags); | ||
2018 | |||
2019 | skb->dev = (void *) hdev; | ||
2020 | bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; | ||
2021 | hci_add_acl_hdr(skb, conn->handle, flags); | ||
2022 | |||
2023 | hci_queue_acl(conn, &chan->data_q, skb, flags); | ||
1995 | 2024 | ||
1996 | tasklet_schedule(&hdev->tx_task); | 2025 | tasklet_schedule(&hdev->tx_task); |
1997 | } | 2026 | } |
@@ -2026,16 +2055,12 @@ EXPORT_SYMBOL(hci_send_sco); | |||
2026 | static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int *quote) | 2055 | static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int *quote) |
2027 | { | 2056 | { |
2028 | struct hci_conn_hash *h = &hdev->conn_hash; | 2057 | struct hci_conn_hash *h = &hdev->conn_hash; |
2029 | struct hci_conn *conn = NULL; | 2058 | struct hci_conn *conn = NULL, *c; |
2030 | int num = 0, min = ~0; | 2059 | int num = 0, min = ~0; |
2031 | struct list_head *p; | ||
2032 | 2060 | ||
2033 | /* We don't have to lock device here. Connections are always | 2061 | /* We don't have to lock device here. Connections are always |
2034 | * added and removed with TX task disabled. */ | 2062 | * added and removed with TX task disabled. */ |
2035 | list_for_each(p, &h->list) { | 2063 | list_for_each_entry(c, &h->list, list) { |
2036 | struct hci_conn *c; | ||
2037 | c = list_entry(p, struct hci_conn, list); | ||
2038 | |||
2039 | if (c->type != type || skb_queue_empty(&c->data_q)) | 2064 | if (c->type != type || skb_queue_empty(&c->data_q)) |
2040 | continue; | 2065 | continue; |
2041 | 2066 | ||
@@ -2084,14 +2109,12 @@ static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int | |||
2084 | static inline void hci_link_tx_to(struct hci_dev *hdev, __u8 type) | 2109 | static inline void hci_link_tx_to(struct hci_dev *hdev, __u8 type) |
2085 | { | 2110 | { |
2086 | struct hci_conn_hash *h = &hdev->conn_hash; | 2111 | struct hci_conn_hash *h = &hdev->conn_hash; |
2087 | struct list_head *p; | 2112 | struct hci_conn *c; |
2088 | struct hci_conn *c; | ||
2089 | 2113 | ||
2090 | BT_ERR("%s link tx timeout", hdev->name); | 2114 | BT_ERR("%s link tx timeout", hdev->name); |
2091 | 2115 | ||
2092 | /* Kill stalled connections */ | 2116 | /* Kill stalled connections */ |
2093 | list_for_each(p, &h->list) { | 2117 | list_for_each_entry(c, &h->list, list) { |
2094 | c = list_entry(p, struct hci_conn, list); | ||
2095 | if (c->type == type && c->sent) { | 2118 | if (c->type == type && c->sent) { |
2096 | BT_ERR("%s killing stalled connection %s", | 2119 | BT_ERR("%s killing stalled connection %s", |
2097 | hdev->name, batostr(&c->dst)); | 2120 | hdev->name, batostr(&c->dst)); |
@@ -2100,11 +2123,137 @@ static inline void hci_link_tx_to(struct hci_dev *hdev, __u8 type) | |||
2100 | } | 2123 | } |
2101 | } | 2124 | } |
2102 | 2125 | ||
2103 | static inline void hci_sched_acl(struct hci_dev *hdev) | 2126 | static inline struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type, |
2127 | int *quote) | ||
2104 | { | 2128 | { |
2129 | struct hci_conn_hash *h = &hdev->conn_hash; | ||
2130 | struct hci_chan *chan = NULL; | ||
2131 | int num = 0, min = ~0, cur_prio = 0; | ||
2105 | struct hci_conn *conn; | 2132 | struct hci_conn *conn; |
2133 | int cnt, q, conn_num = 0; | ||
2134 | |||
2135 | BT_DBG("%s", hdev->name); | ||
2136 | |||
2137 | list_for_each_entry(conn, &h->list, list) { | ||
2138 | struct hci_chan_hash *ch; | ||
2139 | struct hci_chan *tmp; | ||
2140 | |||
2141 | if (conn->type != type) | ||
2142 | continue; | ||
2143 | |||
2144 | if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) | ||
2145 | continue; | ||
2146 | |||
2147 | conn_num++; | ||
2148 | |||
2149 | ch = &conn->chan_hash; | ||
2150 | |||
2151 | list_for_each_entry(tmp, &ch->list, list) { | ||
2152 | struct sk_buff *skb; | ||
2153 | |||
2154 | if (skb_queue_empty(&tmp->data_q)) | ||
2155 | continue; | ||
2156 | |||
2157 | skb = skb_peek(&tmp->data_q); | ||
2158 | if (skb->priority < cur_prio) | ||
2159 | continue; | ||
2160 | |||
2161 | if (skb->priority > cur_prio) { | ||
2162 | num = 0; | ||
2163 | min = ~0; | ||
2164 | cur_prio = skb->priority; | ||
2165 | } | ||
2166 | |||
2167 | num++; | ||
2168 | |||
2169 | if (conn->sent < min) { | ||
2170 | min = conn->sent; | ||
2171 | chan = tmp; | ||
2172 | } | ||
2173 | } | ||
2174 | |||
2175 | if (hci_conn_num(hdev, type) == conn_num) | ||
2176 | break; | ||
2177 | } | ||
2178 | |||
2179 | if (!chan) | ||
2180 | return NULL; | ||
2181 | |||
2182 | switch (chan->conn->type) { | ||
2183 | case ACL_LINK: | ||
2184 | cnt = hdev->acl_cnt; | ||
2185 | break; | ||
2186 | case SCO_LINK: | ||
2187 | case ESCO_LINK: | ||
2188 | cnt = hdev->sco_cnt; | ||
2189 | break; | ||
2190 | case LE_LINK: | ||
2191 | cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; | ||
2192 | break; | ||
2193 | default: | ||
2194 | cnt = 0; | ||
2195 | BT_ERR("Unknown link type"); | ||
2196 | } | ||
2197 | |||
2198 | q = cnt / num; | ||
2199 | *quote = q ? q : 1; | ||
2200 | BT_DBG("chan %p quote %d", chan, *quote); | ||
2201 | return chan; | ||
2202 | } | ||
2203 | |||
2204 | static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type) | ||
2205 | { | ||
2206 | struct hci_conn_hash *h = &hdev->conn_hash; | ||
2207 | struct hci_conn *conn; | ||
2208 | int num = 0; | ||
2209 | |||
2210 | BT_DBG("%s", hdev->name); | ||
2211 | |||
2212 | list_for_each_entry(conn, &h->list, list) { | ||
2213 | struct hci_chan_hash *ch; | ||
2214 | struct hci_chan *chan; | ||
2215 | |||
2216 | if (conn->type != type) | ||
2217 | continue; | ||
2218 | |||
2219 | if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) | ||
2220 | continue; | ||
2221 | |||
2222 | num++; | ||
2223 | |||
2224 | ch = &conn->chan_hash; | ||
2225 | list_for_each_entry(chan, &ch->list, list) { | ||
2226 | struct sk_buff *skb; | ||
2227 | |||
2228 | if (chan->sent) { | ||
2229 | chan->sent = 0; | ||
2230 | continue; | ||
2231 | } | ||
2232 | |||
2233 | if (skb_queue_empty(&chan->data_q)) | ||
2234 | continue; | ||
2235 | |||
2236 | skb = skb_peek(&chan->data_q); | ||
2237 | if (skb->priority >= HCI_PRIO_MAX - 1) | ||
2238 | continue; | ||
2239 | |||
2240 | skb->priority = HCI_PRIO_MAX - 1; | ||
2241 | |||
2242 | BT_DBG("chan %p skb %p promoted to %d", chan, skb, | ||
2243 | skb->priority); | ||
2244 | } | ||
2245 | |||
2246 | if (hci_conn_num(hdev, type) == num) | ||
2247 | break; | ||
2248 | } | ||
2249 | } | ||
2250 | |||
2251 | static inline void hci_sched_acl(struct hci_dev *hdev) | ||
2252 | { | ||
2253 | struct hci_chan *chan; | ||
2106 | struct sk_buff *skb; | 2254 | struct sk_buff *skb; |
2107 | int quote; | 2255 | int quote; |
2256 | unsigned int cnt; | ||
2108 | 2257 | ||
2109 | BT_DBG("%s", hdev->name); | 2258 | BT_DBG("%s", hdev->name); |
2110 | 2259 | ||
@@ -2118,19 +2267,35 @@ static inline void hci_sched_acl(struct hci_dev *hdev) | |||
2118 | hci_link_tx_to(hdev, ACL_LINK); | 2267 | hci_link_tx_to(hdev, ACL_LINK); |
2119 | } | 2268 | } |
2120 | 2269 | ||
2121 | while (hdev->acl_cnt && (conn = hci_low_sent(hdev, ACL_LINK, "e))) { | 2270 | cnt = hdev->acl_cnt; |
2122 | while (quote-- && (skb = skb_dequeue(&conn->data_q))) { | 2271 | |
2123 | BT_DBG("skb %p len %d", skb, skb->len); | 2272 | while (hdev->acl_cnt && |
2273 | (chan = hci_chan_sent(hdev, ACL_LINK, "e))) { | ||
2274 | u32 priority = (skb_peek(&chan->data_q))->priority; | ||
2275 | while (quote-- && (skb = skb_peek(&chan->data_q))) { | ||
2276 | BT_DBG("chan %p skb %p len %d priority %u", chan, skb, | ||
2277 | skb->len, skb->priority); | ||
2124 | 2278 | ||
2125 | hci_conn_enter_active_mode(conn, bt_cb(skb)->force_active); | 2279 | /* Stop if priority has changed */ |
2280 | if (skb->priority < priority) | ||
2281 | break; | ||
2282 | |||
2283 | skb = skb_dequeue(&chan->data_q); | ||
2284 | |||
2285 | hci_conn_enter_active_mode(chan->conn, | ||
2286 | bt_cb(skb)->force_active); | ||
2126 | 2287 | ||
2127 | hci_send_frame(skb); | 2288 | hci_send_frame(skb); |
2128 | hdev->acl_last_tx = jiffies; | 2289 | hdev->acl_last_tx = jiffies; |
2129 | 2290 | ||
2130 | hdev->acl_cnt--; | 2291 | hdev->acl_cnt--; |
2131 | conn->sent++; | 2292 | chan->sent++; |
2293 | chan->conn->sent++; | ||
2132 | } | 2294 | } |
2133 | } | 2295 | } |
2296 | |||
2297 | if (cnt != hdev->acl_cnt) | ||
2298 | hci_prio_recalculate(hdev, ACL_LINK); | ||
2134 | } | 2299 | } |
2135 | 2300 | ||
2136 | /* Schedule SCO */ | 2301 | /* Schedule SCO */ |
@@ -2182,9 +2347,9 @@ static inline void hci_sched_esco(struct hci_dev *hdev) | |||
2182 | 2347 | ||
2183 | static inline void hci_sched_le(struct hci_dev *hdev) | 2348 | static inline void hci_sched_le(struct hci_dev *hdev) |
2184 | { | 2349 | { |
2185 | struct hci_conn *conn; | 2350 | struct hci_chan *chan; |
2186 | struct sk_buff *skb; | 2351 | struct sk_buff *skb; |
2187 | int quote, cnt; | 2352 | int quote, cnt, tmp; |
2188 | 2353 | ||
2189 | BT_DBG("%s", hdev->name); | 2354 | BT_DBG("%s", hdev->name); |
2190 | 2355 | ||
@@ -2200,21 +2365,35 @@ static inline void hci_sched_le(struct hci_dev *hdev) | |||
2200 | } | 2365 | } |
2201 | 2366 | ||
2202 | cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt; | 2367 | cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt; |
2203 | while (cnt && (conn = hci_low_sent(hdev, LE_LINK, "e))) { | 2368 | tmp = cnt; |
2204 | while (quote-- && (skb = skb_dequeue(&conn->data_q))) { | 2369 | while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, "e))) { |
2205 | BT_DBG("skb %p len %d", skb, skb->len); | 2370 | u32 priority = (skb_peek(&chan->data_q))->priority; |
2371 | while (quote-- && (skb = skb_peek(&chan->data_q))) { | ||
2372 | BT_DBG("chan %p skb %p len %d priority %u", chan, skb, | ||
2373 | skb->len, skb->priority); | ||
2374 | |||
2375 | /* Stop if priority has changed */ | ||
2376 | if (skb->priority < priority) | ||
2377 | break; | ||
2378 | |||
2379 | skb = skb_dequeue(&chan->data_q); | ||
2206 | 2380 | ||
2207 | hci_send_frame(skb); | 2381 | hci_send_frame(skb); |
2208 | hdev->le_last_tx = jiffies; | 2382 | hdev->le_last_tx = jiffies; |
2209 | 2383 | ||
2210 | cnt--; | 2384 | cnt--; |
2211 | conn->sent++; | 2385 | chan->sent++; |
2386 | chan->conn->sent++; | ||
2212 | } | 2387 | } |
2213 | } | 2388 | } |
2389 | |||
2214 | if (hdev->le_pkts) | 2390 | if (hdev->le_pkts) |
2215 | hdev->le_cnt = cnt; | 2391 | hdev->le_cnt = cnt; |
2216 | else | 2392 | else |
2217 | hdev->acl_cnt = cnt; | 2393 | hdev->acl_cnt = cnt; |
2394 | |||
2395 | if (cnt != tmp) | ||
2396 | hci_prio_recalculate(hdev, LE_LINK); | ||
2218 | } | 2397 | } |
2219 | 2398 | ||
2220 | static void hci_tx_task(unsigned long arg) | 2399 | static void hci_tx_task(unsigned long arg) |
@@ -2407,3 +2586,31 @@ static void hci_cmd_task(unsigned long arg) | |||
2407 | } | 2586 | } |
2408 | } | 2587 | } |
2409 | } | 2588 | } |
2589 | |||
2590 | int hci_do_inquiry(struct hci_dev *hdev, u8 length) | ||
2591 | { | ||
2592 | /* General inquiry access code (GIAC) */ | ||
2593 | u8 lap[3] = { 0x33, 0x8b, 0x9e }; | ||
2594 | struct hci_cp_inquiry cp; | ||
2595 | |||
2596 | BT_DBG("%s", hdev->name); | ||
2597 | |||
2598 | if (test_bit(HCI_INQUIRY, &hdev->flags)) | ||
2599 | return -EINPROGRESS; | ||
2600 | |||
2601 | memset(&cp, 0, sizeof(cp)); | ||
2602 | memcpy(&cp.lap, lap, sizeof(cp.lap)); | ||
2603 | cp.length = length; | ||
2604 | |||
2605 | return hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp); | ||
2606 | } | ||
2607 | |||
2608 | int hci_cancel_inquiry(struct hci_dev *hdev) | ||
2609 | { | ||
2610 | BT_DBG("%s", hdev->name); | ||
2611 | |||
2612 | if (!test_bit(HCI_INQUIRY, &hdev->flags)) | ||
2613 | return -EPERM; | ||
2614 | |||
2615 | return hci_send_cmd(hdev, HCI_OP_INQUIRY_CANCEL, 0, NULL); | ||
2616 | } | ||
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index d7d96b6b1f0d..a89cf1f24e47 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -58,9 +58,11 @@ static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb) | |||
58 | if (status) | 58 | if (status) |
59 | return; | 59 | return; |
60 | 60 | ||
61 | if (test_and_clear_bit(HCI_INQUIRY, &hdev->flags) && | 61 | clear_bit(HCI_INQUIRY, &hdev->flags); |
62 | test_bit(HCI_MGMT, &hdev->flags)) | 62 | |
63 | mgmt_discovering(hdev->id, 0); | 63 | hci_dev_lock(hdev); |
64 | mgmt_discovering(hdev, 0); | ||
65 | hci_dev_unlock(hdev); | ||
64 | 66 | ||
65 | hci_req_complete(hdev, HCI_OP_INQUIRY_CANCEL, status); | 67 | hci_req_complete(hdev, HCI_OP_INQUIRY_CANCEL, status); |
66 | 68 | ||
@@ -76,10 +78,6 @@ static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb) | |||
76 | if (status) | 78 | if (status) |
77 | return; | 79 | return; |
78 | 80 | ||
79 | if (test_and_clear_bit(HCI_INQUIRY, &hdev->flags) && | ||
80 | test_bit(HCI_MGMT, &hdev->flags)) | ||
81 | mgmt_discovering(hdev->id, 0); | ||
82 | |||
83 | hci_conn_check_pending(hdev); | 81 | hci_conn_check_pending(hdev); |
84 | } | 82 | } |
85 | 83 | ||
@@ -205,13 +203,15 @@ static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb) | |||
205 | if (!sent) | 203 | if (!sent) |
206 | return; | 204 | return; |
207 | 205 | ||
206 | hci_dev_lock(hdev); | ||
207 | |||
208 | if (test_bit(HCI_MGMT, &hdev->flags)) | 208 | if (test_bit(HCI_MGMT, &hdev->flags)) |
209 | mgmt_set_local_name_complete(hdev->id, sent, status); | 209 | mgmt_set_local_name_complete(hdev, sent, status); |
210 | 210 | ||
211 | if (status) | 211 | if (status == 0) |
212 | return; | 212 | memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH); |
213 | 213 | ||
214 | memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH); | 214 | hci_dev_unlock(hdev); |
215 | } | 215 | } |
216 | 216 | ||
217 | static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb) | 217 | static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb) |
@@ -274,7 +274,8 @@ static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb) | |||
274 | 274 | ||
275 | static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb) | 275 | static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb) |
276 | { | 276 | { |
277 | __u8 status = *((__u8 *) skb->data); | 277 | __u8 param, status = *((__u8 *) skb->data); |
278 | int old_pscan, old_iscan; | ||
278 | void *sent; | 279 | void *sent; |
279 | 280 | ||
280 | BT_DBG("%s status 0x%x", hdev->name, status); | 281 | BT_DBG("%s status 0x%x", hdev->name, status); |
@@ -283,28 +284,40 @@ static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb) | |||
283 | if (!sent) | 284 | if (!sent) |
284 | return; | 285 | return; |
285 | 286 | ||
286 | if (!status) { | 287 | param = *((__u8 *) sent); |
287 | __u8 param = *((__u8 *) sent); | ||
288 | int old_pscan, old_iscan; | ||
289 | |||
290 | old_pscan = test_and_clear_bit(HCI_PSCAN, &hdev->flags); | ||
291 | old_iscan = test_and_clear_bit(HCI_ISCAN, &hdev->flags); | ||
292 | 288 | ||
293 | if (param & SCAN_INQUIRY) { | 289 | hci_dev_lock(hdev); |
294 | set_bit(HCI_ISCAN, &hdev->flags); | ||
295 | if (!old_iscan) | ||
296 | mgmt_discoverable(hdev->id, 1); | ||
297 | } else if (old_iscan) | ||
298 | mgmt_discoverable(hdev->id, 0); | ||
299 | 290 | ||
300 | if (param & SCAN_PAGE) { | 291 | if (status != 0) { |
301 | set_bit(HCI_PSCAN, &hdev->flags); | 292 | mgmt_write_scan_failed(hdev, param, status); |
302 | if (!old_pscan) | 293 | hdev->discov_timeout = 0; |
303 | mgmt_connectable(hdev->id, 1); | 294 | goto done; |
304 | } else if (old_pscan) | ||
305 | mgmt_connectable(hdev->id, 0); | ||
306 | } | 295 | } |
307 | 296 | ||
297 | old_pscan = test_and_clear_bit(HCI_PSCAN, &hdev->flags); | ||
298 | old_iscan = test_and_clear_bit(HCI_ISCAN, &hdev->flags); | ||
299 | |||
300 | if (param & SCAN_INQUIRY) { | ||
301 | set_bit(HCI_ISCAN, &hdev->flags); | ||
302 | if (!old_iscan) | ||
303 | mgmt_discoverable(hdev, 1); | ||
304 | if (hdev->discov_timeout > 0) { | ||
305 | int to = msecs_to_jiffies(hdev->discov_timeout * 1000); | ||
306 | queue_delayed_work(hdev->workqueue, &hdev->discov_off, | ||
307 | to); | ||
308 | } | ||
309 | } else if (old_iscan) | ||
310 | mgmt_discoverable(hdev, 0); | ||
311 | |||
312 | if (param & SCAN_PAGE) { | ||
313 | set_bit(HCI_PSCAN, &hdev->flags); | ||
314 | if (!old_pscan) | ||
315 | mgmt_connectable(hdev, 1); | ||
316 | } else if (old_pscan) | ||
317 | mgmt_connectable(hdev, 0); | ||
318 | |||
319 | done: | ||
320 | hci_dev_unlock(hdev); | ||
308 | hci_req_complete(hdev, HCI_OP_WRITE_SCAN_ENABLE, status); | 321 | hci_req_complete(hdev, HCI_OP_WRITE_SCAN_ENABLE, status); |
309 | } | 322 | } |
310 | 323 | ||
@@ -748,6 +761,30 @@ static void hci_cc_write_ca_timeout(struct hci_dev *hdev, struct sk_buff *skb) | |||
748 | hci_req_complete(hdev, HCI_OP_WRITE_CA_TIMEOUT, status); | 761 | hci_req_complete(hdev, HCI_OP_WRITE_CA_TIMEOUT, status); |
749 | } | 762 | } |
750 | 763 | ||
764 | static void hci_cc_read_local_amp_info(struct hci_dev *hdev, | ||
765 | struct sk_buff *skb) | ||
766 | { | ||
767 | struct hci_rp_read_local_amp_info *rp = (void *) skb->data; | ||
768 | |||
769 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | ||
770 | |||
771 | if (rp->status) | ||
772 | return; | ||
773 | |||
774 | hdev->amp_status = rp->amp_status; | ||
775 | hdev->amp_total_bw = __le32_to_cpu(rp->total_bw); | ||
776 | hdev->amp_max_bw = __le32_to_cpu(rp->max_bw); | ||
777 | hdev->amp_min_latency = __le32_to_cpu(rp->min_latency); | ||
778 | hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu); | ||
779 | hdev->amp_type = rp->amp_type; | ||
780 | hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap); | ||
781 | hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size); | ||
782 | hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to); | ||
783 | hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to); | ||
784 | |||
785 | hci_req_complete(hdev, HCI_OP_READ_LOCAL_AMP_INFO, rp->status); | ||
786 | } | ||
787 | |||
751 | static void hci_cc_delete_stored_link_key(struct hci_dev *hdev, | 788 | static void hci_cc_delete_stored_link_key(struct hci_dev *hdev, |
752 | struct sk_buff *skb) | 789 | struct sk_buff *skb) |
753 | { | 790 | { |
@@ -804,19 +841,24 @@ static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb) | |||
804 | 841 | ||
805 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | 842 | BT_DBG("%s status 0x%x", hdev->name, rp->status); |
806 | 843 | ||
844 | hci_dev_lock(hdev); | ||
845 | |||
807 | if (test_bit(HCI_MGMT, &hdev->flags)) | 846 | if (test_bit(HCI_MGMT, &hdev->flags)) |
808 | mgmt_pin_code_reply_complete(hdev->id, &rp->bdaddr, rp->status); | 847 | mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status); |
809 | 848 | ||
810 | if (rp->status != 0) | 849 | if (rp->status != 0) |
811 | return; | 850 | goto unlock; |
812 | 851 | ||
813 | cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY); | 852 | cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY); |
814 | if (!cp) | 853 | if (!cp) |
815 | return; | 854 | goto unlock; |
816 | 855 | ||
817 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); | 856 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); |
818 | if (conn) | 857 | if (conn) |
819 | conn->pin_length = cp->pin_len; | 858 | conn->pin_length = cp->pin_len; |
859 | |||
860 | unlock: | ||
861 | hci_dev_unlock(hdev); | ||
820 | } | 862 | } |
821 | 863 | ||
822 | static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb) | 864 | static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb) |
@@ -825,10 +867,15 @@ static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb) | |||
825 | 867 | ||
826 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | 868 | BT_DBG("%s status 0x%x", hdev->name, rp->status); |
827 | 869 | ||
870 | hci_dev_lock(hdev); | ||
871 | |||
828 | if (test_bit(HCI_MGMT, &hdev->flags)) | 872 | if (test_bit(HCI_MGMT, &hdev->flags)) |
829 | mgmt_pin_code_neg_reply_complete(hdev->id, &rp->bdaddr, | 873 | mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr, |
830 | rp->status); | 874 | rp->status); |
875 | |||
876 | hci_dev_unlock(hdev); | ||
831 | } | 877 | } |
878 | |||
832 | static void hci_cc_le_read_buffer_size(struct hci_dev *hdev, | 879 | static void hci_cc_le_read_buffer_size(struct hci_dev *hdev, |
833 | struct sk_buff *skb) | 880 | struct sk_buff *skb) |
834 | { | 881 | { |
@@ -855,9 +902,13 @@ static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb) | |||
855 | 902 | ||
856 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | 903 | BT_DBG("%s status 0x%x", hdev->name, rp->status); |
857 | 904 | ||
905 | hci_dev_lock(hdev); | ||
906 | |||
858 | if (test_bit(HCI_MGMT, &hdev->flags)) | 907 | if (test_bit(HCI_MGMT, &hdev->flags)) |
859 | mgmt_user_confirm_reply_complete(hdev->id, &rp->bdaddr, | 908 | mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, |
860 | rp->status); | 909 | rp->status); |
910 | |||
911 | hci_dev_unlock(hdev); | ||
861 | } | 912 | } |
862 | 913 | ||
863 | static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev, | 914 | static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev, |
@@ -867,9 +918,13 @@ static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev, | |||
867 | 918 | ||
868 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | 919 | BT_DBG("%s status 0x%x", hdev->name, rp->status); |
869 | 920 | ||
921 | hci_dev_lock(hdev); | ||
922 | |||
870 | if (test_bit(HCI_MGMT, &hdev->flags)) | 923 | if (test_bit(HCI_MGMT, &hdev->flags)) |
871 | mgmt_user_confirm_neg_reply_complete(hdev->id, &rp->bdaddr, | 924 | mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr, |
872 | rp->status); | 925 | rp->status); |
926 | |||
927 | hci_dev_unlock(hdev); | ||
873 | } | 928 | } |
874 | 929 | ||
875 | static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev, | 930 | static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev, |
@@ -879,8 +934,10 @@ static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev, | |||
879 | 934 | ||
880 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | 935 | BT_DBG("%s status 0x%x", hdev->name, rp->status); |
881 | 936 | ||
882 | mgmt_read_local_oob_data_reply_complete(hdev->id, rp->hash, | 937 | hci_dev_lock(hdev); |
938 | mgmt_read_local_oob_data_reply_complete(hdev, rp->hash, | ||
883 | rp->randomizer, rp->status); | 939 | rp->randomizer, rp->status); |
940 | hci_dev_unlock(hdev); | ||
884 | } | 941 | } |
885 | 942 | ||
886 | static void hci_cc_le_set_scan_enable(struct hci_dev *hdev, | 943 | static void hci_cc_le_set_scan_enable(struct hci_dev *hdev, |
@@ -955,12 +1012,18 @@ static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) | |||
955 | if (status) { | 1012 | if (status) { |
956 | hci_req_complete(hdev, HCI_OP_INQUIRY, status); | 1013 | hci_req_complete(hdev, HCI_OP_INQUIRY, status); |
957 | hci_conn_check_pending(hdev); | 1014 | hci_conn_check_pending(hdev); |
1015 | hci_dev_lock(hdev); | ||
1016 | if (test_bit(HCI_MGMT, &hdev->flags)) | ||
1017 | mgmt_inquiry_failed(hdev, status); | ||
1018 | hci_dev_unlock(hdev); | ||
958 | return; | 1019 | return; |
959 | } | 1020 | } |
960 | 1021 | ||
961 | if (!test_and_set_bit(HCI_INQUIRY, &hdev->flags) && | 1022 | set_bit(HCI_INQUIRY, &hdev->flags); |
962 | test_bit(HCI_MGMT, &hdev->flags)) | 1023 | |
963 | mgmt_discovering(hdev->id, 1); | 1024 | hci_dev_lock(hdev); |
1025 | mgmt_discovering(hdev, 1); | ||
1026 | hci_dev_unlock(hdev); | ||
964 | } | 1027 | } |
965 | 1028 | ||
966 | static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status) | 1029 | static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status) |
@@ -1339,13 +1402,16 @@ static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff | |||
1339 | 1402 | ||
1340 | BT_DBG("%s status %d", hdev->name, status); | 1403 | BT_DBG("%s status %d", hdev->name, status); |
1341 | 1404 | ||
1342 | if (test_and_clear_bit(HCI_INQUIRY, &hdev->flags) && | ||
1343 | test_bit(HCI_MGMT, &hdev->flags)) | ||
1344 | mgmt_discovering(hdev->id, 0); | ||
1345 | |||
1346 | hci_req_complete(hdev, HCI_OP_INQUIRY, status); | 1405 | hci_req_complete(hdev, HCI_OP_INQUIRY, status); |
1347 | 1406 | ||
1348 | hci_conn_check_pending(hdev); | 1407 | hci_conn_check_pending(hdev); |
1408 | |||
1409 | if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags)) | ||
1410 | return; | ||
1411 | |||
1412 | hci_dev_lock(hdev); | ||
1413 | mgmt_discovering(hdev, 0); | ||
1414 | hci_dev_unlock(hdev); | ||
1349 | } | 1415 | } |
1350 | 1416 | ||
1351 | static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb) | 1417 | static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb) |
@@ -1361,12 +1427,6 @@ static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff * | |||
1361 | 1427 | ||
1362 | hci_dev_lock(hdev); | 1428 | hci_dev_lock(hdev); |
1363 | 1429 | ||
1364 | if (!test_and_set_bit(HCI_INQUIRY, &hdev->flags)) { | ||
1365 | |||
1366 | if (test_bit(HCI_MGMT, &hdev->flags)) | ||
1367 | mgmt_discovering(hdev->id, 1); | ||
1368 | } | ||
1369 | |||
1370 | for (; num_rsp; num_rsp--, info++) { | 1430 | for (; num_rsp; num_rsp--, info++) { |
1371 | bacpy(&data.bdaddr, &info->bdaddr); | 1431 | bacpy(&data.bdaddr, &info->bdaddr); |
1372 | data.pscan_rep_mode = info->pscan_rep_mode; | 1432 | data.pscan_rep_mode = info->pscan_rep_mode; |
@@ -1377,8 +1437,8 @@ static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff * | |||
1377 | data.rssi = 0x00; | 1437 | data.rssi = 0x00; |
1378 | data.ssp_mode = 0x00; | 1438 | data.ssp_mode = 0x00; |
1379 | hci_inquiry_cache_update(hdev, &data); | 1439 | hci_inquiry_cache_update(hdev, &data); |
1380 | mgmt_device_found(hdev->id, &info->bdaddr, info->dev_class, 0, | 1440 | mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, |
1381 | NULL); | 1441 | info->dev_class, 0, NULL); |
1382 | } | 1442 | } |
1383 | 1443 | ||
1384 | hci_dev_unlock(hdev); | 1444 | hci_dev_unlock(hdev); |
@@ -1412,7 +1472,7 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s | |||
1412 | conn->state = BT_CONFIG; | 1472 | conn->state = BT_CONFIG; |
1413 | hci_conn_hold(conn); | 1473 | hci_conn_hold(conn); |
1414 | conn->disc_timeout = HCI_DISCONN_TIMEOUT; | 1474 | conn->disc_timeout = HCI_DISCONN_TIMEOUT; |
1415 | mgmt_connected(hdev->id, &ev->bdaddr, conn->type); | 1475 | mgmt_connected(hdev, &ev->bdaddr, conn->type); |
1416 | } else | 1476 | } else |
1417 | conn->state = BT_CONNECTED; | 1477 | conn->state = BT_CONNECTED; |
1418 | 1478 | ||
@@ -1444,7 +1504,8 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s | |||
1444 | } else { | 1504 | } else { |
1445 | conn->state = BT_CLOSED; | 1505 | conn->state = BT_CLOSED; |
1446 | if (conn->type == ACL_LINK) | 1506 | if (conn->type == ACL_LINK) |
1447 | mgmt_connect_failed(hdev->id, &ev->bdaddr, ev->status); | 1507 | mgmt_connect_failed(hdev, &ev->bdaddr, conn->type, |
1508 | ev->status); | ||
1448 | } | 1509 | } |
1449 | 1510 | ||
1450 | if (conn->type == ACL_LINK) | 1511 | if (conn->type == ACL_LINK) |
@@ -1531,7 +1592,7 @@ static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *sk | |||
1531 | struct hci_cp_reject_conn_req cp; | 1592 | struct hci_cp_reject_conn_req cp; |
1532 | 1593 | ||
1533 | bacpy(&cp.bdaddr, &ev->bdaddr); | 1594 | bacpy(&cp.bdaddr, &ev->bdaddr); |
1534 | cp.reason = 0x0f; | 1595 | cp.reason = HCI_ERROR_REJ_BAD_ADDR; |
1535 | hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp); | 1596 | hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp); |
1536 | } | 1597 | } |
1537 | } | 1598 | } |
@@ -1544,7 +1605,9 @@ static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff | |||
1544 | BT_DBG("%s status %d", hdev->name, ev->status); | 1605 | BT_DBG("%s status %d", hdev->name, ev->status); |
1545 | 1606 | ||
1546 | if (ev->status) { | 1607 | if (ev->status) { |
1547 | mgmt_disconnect_failed(hdev->id); | 1608 | hci_dev_lock(hdev); |
1609 | mgmt_disconnect_failed(hdev); | ||
1610 | hci_dev_unlock(hdev); | ||
1548 | return; | 1611 | return; |
1549 | } | 1612 | } |
1550 | 1613 | ||
@@ -1557,7 +1620,7 @@ static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff | |||
1557 | conn->state = BT_CLOSED; | 1620 | conn->state = BT_CLOSED; |
1558 | 1621 | ||
1559 | if (conn->type == ACL_LINK || conn->type == LE_LINK) | 1622 | if (conn->type == ACL_LINK || conn->type == LE_LINK) |
1560 | mgmt_disconnected(hdev->id, &conn->dst); | 1623 | mgmt_disconnected(hdev, &conn->dst, conn->type); |
1561 | 1624 | ||
1562 | hci_proto_disconn_cfm(conn, ev->reason); | 1625 | hci_proto_disconn_cfm(conn, ev->reason); |
1563 | hci_conn_del(conn); | 1626 | hci_conn_del(conn); |
@@ -1588,7 +1651,7 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s | |||
1588 | conn->sec_level = conn->pending_sec_level; | 1651 | conn->sec_level = conn->pending_sec_level; |
1589 | } | 1652 | } |
1590 | } else { | 1653 | } else { |
1591 | mgmt_auth_failed(hdev->id, &conn->dst, ev->status); | 1654 | mgmt_auth_failed(hdev, &conn->dst, ev->status); |
1592 | } | 1655 | } |
1593 | 1656 | ||
1594 | clear_bit(HCI_CONN_AUTH_PEND, &conn->pend); | 1657 | clear_bit(HCI_CONN_AUTH_PEND, &conn->pend); |
@@ -1643,7 +1706,7 @@ static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb | |||
1643 | hci_dev_lock(hdev); | 1706 | hci_dev_lock(hdev); |
1644 | 1707 | ||
1645 | if (ev->status == 0 && test_bit(HCI_MGMT, &hdev->flags)) | 1708 | if (ev->status == 0 && test_bit(HCI_MGMT, &hdev->flags)) |
1646 | mgmt_remote_name(hdev->id, &ev->bdaddr, ev->name); | 1709 | mgmt_remote_name(hdev, &ev->bdaddr, ev->name); |
1647 | 1710 | ||
1648 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); | 1711 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); |
1649 | if (!conn) | 1712 | if (!conn) |
@@ -1898,6 +1961,10 @@ static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *sk | |||
1898 | hci_cc_write_ca_timeout(hdev, skb); | 1961 | hci_cc_write_ca_timeout(hdev, skb); |
1899 | break; | 1962 | break; |
1900 | 1963 | ||
1964 | case HCI_OP_READ_LOCAL_AMP_INFO: | ||
1965 | hci_cc_read_local_amp_info(hdev, skb); | ||
1966 | break; | ||
1967 | |||
1901 | case HCI_OP_DELETE_STORED_LINK_KEY: | 1968 | case HCI_OP_DELETE_STORED_LINK_KEY: |
1902 | hci_cc_delete_stored_link_key(hdev, skb); | 1969 | hci_cc_delete_stored_link_key(hdev, skb); |
1903 | break; | 1970 | break; |
@@ -2029,7 +2096,7 @@ static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
2029 | 2096 | ||
2030 | case HCI_OP_DISCONNECT: | 2097 | case HCI_OP_DISCONNECT: |
2031 | if (ev->status != 0) | 2098 | if (ev->status != 0) |
2032 | mgmt_disconnect_failed(hdev->id); | 2099 | mgmt_disconnect_failed(hdev); |
2033 | break; | 2100 | break; |
2034 | 2101 | ||
2035 | case HCI_OP_LE_CREATE_CONN: | 2102 | case HCI_OP_LE_CREATE_CONN: |
@@ -2194,7 +2261,7 @@ static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff | |||
2194 | else | 2261 | else |
2195 | secure = 0; | 2262 | secure = 0; |
2196 | 2263 | ||
2197 | mgmt_pin_code_request(hdev->id, &ev->bdaddr, secure); | 2264 | mgmt_pin_code_request(hdev, &ev->bdaddr, secure); |
2198 | } | 2265 | } |
2199 | 2266 | ||
2200 | unlock: | 2267 | unlock: |
@@ -2363,12 +2430,6 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct | |||
2363 | 2430 | ||
2364 | hci_dev_lock(hdev); | 2431 | hci_dev_lock(hdev); |
2365 | 2432 | ||
2366 | if (!test_and_set_bit(HCI_INQUIRY, &hdev->flags)) { | ||
2367 | |||
2368 | if (test_bit(HCI_MGMT, &hdev->flags)) | ||
2369 | mgmt_discovering(hdev->id, 1); | ||
2370 | } | ||
2371 | |||
2372 | if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) { | 2433 | if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) { |
2373 | struct inquiry_info_with_rssi_and_pscan_mode *info; | 2434 | struct inquiry_info_with_rssi_and_pscan_mode *info; |
2374 | info = (void *) (skb->data + 1); | 2435 | info = (void *) (skb->data + 1); |
@@ -2383,7 +2444,7 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct | |||
2383 | data.rssi = info->rssi; | 2444 | data.rssi = info->rssi; |
2384 | data.ssp_mode = 0x00; | 2445 | data.ssp_mode = 0x00; |
2385 | hci_inquiry_cache_update(hdev, &data); | 2446 | hci_inquiry_cache_update(hdev, &data); |
2386 | mgmt_device_found(hdev->id, &info->bdaddr, | 2447 | mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, |
2387 | info->dev_class, info->rssi, | 2448 | info->dev_class, info->rssi, |
2388 | NULL); | 2449 | NULL); |
2389 | } | 2450 | } |
@@ -2400,7 +2461,7 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct | |||
2400 | data.rssi = info->rssi; | 2461 | data.rssi = info->rssi; |
2401 | data.ssp_mode = 0x00; | 2462 | data.ssp_mode = 0x00; |
2402 | hci_inquiry_cache_update(hdev, &data); | 2463 | hci_inquiry_cache_update(hdev, &data); |
2403 | mgmt_device_found(hdev->id, &info->bdaddr, | 2464 | mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, |
2404 | info->dev_class, info->rssi, | 2465 | info->dev_class, info->rssi, |
2405 | NULL); | 2466 | NULL); |
2406 | } | 2467 | } |
@@ -2531,12 +2592,6 @@ static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct | |||
2531 | if (!num_rsp) | 2592 | if (!num_rsp) |
2532 | return; | 2593 | return; |
2533 | 2594 | ||
2534 | if (!test_and_set_bit(HCI_INQUIRY, &hdev->flags)) { | ||
2535 | |||
2536 | if (test_bit(HCI_MGMT, &hdev->flags)) | ||
2537 | mgmt_discovering(hdev->id, 1); | ||
2538 | } | ||
2539 | |||
2540 | hci_dev_lock(hdev); | 2595 | hci_dev_lock(hdev); |
2541 | 2596 | ||
2542 | for (; num_rsp; num_rsp--, info++) { | 2597 | for (; num_rsp; num_rsp--, info++) { |
@@ -2549,8 +2604,8 @@ static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct | |||
2549 | data.rssi = info->rssi; | 2604 | data.rssi = info->rssi; |
2550 | data.ssp_mode = 0x01; | 2605 | data.ssp_mode = 0x01; |
2551 | hci_inquiry_cache_update(hdev, &data); | 2606 | hci_inquiry_cache_update(hdev, &data); |
2552 | mgmt_device_found(hdev->id, &info->bdaddr, info->dev_class, | 2607 | mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, |
2553 | info->rssi, info->data); | 2608 | info->dev_class, info->rssi, info->data); |
2554 | } | 2609 | } |
2555 | 2610 | ||
2556 | hci_dev_unlock(hdev); | 2611 | hci_dev_unlock(hdev); |
@@ -2614,7 +2669,7 @@ static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff | |||
2614 | struct hci_cp_io_capability_neg_reply cp; | 2669 | struct hci_cp_io_capability_neg_reply cp; |
2615 | 2670 | ||
2616 | bacpy(&cp.bdaddr, &ev->bdaddr); | 2671 | bacpy(&cp.bdaddr, &ev->bdaddr); |
2617 | cp.reason = 0x18; /* Pairing not allowed */ | 2672 | cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED; |
2618 | 2673 | ||
2619 | hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY, | 2674 | hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY, |
2620 | sizeof(cp), &cp); | 2675 | sizeof(cp), &cp); |
@@ -2706,7 +2761,7 @@ static inline void hci_user_confirm_request_evt(struct hci_dev *hdev, | |||
2706 | } | 2761 | } |
2707 | 2762 | ||
2708 | confirm: | 2763 | confirm: |
2709 | mgmt_user_confirm_request(hdev->id, &ev->bdaddr, ev->passkey, | 2764 | mgmt_user_confirm_request(hdev, &ev->bdaddr, ev->passkey, |
2710 | confirm_hint); | 2765 | confirm_hint); |
2711 | 2766 | ||
2712 | unlock: | 2767 | unlock: |
@@ -2732,7 +2787,7 @@ static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_ | |||
2732 | * event gets always produced as initiator and is also mapped to | 2787 | * event gets always produced as initiator and is also mapped to |
2733 | * the mgmt_auth_failed event */ | 2788 | * the mgmt_auth_failed event */ |
2734 | if (!test_bit(HCI_CONN_AUTH_PEND, &conn->pend) && ev->status != 0) | 2789 | if (!test_bit(HCI_CONN_AUTH_PEND, &conn->pend) && ev->status != 0) |
2735 | mgmt_auth_failed(hdev->id, &conn->dst, ev->status); | 2790 | mgmt_auth_failed(hdev, &conn->dst, ev->status); |
2736 | 2791 | ||
2737 | hci_conn_put(conn); | 2792 | hci_conn_put(conn); |
2738 | 2793 | ||
@@ -2813,14 +2868,14 @@ static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff | |||
2813 | } | 2868 | } |
2814 | 2869 | ||
2815 | if (ev->status) { | 2870 | if (ev->status) { |
2816 | mgmt_connect_failed(hdev->id, &ev->bdaddr, ev->status); | 2871 | mgmt_connect_failed(hdev, &ev->bdaddr, conn->type, ev->status); |
2817 | hci_proto_connect_cfm(conn, ev->status); | 2872 | hci_proto_connect_cfm(conn, ev->status); |
2818 | conn->state = BT_CLOSED; | 2873 | conn->state = BT_CLOSED; |
2819 | hci_conn_del(conn); | 2874 | hci_conn_del(conn); |
2820 | goto unlock; | 2875 | goto unlock; |
2821 | } | 2876 | } |
2822 | 2877 | ||
2823 | mgmt_connected(hdev->id, &ev->bdaddr, conn->type); | 2878 | mgmt_connected(hdev, &ev->bdaddr, conn->type); |
2824 | 2879 | ||
2825 | conn->sec_level = BT_SECURITY_LOW; | 2880 | conn->sec_level = BT_SECURITY_LOW; |
2826 | conn->handle = __le16_to_cpu(ev->handle); | 2881 | conn->handle = __le16_to_cpu(ev->handle); |
@@ -3104,5 +3159,5 @@ void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data) | |||
3104 | kfree_skb(skb); | 3159 | kfree_skb(skb); |
3105 | } | 3160 | } |
3106 | 3161 | ||
3107 | module_param(enable_le, bool, 0444); | 3162 | module_param(enable_le, bool, 0644); |
3108 | MODULE_PARM_DESC(enable_le, "Enable LE support"); | 3163 | MODULE_PARM_DESC(enable_le, "Enable LE support"); |
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c index 661b461cf0b0..c62d254a1379 100644 --- a/net/bluetooth/hci_sysfs.c +++ b/net/bluetooth/hci_sysfs.c | |||
@@ -436,17 +436,12 @@ static const struct file_operations inquiry_cache_fops = { | |||
436 | static int blacklist_show(struct seq_file *f, void *p) | 436 | static int blacklist_show(struct seq_file *f, void *p) |
437 | { | 437 | { |
438 | struct hci_dev *hdev = f->private; | 438 | struct hci_dev *hdev = f->private; |
439 | struct list_head *l; | 439 | struct bdaddr_list *b; |
440 | 440 | ||
441 | hci_dev_lock_bh(hdev); | 441 | hci_dev_lock_bh(hdev); |
442 | 442 | ||
443 | list_for_each(l, &hdev->blacklist) { | 443 | list_for_each_entry(b, &hdev->blacklist, list) |
444 | struct bdaddr_list *b; | ||
445 | |||
446 | b = list_entry(l, struct bdaddr_list, list); | ||
447 | |||
448 | seq_printf(f, "%s\n", batostr(&b->bdaddr)); | 444 | seq_printf(f, "%s\n", batostr(&b->bdaddr)); |
449 | } | ||
450 | 445 | ||
451 | hci_dev_unlock_bh(hdev); | 446 | hci_dev_unlock_bh(hdev); |
452 | 447 | ||
@@ -485,17 +480,12 @@ static void print_bt_uuid(struct seq_file *f, u8 *uuid) | |||
485 | static int uuids_show(struct seq_file *f, void *p) | 480 | static int uuids_show(struct seq_file *f, void *p) |
486 | { | 481 | { |
487 | struct hci_dev *hdev = f->private; | 482 | struct hci_dev *hdev = f->private; |
488 | struct list_head *l; | 483 | struct bt_uuid *uuid; |
489 | 484 | ||
490 | hci_dev_lock_bh(hdev); | 485 | hci_dev_lock_bh(hdev); |
491 | 486 | ||
492 | list_for_each(l, &hdev->uuids) { | 487 | list_for_each_entry(uuid, &hdev->uuids, list) |
493 | struct bt_uuid *uuid; | ||
494 | |||
495 | uuid = list_entry(l, struct bt_uuid, list); | ||
496 | |||
497 | print_bt_uuid(f, uuid->uuid); | 488 | print_bt_uuid(f, uuid->uuid); |
498 | } | ||
499 | 489 | ||
500 | hci_dev_unlock_bh(hdev); | 490 | hci_dev_unlock_bh(hdev); |
501 | 491 | ||
@@ -543,22 +533,28 @@ static int auto_accept_delay_get(void *data, u64 *val) | |||
543 | DEFINE_SIMPLE_ATTRIBUTE(auto_accept_delay_fops, auto_accept_delay_get, | 533 | DEFINE_SIMPLE_ATTRIBUTE(auto_accept_delay_fops, auto_accept_delay_get, |
544 | auto_accept_delay_set, "%llu\n"); | 534 | auto_accept_delay_set, "%llu\n"); |
545 | 535 | ||
546 | int hci_register_sysfs(struct hci_dev *hdev) | 536 | void hci_init_sysfs(struct hci_dev *hdev) |
537 | { | ||
538 | struct device *dev = &hdev->dev; | ||
539 | |||
540 | dev->type = &bt_host; | ||
541 | dev->class = bt_class; | ||
542 | |||
543 | dev_set_drvdata(dev, hdev); | ||
544 | device_initialize(dev); | ||
545 | } | ||
546 | |||
547 | int hci_add_sysfs(struct hci_dev *hdev) | ||
547 | { | 548 | { |
548 | struct device *dev = &hdev->dev; | 549 | struct device *dev = &hdev->dev; |
549 | int err; | 550 | int err; |
550 | 551 | ||
551 | BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); | 552 | BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); |
552 | 553 | ||
553 | dev->type = &bt_host; | ||
554 | dev->class = bt_class; | ||
555 | dev->parent = hdev->parent; | 554 | dev->parent = hdev->parent; |
556 | |||
557 | dev_set_name(dev, "%s", hdev->name); | 555 | dev_set_name(dev, "%s", hdev->name); |
558 | 556 | ||
559 | dev_set_drvdata(dev, hdev); | 557 | err = device_add(dev); |
560 | |||
561 | err = device_register(dev); | ||
562 | if (err < 0) | 558 | if (err < 0) |
563 | return err; | 559 | return err; |
564 | 560 | ||
@@ -582,7 +578,7 @@ int hci_register_sysfs(struct hci_dev *hdev) | |||
582 | return 0; | 578 | return 0; |
583 | } | 579 | } |
584 | 580 | ||
585 | void hci_unregister_sysfs(struct hci_dev *hdev) | 581 | void hci_del_sysfs(struct hci_dev *hdev) |
586 | { | 582 | { |
587 | BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); | 583 | BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); |
588 | 584 | ||
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index 075a3e920caf..3c2d888925d7 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c | |||
@@ -81,24 +81,20 @@ static unsigned char hidp_mkeyspat[] = { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }; | |||
81 | static struct hidp_session *__hidp_get_session(bdaddr_t *bdaddr) | 81 | static struct hidp_session *__hidp_get_session(bdaddr_t *bdaddr) |
82 | { | 82 | { |
83 | struct hidp_session *session; | 83 | struct hidp_session *session; |
84 | struct list_head *p; | ||
85 | 84 | ||
86 | BT_DBG(""); | 85 | BT_DBG(""); |
87 | 86 | ||
88 | list_for_each(p, &hidp_session_list) { | 87 | list_for_each_entry(session, &hidp_session_list, list) { |
89 | session = list_entry(p, struct hidp_session, list); | ||
90 | if (!bacmp(bdaddr, &session->bdaddr)) | 88 | if (!bacmp(bdaddr, &session->bdaddr)) |
91 | return session; | 89 | return session; |
92 | } | 90 | } |
91 | |||
93 | return NULL; | 92 | return NULL; |
94 | } | 93 | } |
95 | 94 | ||
96 | static void __hidp_link_session(struct hidp_session *session) | 95 | static void __hidp_link_session(struct hidp_session *session) |
97 | { | 96 | { |
98 | __module_get(THIS_MODULE); | ||
99 | list_add(&session->list, &hidp_session_list); | 97 | list_add(&session->list, &hidp_session_list); |
100 | |||
101 | hci_conn_hold_device(session->conn); | ||
102 | } | 98 | } |
103 | 99 | ||
104 | static void __hidp_unlink_session(struct hidp_session *session) | 100 | static void __hidp_unlink_session(struct hidp_session *session) |
@@ -106,7 +102,6 @@ static void __hidp_unlink_session(struct hidp_session *session) | |||
106 | hci_conn_put_device(session->conn); | 102 | hci_conn_put_device(session->conn); |
107 | 103 | ||
108 | list_del(&session->list); | 104 | list_del(&session->list); |
109 | module_put(THIS_MODULE); | ||
110 | } | 105 | } |
111 | 106 | ||
112 | static void __hidp_copy_session(struct hidp_session *session, struct hidp_conninfo *ci) | 107 | static void __hidp_copy_session(struct hidp_session *session, struct hidp_conninfo *ci) |
@@ -255,6 +250,9 @@ static int __hidp_send_ctrl_message(struct hidp_session *session, | |||
255 | 250 | ||
256 | BT_DBG("session %p data %p size %d", session, data, size); | 251 | BT_DBG("session %p data %p size %d", session, data, size); |
257 | 252 | ||
253 | if (atomic_read(&session->terminate)) | ||
254 | return -EIO; | ||
255 | |||
258 | skb = alloc_skb(size + 1, GFP_ATOMIC); | 256 | skb = alloc_skb(size + 1, GFP_ATOMIC); |
259 | if (!skb) { | 257 | if (!skb) { |
260 | BT_ERR("Can't allocate memory for new frame"); | 258 | BT_ERR("Can't allocate memory for new frame"); |
@@ -329,6 +327,7 @@ static int hidp_get_raw_report(struct hid_device *hid, | |||
329 | struct sk_buff *skb; | 327 | struct sk_buff *skb; |
330 | size_t len; | 328 | size_t len; |
331 | int numbered_reports = hid->report_enum[report_type].numbered; | 329 | int numbered_reports = hid->report_enum[report_type].numbered; |
330 | int ret; | ||
332 | 331 | ||
333 | switch (report_type) { | 332 | switch (report_type) { |
334 | case HID_FEATURE_REPORT: | 333 | case HID_FEATURE_REPORT: |
@@ -352,8 +351,9 @@ static int hidp_get_raw_report(struct hid_device *hid, | |||
352 | session->waiting_report_number = numbered_reports ? report_number : -1; | 351 | session->waiting_report_number = numbered_reports ? report_number : -1; |
353 | set_bit(HIDP_WAITING_FOR_RETURN, &session->flags); | 352 | set_bit(HIDP_WAITING_FOR_RETURN, &session->flags); |
354 | data[0] = report_number; | 353 | data[0] = report_number; |
355 | if (hidp_send_ctrl_message(hid->driver_data, report_type, data, 1)) | 354 | ret = hidp_send_ctrl_message(hid->driver_data, report_type, data, 1); |
356 | goto err_eio; | 355 | if (ret) |
356 | goto err; | ||
357 | 357 | ||
358 | /* Wait for the return of the report. The returned report | 358 | /* Wait for the return of the report. The returned report |
359 | gets put in session->report_return. */ | 359 | gets put in session->report_return. */ |
@@ -365,11 +365,13 @@ static int hidp_get_raw_report(struct hid_device *hid, | |||
365 | 5*HZ); | 365 | 5*HZ); |
366 | if (res == 0) { | 366 | if (res == 0) { |
367 | /* timeout */ | 367 | /* timeout */ |
368 | goto err_eio; | 368 | ret = -EIO; |
369 | goto err; | ||
369 | } | 370 | } |
370 | if (res < 0) { | 371 | if (res < 0) { |
371 | /* signal */ | 372 | /* signal */ |
372 | goto err_restartsys; | 373 | ret = -ERESTARTSYS; |
374 | goto err; | ||
373 | } | 375 | } |
374 | } | 376 | } |
375 | 377 | ||
@@ -390,14 +392,10 @@ static int hidp_get_raw_report(struct hid_device *hid, | |||
390 | 392 | ||
391 | return len; | 393 | return len; |
392 | 394 | ||
393 | err_restartsys: | 395 | err: |
394 | clear_bit(HIDP_WAITING_FOR_RETURN, &session->flags); | ||
395 | mutex_unlock(&session->report_mutex); | ||
396 | return -ERESTARTSYS; | ||
397 | err_eio: | ||
398 | clear_bit(HIDP_WAITING_FOR_RETURN, &session->flags); | 396 | clear_bit(HIDP_WAITING_FOR_RETURN, &session->flags); |
399 | mutex_unlock(&session->report_mutex); | 397 | mutex_unlock(&session->report_mutex); |
400 | return -EIO; | 398 | return ret; |
401 | } | 399 | } |
402 | 400 | ||
403 | static int hidp_output_raw_report(struct hid_device *hid, unsigned char *data, size_t count, | 401 | static int hidp_output_raw_report(struct hid_device *hid, unsigned char *data, size_t count, |
@@ -422,11 +420,10 @@ static int hidp_output_raw_report(struct hid_device *hid, unsigned char *data, s | |||
422 | 420 | ||
423 | /* Set up our wait, and send the report request to the device. */ | 421 | /* Set up our wait, and send the report request to the device. */ |
424 | set_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags); | 422 | set_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags); |
425 | if (hidp_send_ctrl_message(hid->driver_data, report_type, | 423 | ret = hidp_send_ctrl_message(hid->driver_data, report_type, data, |
426 | data, count)) { | 424 | count); |
427 | ret = -ENOMEM; | 425 | if (ret) |
428 | goto err; | 426 | goto err; |
429 | } | ||
430 | 427 | ||
431 | /* Wait for the ACK from the device. */ | 428 | /* Wait for the ACK from the device. */ |
432 | while (test_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags)) { | 429 | while (test_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags)) { |
@@ -496,10 +493,9 @@ static void hidp_process_handshake(struct hidp_session *session, | |||
496 | case HIDP_HSHK_ERR_INVALID_REPORT_ID: | 493 | case HIDP_HSHK_ERR_INVALID_REPORT_ID: |
497 | case HIDP_HSHK_ERR_UNSUPPORTED_REQUEST: | 494 | case HIDP_HSHK_ERR_UNSUPPORTED_REQUEST: |
498 | case HIDP_HSHK_ERR_INVALID_PARAMETER: | 495 | case HIDP_HSHK_ERR_INVALID_PARAMETER: |
499 | if (test_bit(HIDP_WAITING_FOR_RETURN, &session->flags)) { | 496 | if (test_and_clear_bit(HIDP_WAITING_FOR_RETURN, &session->flags)) |
500 | clear_bit(HIDP_WAITING_FOR_RETURN, &session->flags); | ||
501 | wake_up_interruptible(&session->report_queue); | 497 | wake_up_interruptible(&session->report_queue); |
502 | } | 498 | |
503 | /* FIXME: Call into SET_ GET_ handlers here */ | 499 | /* FIXME: Call into SET_ GET_ handlers here */ |
504 | break; | 500 | break; |
505 | 501 | ||
@@ -520,10 +516,8 @@ static void hidp_process_handshake(struct hidp_session *session, | |||
520 | } | 516 | } |
521 | 517 | ||
522 | /* Wake up the waiting thread. */ | 518 | /* Wake up the waiting thread. */ |
523 | if (test_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags)) { | 519 | if (test_and_clear_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags)) |
524 | clear_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags); | ||
525 | wake_up_interruptible(&session->report_queue); | 520 | wake_up_interruptible(&session->report_queue); |
526 | } | ||
527 | } | 521 | } |
528 | 522 | ||
529 | static void hidp_process_hid_control(struct hidp_session *session, | 523 | static void hidp_process_hid_control(struct hidp_session *session, |
@@ -663,25 +657,32 @@ static int hidp_send_frame(struct socket *sock, unsigned char *data, int len) | |||
663 | return kernel_sendmsg(sock, &msg, &iv, 1, len); | 657 | return kernel_sendmsg(sock, &msg, &iv, 1, len); |
664 | } | 658 | } |
665 | 659 | ||
666 | static void hidp_process_transmit(struct hidp_session *session) | 660 | static void hidp_process_intr_transmit(struct hidp_session *session) |
667 | { | 661 | { |
668 | struct sk_buff *skb; | 662 | struct sk_buff *skb; |
669 | 663 | ||
670 | BT_DBG("session %p", session); | 664 | BT_DBG("session %p", session); |
671 | 665 | ||
672 | while ((skb = skb_dequeue(&session->ctrl_transmit))) { | 666 | while ((skb = skb_dequeue(&session->intr_transmit))) { |
673 | if (hidp_send_frame(session->ctrl_sock, skb->data, skb->len) < 0) { | 667 | if (hidp_send_frame(session->intr_sock, skb->data, skb->len) < 0) { |
674 | skb_queue_head(&session->ctrl_transmit, skb); | 668 | skb_queue_head(&session->intr_transmit, skb); |
675 | break; | 669 | break; |
676 | } | 670 | } |
677 | 671 | ||
678 | hidp_set_timer(session); | 672 | hidp_set_timer(session); |
679 | kfree_skb(skb); | 673 | kfree_skb(skb); |
680 | } | 674 | } |
675 | } | ||
681 | 676 | ||
682 | while ((skb = skb_dequeue(&session->intr_transmit))) { | 677 | static void hidp_process_ctrl_transmit(struct hidp_session *session) |
683 | if (hidp_send_frame(session->intr_sock, skb->data, skb->len) < 0) { | 678 | { |
684 | skb_queue_head(&session->intr_transmit, skb); | 679 | struct sk_buff *skb; |
680 | |||
681 | BT_DBG("session %p", session); | ||
682 | |||
683 | while ((skb = skb_dequeue(&session->ctrl_transmit))) { | ||
684 | if (hidp_send_frame(session->ctrl_sock, skb->data, skb->len) < 0) { | ||
685 | skb_queue_head(&session->ctrl_transmit, skb); | ||
685 | break; | 686 | break; |
686 | } | 687 | } |
687 | 688 | ||
@@ -700,6 +701,7 @@ static int hidp_session(void *arg) | |||
700 | 701 | ||
701 | BT_DBG("session %p", session); | 702 | BT_DBG("session %p", session); |
702 | 703 | ||
704 | __module_get(THIS_MODULE); | ||
703 | set_user_nice(current, -15); | 705 | set_user_nice(current, -15); |
704 | 706 | ||
705 | init_waitqueue_entry(&ctrl_wait, current); | 707 | init_waitqueue_entry(&ctrl_wait, current); |
@@ -714,23 +716,25 @@ static int hidp_session(void *arg) | |||
714 | intr_sk->sk_state != BT_CONNECTED) | 716 | intr_sk->sk_state != BT_CONNECTED) |
715 | break; | 717 | break; |
716 | 718 | ||
717 | while ((skb = skb_dequeue(&ctrl_sk->sk_receive_queue))) { | 719 | while ((skb = skb_dequeue(&intr_sk->sk_receive_queue))) { |
718 | skb_orphan(skb); | 720 | skb_orphan(skb); |
719 | if (!skb_linearize(skb)) | 721 | if (!skb_linearize(skb)) |
720 | hidp_recv_ctrl_frame(session, skb); | 722 | hidp_recv_intr_frame(session, skb); |
721 | else | 723 | else |
722 | kfree_skb(skb); | 724 | kfree_skb(skb); |
723 | } | 725 | } |
724 | 726 | ||
725 | while ((skb = skb_dequeue(&intr_sk->sk_receive_queue))) { | 727 | hidp_process_intr_transmit(session); |
728 | |||
729 | while ((skb = skb_dequeue(&ctrl_sk->sk_receive_queue))) { | ||
726 | skb_orphan(skb); | 730 | skb_orphan(skb); |
727 | if (!skb_linearize(skb)) | 731 | if (!skb_linearize(skb)) |
728 | hidp_recv_intr_frame(session, skb); | 732 | hidp_recv_ctrl_frame(session, skb); |
729 | else | 733 | else |
730 | kfree_skb(skb); | 734 | kfree_skb(skb); |
731 | } | 735 | } |
732 | 736 | ||
733 | hidp_process_transmit(session); | 737 | hidp_process_ctrl_transmit(session); |
734 | 738 | ||
735 | schedule(); | 739 | schedule(); |
736 | set_current_state(TASK_INTERRUPTIBLE); | 740 | set_current_state(TASK_INTERRUPTIBLE); |
@@ -739,6 +743,10 @@ static int hidp_session(void *arg) | |||
739 | remove_wait_queue(sk_sleep(intr_sk), &intr_wait); | 743 | remove_wait_queue(sk_sleep(intr_sk), &intr_wait); |
740 | remove_wait_queue(sk_sleep(ctrl_sk), &ctrl_wait); | 744 | remove_wait_queue(sk_sleep(ctrl_sk), &ctrl_wait); |
741 | 745 | ||
746 | clear_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags); | ||
747 | clear_bit(HIDP_WAITING_FOR_RETURN, &session->flags); | ||
748 | wake_up_interruptible(&session->report_queue); | ||
749 | |||
742 | down_write(&hidp_session_sem); | 750 | down_write(&hidp_session_sem); |
743 | 751 | ||
744 | hidp_del_timer(session); | 752 | hidp_del_timer(session); |
@@ -772,34 +780,37 @@ static int hidp_session(void *arg) | |||
772 | 780 | ||
773 | kfree(session->rd_data); | 781 | kfree(session->rd_data); |
774 | kfree(session); | 782 | kfree(session); |
783 | module_put_and_exit(0); | ||
775 | return 0; | 784 | return 0; |
776 | } | 785 | } |
777 | 786 | ||
778 | static struct device *hidp_get_device(struct hidp_session *session) | 787 | static struct hci_conn *hidp_get_connection(struct hidp_session *session) |
779 | { | 788 | { |
780 | bdaddr_t *src = &bt_sk(session->ctrl_sock->sk)->src; | 789 | bdaddr_t *src = &bt_sk(session->ctrl_sock->sk)->src; |
781 | bdaddr_t *dst = &bt_sk(session->ctrl_sock->sk)->dst; | 790 | bdaddr_t *dst = &bt_sk(session->ctrl_sock->sk)->dst; |
782 | struct device *device = NULL; | 791 | struct hci_conn *conn; |
783 | struct hci_dev *hdev; | 792 | struct hci_dev *hdev; |
784 | 793 | ||
785 | hdev = hci_get_route(dst, src); | 794 | hdev = hci_get_route(dst, src); |
786 | if (!hdev) | 795 | if (!hdev) |
787 | return NULL; | 796 | return NULL; |
788 | 797 | ||
789 | session->conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst); | 798 | hci_dev_lock_bh(hdev); |
790 | if (session->conn) | 799 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst); |
791 | device = &session->conn->dev; | 800 | if (conn) |
801 | hci_conn_hold_device(conn); | ||
802 | hci_dev_unlock_bh(hdev); | ||
792 | 803 | ||
793 | hci_dev_put(hdev); | 804 | hci_dev_put(hdev); |
794 | 805 | ||
795 | return device; | 806 | return conn; |
796 | } | 807 | } |
797 | 808 | ||
798 | static int hidp_setup_input(struct hidp_session *session, | 809 | static int hidp_setup_input(struct hidp_session *session, |
799 | struct hidp_connadd_req *req) | 810 | struct hidp_connadd_req *req) |
800 | { | 811 | { |
801 | struct input_dev *input; | 812 | struct input_dev *input; |
802 | int err, i; | 813 | int i; |
803 | 814 | ||
804 | input = input_allocate_device(); | 815 | input = input_allocate_device(); |
805 | if (!input) | 816 | if (!input) |
@@ -842,17 +853,10 @@ static int hidp_setup_input(struct hidp_session *session, | |||
842 | input->relbit[0] |= BIT_MASK(REL_WHEEL); | 853 | input->relbit[0] |= BIT_MASK(REL_WHEEL); |
843 | } | 854 | } |
844 | 855 | ||
845 | input->dev.parent = hidp_get_device(session); | 856 | input->dev.parent = &session->conn->dev; |
846 | 857 | ||
847 | input->event = hidp_input_event; | 858 | input->event = hidp_input_event; |
848 | 859 | ||
849 | err = input_register_device(input); | ||
850 | if (err < 0) { | ||
851 | input_free_device(input); | ||
852 | session->input = NULL; | ||
853 | return err; | ||
854 | } | ||
855 | |||
856 | return 0; | 860 | return 0; |
857 | } | 861 | } |
858 | 862 | ||
@@ -949,7 +953,7 @@ static int hidp_setup_hid(struct hidp_session *session, | |||
949 | strncpy(hid->phys, batostr(&bt_sk(session->ctrl_sock->sk)->src), 64); | 953 | strncpy(hid->phys, batostr(&bt_sk(session->ctrl_sock->sk)->src), 64); |
950 | strncpy(hid->uniq, batostr(&bt_sk(session->ctrl_sock->sk)->dst), 64); | 954 | strncpy(hid->uniq, batostr(&bt_sk(session->ctrl_sock->sk)->dst), 64); |
951 | 955 | ||
952 | hid->dev.parent = hidp_get_device(session); | 956 | hid->dev.parent = &session->conn->dev; |
953 | hid->ll_driver = &hidp_hid_driver; | 957 | hid->ll_driver = &hidp_hid_driver; |
954 | 958 | ||
955 | hid->hid_get_raw_report = hidp_get_raw_report; | 959 | hid->hid_get_raw_report = hidp_get_raw_report; |
@@ -976,18 +980,20 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, | |||
976 | bacmp(&bt_sk(ctrl_sock->sk)->dst, &bt_sk(intr_sock->sk)->dst)) | 980 | bacmp(&bt_sk(ctrl_sock->sk)->dst, &bt_sk(intr_sock->sk)->dst)) |
977 | return -ENOTUNIQ; | 981 | return -ENOTUNIQ; |
978 | 982 | ||
979 | session = kzalloc(sizeof(struct hidp_session), GFP_KERNEL); | ||
980 | if (!session) | ||
981 | return -ENOMEM; | ||
982 | |||
983 | BT_DBG("rd_data %p rd_size %d", req->rd_data, req->rd_size); | 983 | BT_DBG("rd_data %p rd_size %d", req->rd_data, req->rd_size); |
984 | 984 | ||
985 | down_write(&hidp_session_sem); | 985 | down_write(&hidp_session_sem); |
986 | 986 | ||
987 | s = __hidp_get_session(&bt_sk(ctrl_sock->sk)->dst); | 987 | s = __hidp_get_session(&bt_sk(ctrl_sock->sk)->dst); |
988 | if (s && s->state == BT_CONNECTED) { | 988 | if (s && s->state == BT_CONNECTED) { |
989 | err = -EEXIST; | 989 | up_write(&hidp_session_sem); |
990 | goto failed; | 990 | return -EEXIST; |
991 | } | ||
992 | |||
993 | session = kzalloc(sizeof(struct hidp_session), GFP_KERNEL); | ||
994 | if (!session) { | ||
995 | up_write(&hidp_session_sem); | ||
996 | return -ENOMEM; | ||
991 | } | 997 | } |
992 | 998 | ||
993 | bacpy(&session->bdaddr, &bt_sk(ctrl_sock->sk)->dst); | 999 | bacpy(&session->bdaddr, &bt_sk(ctrl_sock->sk)->dst); |
@@ -1003,6 +1009,12 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, | |||
1003 | session->intr_sock = intr_sock; | 1009 | session->intr_sock = intr_sock; |
1004 | session->state = BT_CONNECTED; | 1010 | session->state = BT_CONNECTED; |
1005 | 1011 | ||
1012 | session->conn = hidp_get_connection(session); | ||
1013 | if (!session->conn) { | ||
1014 | err = -ENOTCONN; | ||
1015 | goto failed; | ||
1016 | } | ||
1017 | |||
1006 | setup_timer(&session->timer, hidp_idle_timeout, (unsigned long)session); | 1018 | setup_timer(&session->timer, hidp_idle_timeout, (unsigned long)session); |
1007 | 1019 | ||
1008 | skb_queue_head_init(&session->ctrl_transmit); | 1020 | skb_queue_head_init(&session->ctrl_transmit); |
@@ -1015,9 +1027,11 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, | |||
1015 | session->flags = req->flags & (1 << HIDP_BLUETOOTH_VENDOR_ID); | 1027 | session->flags = req->flags & (1 << HIDP_BLUETOOTH_VENDOR_ID); |
1016 | session->idle_to = req->idle_to; | 1028 | session->idle_to = req->idle_to; |
1017 | 1029 | ||
1030 | __hidp_link_session(session); | ||
1031 | |||
1018 | if (req->rd_size > 0) { | 1032 | if (req->rd_size > 0) { |
1019 | err = hidp_setup_hid(session, req); | 1033 | err = hidp_setup_hid(session, req); |
1020 | if (err && err != -ENODEV) | 1034 | if (err) |
1021 | goto purge; | 1035 | goto purge; |
1022 | } | 1036 | } |
1023 | 1037 | ||
@@ -1027,8 +1041,6 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, | |||
1027 | goto purge; | 1041 | goto purge; |
1028 | } | 1042 | } |
1029 | 1043 | ||
1030 | __hidp_link_session(session); | ||
1031 | |||
1032 | hidp_set_timer(session); | 1044 | hidp_set_timer(session); |
1033 | 1045 | ||
1034 | if (session->hid) { | 1046 | if (session->hid) { |
@@ -1054,7 +1066,11 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, | |||
1054 | !session->waiting_for_startup); | 1066 | !session->waiting_for_startup); |
1055 | } | 1067 | } |
1056 | 1068 | ||
1057 | err = hid_add_device(session->hid); | 1069 | if (session->hid) |
1070 | err = hid_add_device(session->hid); | ||
1071 | else | ||
1072 | err = input_register_device(session->input); | ||
1073 | |||
1058 | if (err < 0) { | 1074 | if (err < 0) { |
1059 | atomic_inc(&session->terminate); | 1075 | atomic_inc(&session->terminate); |
1060 | wake_up_process(session->task); | 1076 | wake_up_process(session->task); |
@@ -1077,8 +1093,6 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, | |||
1077 | unlink: | 1093 | unlink: |
1078 | hidp_del_timer(session); | 1094 | hidp_del_timer(session); |
1079 | 1095 | ||
1080 | __hidp_unlink_session(session); | ||
1081 | |||
1082 | if (session->input) { | 1096 | if (session->input) { |
1083 | input_unregister_device(session->input); | 1097 | input_unregister_device(session->input); |
1084 | session->input = NULL; | 1098 | session->input = NULL; |
@@ -1093,6 +1107,8 @@ unlink: | |||
1093 | session->rd_data = NULL; | 1107 | session->rd_data = NULL; |
1094 | 1108 | ||
1095 | purge: | 1109 | purge: |
1110 | __hidp_unlink_session(session); | ||
1111 | |||
1096 | skb_queue_purge(&session->ctrl_transmit); | 1112 | skb_queue_purge(&session->ctrl_transmit); |
1097 | skb_queue_purge(&session->intr_transmit); | 1113 | skb_queue_purge(&session->intr_transmit); |
1098 | 1114 | ||
@@ -1134,19 +1150,16 @@ int hidp_del_connection(struct hidp_conndel_req *req) | |||
1134 | 1150 | ||
1135 | int hidp_get_connlist(struct hidp_connlist_req *req) | 1151 | int hidp_get_connlist(struct hidp_connlist_req *req) |
1136 | { | 1152 | { |
1137 | struct list_head *p; | 1153 | struct hidp_session *session; |
1138 | int err = 0, n = 0; | 1154 | int err = 0, n = 0; |
1139 | 1155 | ||
1140 | BT_DBG(""); | 1156 | BT_DBG(""); |
1141 | 1157 | ||
1142 | down_read(&hidp_session_sem); | 1158 | down_read(&hidp_session_sem); |
1143 | 1159 | ||
1144 | list_for_each(p, &hidp_session_list) { | 1160 | list_for_each_entry(session, &hidp_session_list, list) { |
1145 | struct hidp_session *session; | ||
1146 | struct hidp_conninfo ci; | 1161 | struct hidp_conninfo ci; |
1147 | 1162 | ||
1148 | session = list_entry(p, struct hidp_session, list); | ||
1149 | |||
1150 | __hidp_copy_session(session, &ci); | 1163 | __hidp_copy_session(session, &ci); |
1151 | 1164 | ||
1152 | if (copy_to_user(req->ci, &ci, sizeof(ci))) { | 1165 | if (copy_to_user(req->ci, &ci, sizeof(ci))) { |
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 8cd12917733b..e8a6837996cf 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
@@ -57,9 +57,10 @@ | |||
57 | #include <net/bluetooth/smp.h> | 57 | #include <net/bluetooth/smp.h> |
58 | 58 | ||
59 | int disable_ertm; | 59 | int disable_ertm; |
60 | int enable_hs; | ||
60 | 61 | ||
61 | static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN; | 62 | static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN; |
62 | static u8 l2cap_fixed_chan[8] = { 0x02, }; | 63 | static u8 l2cap_fixed_chan[8] = { L2CAP_FC_L2CAP, }; |
63 | 64 | ||
64 | static LIST_HEAD(chan_list); | 65 | static LIST_HEAD(chan_list); |
65 | static DEFINE_RWLOCK(chan_list_lock); | 66 | static DEFINE_RWLOCK(chan_list_lock); |
@@ -219,7 +220,7 @@ static u16 l2cap_alloc_cid(struct l2cap_conn *conn) | |||
219 | 220 | ||
220 | static void l2cap_set_timer(struct l2cap_chan *chan, struct timer_list *timer, long timeout) | 221 | static void l2cap_set_timer(struct l2cap_chan *chan, struct timer_list *timer, long timeout) |
221 | { | 222 | { |
222 | BT_DBG("chan %p state %d timeout %ld", chan->sk, chan->state, timeout); | 223 | BT_DBG("chan %p state %d timeout %ld", chan, chan->state, timeout); |
223 | 224 | ||
224 | if (!mod_timer(timer, jiffies + msecs_to_jiffies(timeout))) | 225 | if (!mod_timer(timer, jiffies + msecs_to_jiffies(timeout))) |
225 | chan_hold(chan); | 226 | chan_hold(chan); |
@@ -251,7 +252,7 @@ static void l2cap_chan_timeout(unsigned long arg) | |||
251 | 252 | ||
252 | if (sock_owned_by_user(sk)) { | 253 | if (sock_owned_by_user(sk)) { |
253 | /* sk is owned by user. Try again later */ | 254 | /* sk is owned by user. Try again later */ |
254 | __set_chan_timer(chan, HZ / 5); | 255 | __set_chan_timer(chan, L2CAP_DISC_TIMEOUT); |
255 | bh_unlock_sock(sk); | 256 | bh_unlock_sock(sk); |
256 | chan_put(chan); | 257 | chan_put(chan); |
257 | return; | 258 | return; |
@@ -293,6 +294,8 @@ struct l2cap_chan *l2cap_chan_create(struct sock *sk) | |||
293 | 294 | ||
294 | atomic_set(&chan->refcnt, 1); | 295 | atomic_set(&chan->refcnt, 1); |
295 | 296 | ||
297 | BT_DBG("sk %p chan %p", sk, chan); | ||
298 | |||
296 | return chan; | 299 | return chan; |
297 | } | 300 | } |
298 | 301 | ||
@@ -310,7 +313,7 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) | |||
310 | BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn, | 313 | BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn, |
311 | chan->psm, chan->dcid); | 314 | chan->psm, chan->dcid); |
312 | 315 | ||
313 | conn->disc_reason = 0x13; | 316 | conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM; |
314 | 317 | ||
315 | chan->conn = conn; | 318 | chan->conn = conn; |
316 | 319 | ||
@@ -337,6 +340,13 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) | |||
337 | chan->omtu = L2CAP_DEFAULT_MTU; | 340 | chan->omtu = L2CAP_DEFAULT_MTU; |
338 | } | 341 | } |
339 | 342 | ||
343 | chan->local_id = L2CAP_BESTEFFORT_ID; | ||
344 | chan->local_stype = L2CAP_SERV_BESTEFFORT; | ||
345 | chan->local_msdu = L2CAP_DEFAULT_MAX_SDU_SIZE; | ||
346 | chan->local_sdu_itime = L2CAP_DEFAULT_SDU_ITIME; | ||
347 | chan->local_acc_lat = L2CAP_DEFAULT_ACC_LAT; | ||
348 | chan->local_flush_to = L2CAP_DEFAULT_FLUSH_TO; | ||
349 | |||
340 | chan_hold(chan); | 350 | chan_hold(chan); |
341 | 351 | ||
342 | list_add(&chan->list, &conn->chan_l); | 352 | list_add(&chan->list, &conn->chan_l); |
@@ -556,34 +566,58 @@ static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, | |||
556 | flags = ACL_START; | 566 | flags = ACL_START; |
557 | 567 | ||
558 | bt_cb(skb)->force_active = BT_POWER_FORCE_ACTIVE_ON; | 568 | bt_cb(skb)->force_active = BT_POWER_FORCE_ACTIVE_ON; |
569 | skb->priority = HCI_PRIO_MAX; | ||
570 | |||
571 | hci_send_acl(conn->hchan, skb, flags); | ||
572 | } | ||
573 | |||
574 | static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb) | ||
575 | { | ||
576 | struct hci_conn *hcon = chan->conn->hcon; | ||
577 | u16 flags; | ||
578 | |||
579 | BT_DBG("chan %p, skb %p len %d priority %u", chan, skb, skb->len, | ||
580 | skb->priority); | ||
581 | |||
582 | if (!test_bit(FLAG_FLUSHABLE, &chan->flags) && | ||
583 | lmp_no_flush_capable(hcon->hdev)) | ||
584 | flags = ACL_START_NO_FLUSH; | ||
585 | else | ||
586 | flags = ACL_START; | ||
559 | 587 | ||
560 | hci_send_acl(conn->hcon, skb, flags); | 588 | bt_cb(skb)->force_active = test_bit(FLAG_FORCE_ACTIVE, &chan->flags); |
589 | hci_send_acl(chan->conn->hchan, skb, flags); | ||
561 | } | 590 | } |
562 | 591 | ||
563 | static inline void l2cap_send_sframe(struct l2cap_chan *chan, u16 control) | 592 | static inline void l2cap_send_sframe(struct l2cap_chan *chan, u32 control) |
564 | { | 593 | { |
565 | struct sk_buff *skb; | 594 | struct sk_buff *skb; |
566 | struct l2cap_hdr *lh; | 595 | struct l2cap_hdr *lh; |
567 | struct l2cap_conn *conn = chan->conn; | 596 | struct l2cap_conn *conn = chan->conn; |
568 | int count, hlen = L2CAP_HDR_SIZE + 2; | 597 | int count, hlen; |
569 | u8 flags; | ||
570 | 598 | ||
571 | if (chan->state != BT_CONNECTED) | 599 | if (chan->state != BT_CONNECTED) |
572 | return; | 600 | return; |
573 | 601 | ||
602 | if (test_bit(FLAG_EXT_CTRL, &chan->flags)) | ||
603 | hlen = L2CAP_EXT_HDR_SIZE; | ||
604 | else | ||
605 | hlen = L2CAP_ENH_HDR_SIZE; | ||
606 | |||
574 | if (chan->fcs == L2CAP_FCS_CRC16) | 607 | if (chan->fcs == L2CAP_FCS_CRC16) |
575 | hlen += 2; | 608 | hlen += L2CAP_FCS_SIZE; |
576 | 609 | ||
577 | BT_DBG("chan %p, control 0x%2.2x", chan, control); | 610 | BT_DBG("chan %p, control 0x%8.8x", chan, control); |
578 | 611 | ||
579 | count = min_t(unsigned int, conn->mtu, hlen); | 612 | count = min_t(unsigned int, conn->mtu, hlen); |
580 | control |= L2CAP_CTRL_FRAME_TYPE; | 613 | |
614 | control |= __set_sframe(chan); | ||
581 | 615 | ||
582 | if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state)) | 616 | if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state)) |
583 | control |= L2CAP_CTRL_FINAL; | 617 | control |= __set_ctrl_final(chan); |
584 | 618 | ||
585 | if (test_and_clear_bit(CONN_SEND_PBIT, &chan->conn_state)) | 619 | if (test_and_clear_bit(CONN_SEND_PBIT, &chan->conn_state)) |
586 | control |= L2CAP_CTRL_POLL; | 620 | control |= __set_ctrl_poll(chan); |
587 | 621 | ||
588 | skb = bt_skb_alloc(count, GFP_ATOMIC); | 622 | skb = bt_skb_alloc(count, GFP_ATOMIC); |
589 | if (!skb) | 623 | if (!skb) |
@@ -592,32 +626,27 @@ static inline void l2cap_send_sframe(struct l2cap_chan *chan, u16 control) | |||
592 | lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE); | 626 | lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE); |
593 | lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE); | 627 | lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE); |
594 | lh->cid = cpu_to_le16(chan->dcid); | 628 | lh->cid = cpu_to_le16(chan->dcid); |
595 | put_unaligned_le16(control, skb_put(skb, 2)); | 629 | |
630 | __put_control(chan, control, skb_put(skb, __ctrl_size(chan))); | ||
596 | 631 | ||
597 | if (chan->fcs == L2CAP_FCS_CRC16) { | 632 | if (chan->fcs == L2CAP_FCS_CRC16) { |
598 | u16 fcs = crc16(0, (u8 *)lh, count - 2); | 633 | u16 fcs = crc16(0, (u8 *)lh, count - L2CAP_FCS_SIZE); |
599 | put_unaligned_le16(fcs, skb_put(skb, 2)); | 634 | put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE)); |
600 | } | 635 | } |
601 | 636 | ||
602 | if (lmp_no_flush_capable(conn->hcon->hdev)) | 637 | skb->priority = HCI_PRIO_MAX; |
603 | flags = ACL_START_NO_FLUSH; | 638 | l2cap_do_send(chan, skb); |
604 | else | ||
605 | flags = ACL_START; | ||
606 | |||
607 | bt_cb(skb)->force_active = chan->force_active; | ||
608 | |||
609 | hci_send_acl(chan->conn->hcon, skb, flags); | ||
610 | } | 639 | } |
611 | 640 | ||
612 | static inline void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, u16 control) | 641 | static inline void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, u32 control) |
613 | { | 642 | { |
614 | if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) { | 643 | if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) { |
615 | control |= L2CAP_SUPER_RCV_NOT_READY; | 644 | control |= __set_ctrl_super(chan, L2CAP_SUPER_RNR); |
616 | set_bit(CONN_RNR_SENT, &chan->conn_state); | 645 | set_bit(CONN_RNR_SENT, &chan->conn_state); |
617 | } else | 646 | } else |
618 | control |= L2CAP_SUPER_RCV_READY; | 647 | control |= __set_ctrl_super(chan, L2CAP_SUPER_RR); |
619 | 648 | ||
620 | control |= chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; | 649 | control |= __set_reqseq(chan, chan->buffer_seq); |
621 | 650 | ||
622 | l2cap_send_sframe(chan, control); | 651 | l2cap_send_sframe(chan, control); |
623 | } | 652 | } |
@@ -947,7 +976,7 @@ static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err) | |||
947 | list_for_each_entry(chan, &conn->chan_l, list) { | 976 | list_for_each_entry(chan, &conn->chan_l, list) { |
948 | struct sock *sk = chan->sk; | 977 | struct sock *sk = chan->sk; |
949 | 978 | ||
950 | if (chan->force_reliable) | 979 | if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags)) |
951 | sk->sk_err = err; | 980 | sk->sk_err = err; |
952 | } | 981 | } |
953 | 982 | ||
@@ -986,6 +1015,8 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err) | |||
986 | chan->ops->close(chan->data); | 1015 | chan->ops->close(chan->data); |
987 | } | 1016 | } |
988 | 1017 | ||
1018 | hci_chan_del(conn->hchan); | ||
1019 | |||
989 | if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) | 1020 | if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) |
990 | del_timer_sync(&conn->info_timer); | 1021 | del_timer_sync(&conn->info_timer); |
991 | 1022 | ||
@@ -1008,18 +1039,26 @@ static void security_timeout(unsigned long arg) | |||
1008 | static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status) | 1039 | static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status) |
1009 | { | 1040 | { |
1010 | struct l2cap_conn *conn = hcon->l2cap_data; | 1041 | struct l2cap_conn *conn = hcon->l2cap_data; |
1042 | struct hci_chan *hchan; | ||
1011 | 1043 | ||
1012 | if (conn || status) | 1044 | if (conn || status) |
1013 | return conn; | 1045 | return conn; |
1014 | 1046 | ||
1047 | hchan = hci_chan_create(hcon); | ||
1048 | if (!hchan) | ||
1049 | return NULL; | ||
1050 | |||
1015 | conn = kzalloc(sizeof(struct l2cap_conn), GFP_ATOMIC); | 1051 | conn = kzalloc(sizeof(struct l2cap_conn), GFP_ATOMIC); |
1016 | if (!conn) | 1052 | if (!conn) { |
1053 | hci_chan_del(hchan); | ||
1017 | return NULL; | 1054 | return NULL; |
1055 | } | ||
1018 | 1056 | ||
1019 | hcon->l2cap_data = conn; | 1057 | hcon->l2cap_data = conn; |
1020 | conn->hcon = hcon; | 1058 | conn->hcon = hcon; |
1059 | conn->hchan = hchan; | ||
1021 | 1060 | ||
1022 | BT_DBG("hcon %p conn %p", hcon, conn); | 1061 | BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan); |
1023 | 1062 | ||
1024 | if (hcon->hdev->le_mtu && hcon->type == LE_LINK) | 1063 | if (hcon->hdev->le_mtu && hcon->type == LE_LINK) |
1025 | conn->mtu = hcon->hdev->le_mtu; | 1064 | conn->mtu = hcon->hdev->le_mtu; |
@@ -1043,7 +1082,7 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status) | |||
1043 | setup_timer(&conn->info_timer, l2cap_info_timeout, | 1082 | setup_timer(&conn->info_timer, l2cap_info_timeout, |
1044 | (unsigned long) conn); | 1083 | (unsigned long) conn); |
1045 | 1084 | ||
1046 | conn->disc_reason = 0x13; | 1085 | conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM; |
1047 | 1086 | ||
1048 | return conn; | 1087 | return conn; |
1049 | } | 1088 | } |
@@ -1245,47 +1284,35 @@ static void l2cap_drop_acked_frames(struct l2cap_chan *chan) | |||
1245 | __clear_retrans_timer(chan); | 1284 | __clear_retrans_timer(chan); |
1246 | } | 1285 | } |
1247 | 1286 | ||
1248 | static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb) | ||
1249 | { | ||
1250 | struct hci_conn *hcon = chan->conn->hcon; | ||
1251 | u16 flags; | ||
1252 | |||
1253 | BT_DBG("chan %p, skb %p len %d", chan, skb, skb->len); | ||
1254 | |||
1255 | if (!chan->flushable && lmp_no_flush_capable(hcon->hdev)) | ||
1256 | flags = ACL_START_NO_FLUSH; | ||
1257 | else | ||
1258 | flags = ACL_START; | ||
1259 | |||
1260 | bt_cb(skb)->force_active = chan->force_active; | ||
1261 | hci_send_acl(hcon, skb, flags); | ||
1262 | } | ||
1263 | |||
1264 | static void l2cap_streaming_send(struct l2cap_chan *chan) | 1287 | static void l2cap_streaming_send(struct l2cap_chan *chan) |
1265 | { | 1288 | { |
1266 | struct sk_buff *skb; | 1289 | struct sk_buff *skb; |
1267 | u16 control, fcs; | 1290 | u32 control; |
1291 | u16 fcs; | ||
1268 | 1292 | ||
1269 | while ((skb = skb_dequeue(&chan->tx_q))) { | 1293 | while ((skb = skb_dequeue(&chan->tx_q))) { |
1270 | control = get_unaligned_le16(skb->data + L2CAP_HDR_SIZE); | 1294 | control = __get_control(chan, skb->data + L2CAP_HDR_SIZE); |
1271 | control |= chan->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT; | 1295 | control |= __set_txseq(chan, chan->next_tx_seq); |
1272 | put_unaligned_le16(control, skb->data + L2CAP_HDR_SIZE); | 1296 | __put_control(chan, control, skb->data + L2CAP_HDR_SIZE); |
1273 | 1297 | ||
1274 | if (chan->fcs == L2CAP_FCS_CRC16) { | 1298 | if (chan->fcs == L2CAP_FCS_CRC16) { |
1275 | fcs = crc16(0, (u8 *)skb->data, skb->len - 2); | 1299 | fcs = crc16(0, (u8 *)skb->data, |
1276 | put_unaligned_le16(fcs, skb->data + skb->len - 2); | 1300 | skb->len - L2CAP_FCS_SIZE); |
1301 | put_unaligned_le16(fcs, | ||
1302 | skb->data + skb->len - L2CAP_FCS_SIZE); | ||
1277 | } | 1303 | } |
1278 | 1304 | ||
1279 | l2cap_do_send(chan, skb); | 1305 | l2cap_do_send(chan, skb); |
1280 | 1306 | ||
1281 | chan->next_tx_seq = (chan->next_tx_seq + 1) % 64; | 1307 | chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq); |
1282 | } | 1308 | } |
1283 | } | 1309 | } |
1284 | 1310 | ||
1285 | static void l2cap_retransmit_one_frame(struct l2cap_chan *chan, u8 tx_seq) | 1311 | static void l2cap_retransmit_one_frame(struct l2cap_chan *chan, u16 tx_seq) |
1286 | { | 1312 | { |
1287 | struct sk_buff *skb, *tx_skb; | 1313 | struct sk_buff *skb, *tx_skb; |
1288 | u16 control, fcs; | 1314 | u16 fcs; |
1315 | u32 control; | ||
1289 | 1316 | ||
1290 | skb = skb_peek(&chan->tx_q); | 1317 | skb = skb_peek(&chan->tx_q); |
1291 | if (!skb) | 1318 | if (!skb) |
@@ -1308,20 +1335,23 @@ static void l2cap_retransmit_one_frame(struct l2cap_chan *chan, u8 tx_seq) | |||
1308 | 1335 | ||
1309 | tx_skb = skb_clone(skb, GFP_ATOMIC); | 1336 | tx_skb = skb_clone(skb, GFP_ATOMIC); |
1310 | bt_cb(skb)->retries++; | 1337 | bt_cb(skb)->retries++; |
1311 | control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE); | 1338 | |
1312 | control &= L2CAP_CTRL_SAR; | 1339 | control = __get_control(chan, tx_skb->data + L2CAP_HDR_SIZE); |
1340 | control &= __get_sar_mask(chan); | ||
1313 | 1341 | ||
1314 | if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state)) | 1342 | if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state)) |
1315 | control |= L2CAP_CTRL_FINAL; | 1343 | control |= __set_ctrl_final(chan); |
1316 | 1344 | ||
1317 | control |= (chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT) | 1345 | control |= __set_reqseq(chan, chan->buffer_seq); |
1318 | | (tx_seq << L2CAP_CTRL_TXSEQ_SHIFT); | 1346 | control |= __set_txseq(chan, tx_seq); |
1319 | 1347 | ||
1320 | put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE); | 1348 | __put_control(chan, control, tx_skb->data + L2CAP_HDR_SIZE); |
1321 | 1349 | ||
1322 | if (chan->fcs == L2CAP_FCS_CRC16) { | 1350 | if (chan->fcs == L2CAP_FCS_CRC16) { |
1323 | fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2); | 1351 | fcs = crc16(0, (u8 *)tx_skb->data, |
1324 | put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2); | 1352 | tx_skb->len - L2CAP_FCS_SIZE); |
1353 | put_unaligned_le16(fcs, | ||
1354 | tx_skb->data + tx_skb->len - L2CAP_FCS_SIZE); | ||
1325 | } | 1355 | } |
1326 | 1356 | ||
1327 | l2cap_do_send(chan, tx_skb); | 1357 | l2cap_do_send(chan, tx_skb); |
@@ -1330,7 +1360,8 @@ static void l2cap_retransmit_one_frame(struct l2cap_chan *chan, u8 tx_seq) | |||
1330 | static int l2cap_ertm_send(struct l2cap_chan *chan) | 1360 | static int l2cap_ertm_send(struct l2cap_chan *chan) |
1331 | { | 1361 | { |
1332 | struct sk_buff *skb, *tx_skb; | 1362 | struct sk_buff *skb, *tx_skb; |
1333 | u16 control, fcs; | 1363 | u16 fcs; |
1364 | u32 control; | ||
1334 | int nsent = 0; | 1365 | int nsent = 0; |
1335 | 1366 | ||
1336 | if (chan->state != BT_CONNECTED) | 1367 | if (chan->state != BT_CONNECTED) |
@@ -1348,20 +1379,22 @@ static int l2cap_ertm_send(struct l2cap_chan *chan) | |||
1348 | 1379 | ||
1349 | bt_cb(skb)->retries++; | 1380 | bt_cb(skb)->retries++; |
1350 | 1381 | ||
1351 | control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE); | 1382 | control = __get_control(chan, tx_skb->data + L2CAP_HDR_SIZE); |
1352 | control &= L2CAP_CTRL_SAR; | 1383 | control &= __get_sar_mask(chan); |
1353 | 1384 | ||
1354 | if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state)) | 1385 | if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state)) |
1355 | control |= L2CAP_CTRL_FINAL; | 1386 | control |= __set_ctrl_final(chan); |
1356 | 1387 | ||
1357 | control |= (chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT) | 1388 | control |= __set_reqseq(chan, chan->buffer_seq); |
1358 | | (chan->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT); | 1389 | control |= __set_txseq(chan, chan->next_tx_seq); |
1359 | put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE); | ||
1360 | 1390 | ||
1391 | __put_control(chan, control, tx_skb->data + L2CAP_HDR_SIZE); | ||
1361 | 1392 | ||
1362 | if (chan->fcs == L2CAP_FCS_CRC16) { | 1393 | if (chan->fcs == L2CAP_FCS_CRC16) { |
1363 | fcs = crc16(0, (u8 *)skb->data, tx_skb->len - 2); | 1394 | fcs = crc16(0, (u8 *)skb->data, |
1364 | put_unaligned_le16(fcs, skb->data + tx_skb->len - 2); | 1395 | tx_skb->len - L2CAP_FCS_SIZE); |
1396 | put_unaligned_le16(fcs, skb->data + | ||
1397 | tx_skb->len - L2CAP_FCS_SIZE); | ||
1365 | } | 1398 | } |
1366 | 1399 | ||
1367 | l2cap_do_send(chan, tx_skb); | 1400 | l2cap_do_send(chan, tx_skb); |
@@ -1369,7 +1402,8 @@ static int l2cap_ertm_send(struct l2cap_chan *chan) | |||
1369 | __set_retrans_timer(chan); | 1402 | __set_retrans_timer(chan); |
1370 | 1403 | ||
1371 | bt_cb(skb)->tx_seq = chan->next_tx_seq; | 1404 | bt_cb(skb)->tx_seq = chan->next_tx_seq; |
1372 | chan->next_tx_seq = (chan->next_tx_seq + 1) % 64; | 1405 | |
1406 | chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq); | ||
1373 | 1407 | ||
1374 | if (bt_cb(skb)->retries == 1) | 1408 | if (bt_cb(skb)->retries == 1) |
1375 | chan->unacked_frames++; | 1409 | chan->unacked_frames++; |
@@ -1401,12 +1435,12 @@ static int l2cap_retransmit_frames(struct l2cap_chan *chan) | |||
1401 | 1435 | ||
1402 | static void l2cap_send_ack(struct l2cap_chan *chan) | 1436 | static void l2cap_send_ack(struct l2cap_chan *chan) |
1403 | { | 1437 | { |
1404 | u16 control = 0; | 1438 | u32 control = 0; |
1405 | 1439 | ||
1406 | control |= chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; | 1440 | control |= __set_reqseq(chan, chan->buffer_seq); |
1407 | 1441 | ||
1408 | if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) { | 1442 | if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) { |
1409 | control |= L2CAP_SUPER_RCV_NOT_READY; | 1443 | control |= __set_ctrl_super(chan, L2CAP_SUPER_RNR); |
1410 | set_bit(CONN_RNR_SENT, &chan->conn_state); | 1444 | set_bit(CONN_RNR_SENT, &chan->conn_state); |
1411 | l2cap_send_sframe(chan, control); | 1445 | l2cap_send_sframe(chan, control); |
1412 | return; | 1446 | return; |
@@ -1415,20 +1449,20 @@ static void l2cap_send_ack(struct l2cap_chan *chan) | |||
1415 | if (l2cap_ertm_send(chan) > 0) | 1449 | if (l2cap_ertm_send(chan) > 0) |
1416 | return; | 1450 | return; |
1417 | 1451 | ||
1418 | control |= L2CAP_SUPER_RCV_READY; | 1452 | control |= __set_ctrl_super(chan, L2CAP_SUPER_RR); |
1419 | l2cap_send_sframe(chan, control); | 1453 | l2cap_send_sframe(chan, control); |
1420 | } | 1454 | } |
1421 | 1455 | ||
1422 | static void l2cap_send_srejtail(struct l2cap_chan *chan) | 1456 | static void l2cap_send_srejtail(struct l2cap_chan *chan) |
1423 | { | 1457 | { |
1424 | struct srej_list *tail; | 1458 | struct srej_list *tail; |
1425 | u16 control; | 1459 | u32 control; |
1426 | 1460 | ||
1427 | control = L2CAP_SUPER_SELECT_REJECT; | 1461 | control = __set_ctrl_super(chan, L2CAP_SUPER_SREJ); |
1428 | control |= L2CAP_CTRL_FINAL; | 1462 | control |= __set_ctrl_final(chan); |
1429 | 1463 | ||
1430 | tail = list_entry((&chan->srej_l)->prev, struct srej_list, list); | 1464 | tail = list_entry((&chan->srej_l)->prev, struct srej_list, list); |
1431 | control |= tail->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT; | 1465 | control |= __set_reqseq(chan, tail->tx_seq); |
1432 | 1466 | ||
1433 | l2cap_send_sframe(chan, control); | 1467 | l2cap_send_sframe(chan, control); |
1434 | } | 1468 | } |
@@ -1456,6 +1490,8 @@ static inline int l2cap_skbuff_fromiovec(struct sock *sk, struct msghdr *msg, in | |||
1456 | if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count)) | 1490 | if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count)) |
1457 | return -EFAULT; | 1491 | return -EFAULT; |
1458 | 1492 | ||
1493 | (*frag)->priority = skb->priority; | ||
1494 | |||
1459 | sent += count; | 1495 | sent += count; |
1460 | len -= count; | 1496 | len -= count; |
1461 | 1497 | ||
@@ -1465,15 +1501,17 @@ static inline int l2cap_skbuff_fromiovec(struct sock *sk, struct msghdr *msg, in | |||
1465 | return sent; | 1501 | return sent; |
1466 | } | 1502 | } |
1467 | 1503 | ||
1468 | static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len) | 1504 | static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan, |
1505 | struct msghdr *msg, size_t len, | ||
1506 | u32 priority) | ||
1469 | { | 1507 | { |
1470 | struct sock *sk = chan->sk; | 1508 | struct sock *sk = chan->sk; |
1471 | struct l2cap_conn *conn = chan->conn; | 1509 | struct l2cap_conn *conn = chan->conn; |
1472 | struct sk_buff *skb; | 1510 | struct sk_buff *skb; |
1473 | int err, count, hlen = L2CAP_HDR_SIZE + 2; | 1511 | int err, count, hlen = L2CAP_HDR_SIZE + L2CAP_PSMLEN_SIZE; |
1474 | struct l2cap_hdr *lh; | 1512 | struct l2cap_hdr *lh; |
1475 | 1513 | ||
1476 | BT_DBG("sk %p len %d", sk, (int)len); | 1514 | BT_DBG("sk %p len %d priority %u", sk, (int)len, priority); |
1477 | 1515 | ||
1478 | count = min_t(unsigned int, (conn->mtu - hlen), len); | 1516 | count = min_t(unsigned int, (conn->mtu - hlen), len); |
1479 | skb = bt_skb_send_alloc(sk, count + hlen, | 1517 | skb = bt_skb_send_alloc(sk, count + hlen, |
@@ -1481,6 +1519,8 @@ static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan, struct | |||
1481 | if (!skb) | 1519 | if (!skb) |
1482 | return ERR_PTR(err); | 1520 | return ERR_PTR(err); |
1483 | 1521 | ||
1522 | skb->priority = priority; | ||
1523 | |||
1484 | /* Create L2CAP header */ | 1524 | /* Create L2CAP header */ |
1485 | lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE); | 1525 | lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE); |
1486 | lh->cid = cpu_to_le16(chan->dcid); | 1526 | lh->cid = cpu_to_le16(chan->dcid); |
@@ -1495,7 +1535,9 @@ static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan, struct | |||
1495 | return skb; | 1535 | return skb; |
1496 | } | 1536 | } |
1497 | 1537 | ||
1498 | static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len) | 1538 | static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan, |
1539 | struct msghdr *msg, size_t len, | ||
1540 | u32 priority) | ||
1499 | { | 1541 | { |
1500 | struct sock *sk = chan->sk; | 1542 | struct sock *sk = chan->sk; |
1501 | struct l2cap_conn *conn = chan->conn; | 1543 | struct l2cap_conn *conn = chan->conn; |
@@ -1511,6 +1553,8 @@ static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan, struct ms | |||
1511 | if (!skb) | 1553 | if (!skb) |
1512 | return ERR_PTR(err); | 1554 | return ERR_PTR(err); |
1513 | 1555 | ||
1556 | skb->priority = priority; | ||
1557 | |||
1514 | /* Create L2CAP header */ | 1558 | /* Create L2CAP header */ |
1515 | lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE); | 1559 | lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE); |
1516 | lh->cid = cpu_to_le16(chan->dcid); | 1560 | lh->cid = cpu_to_le16(chan->dcid); |
@@ -1526,12 +1570,12 @@ static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan, struct ms | |||
1526 | 1570 | ||
1527 | static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan, | 1571 | static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan, |
1528 | struct msghdr *msg, size_t len, | 1572 | struct msghdr *msg, size_t len, |
1529 | u16 control, u16 sdulen) | 1573 | u32 control, u16 sdulen) |
1530 | { | 1574 | { |
1531 | struct sock *sk = chan->sk; | 1575 | struct sock *sk = chan->sk; |
1532 | struct l2cap_conn *conn = chan->conn; | 1576 | struct l2cap_conn *conn = chan->conn; |
1533 | struct sk_buff *skb; | 1577 | struct sk_buff *skb; |
1534 | int err, count, hlen = L2CAP_HDR_SIZE + 2; | 1578 | int err, count, hlen; |
1535 | struct l2cap_hdr *lh; | 1579 | struct l2cap_hdr *lh; |
1536 | 1580 | ||
1537 | BT_DBG("sk %p len %d", sk, (int)len); | 1581 | BT_DBG("sk %p len %d", sk, (int)len); |
@@ -1539,11 +1583,16 @@ static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan, | |||
1539 | if (!conn) | 1583 | if (!conn) |
1540 | return ERR_PTR(-ENOTCONN); | 1584 | return ERR_PTR(-ENOTCONN); |
1541 | 1585 | ||
1586 | if (test_bit(FLAG_EXT_CTRL, &chan->flags)) | ||
1587 | hlen = L2CAP_EXT_HDR_SIZE; | ||
1588 | else | ||
1589 | hlen = L2CAP_ENH_HDR_SIZE; | ||
1590 | |||
1542 | if (sdulen) | 1591 | if (sdulen) |
1543 | hlen += 2; | 1592 | hlen += L2CAP_SDULEN_SIZE; |
1544 | 1593 | ||
1545 | if (chan->fcs == L2CAP_FCS_CRC16) | 1594 | if (chan->fcs == L2CAP_FCS_CRC16) |
1546 | hlen += 2; | 1595 | hlen += L2CAP_FCS_SIZE; |
1547 | 1596 | ||
1548 | count = min_t(unsigned int, (conn->mtu - hlen), len); | 1597 | count = min_t(unsigned int, (conn->mtu - hlen), len); |
1549 | skb = bt_skb_send_alloc(sk, count + hlen, | 1598 | skb = bt_skb_send_alloc(sk, count + hlen, |
@@ -1555,9 +1604,11 @@ static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan, | |||
1555 | lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE); | 1604 | lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE); |
1556 | lh->cid = cpu_to_le16(chan->dcid); | 1605 | lh->cid = cpu_to_le16(chan->dcid); |
1557 | lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE)); | 1606 | lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE)); |
1558 | put_unaligned_le16(control, skb_put(skb, 2)); | 1607 | |
1608 | __put_control(chan, control, skb_put(skb, __ctrl_size(chan))); | ||
1609 | |||
1559 | if (sdulen) | 1610 | if (sdulen) |
1560 | put_unaligned_le16(sdulen, skb_put(skb, 2)); | 1611 | put_unaligned_le16(sdulen, skb_put(skb, L2CAP_SDULEN_SIZE)); |
1561 | 1612 | ||
1562 | err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb); | 1613 | err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb); |
1563 | if (unlikely(err < 0)) { | 1614 | if (unlikely(err < 0)) { |
@@ -1566,7 +1617,7 @@ static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan, | |||
1566 | } | 1617 | } |
1567 | 1618 | ||
1568 | if (chan->fcs == L2CAP_FCS_CRC16) | 1619 | if (chan->fcs == L2CAP_FCS_CRC16) |
1569 | put_unaligned_le16(0, skb_put(skb, 2)); | 1620 | put_unaligned_le16(0, skb_put(skb, L2CAP_FCS_SIZE)); |
1570 | 1621 | ||
1571 | bt_cb(skb)->retries = 0; | 1622 | bt_cb(skb)->retries = 0; |
1572 | return skb; | 1623 | return skb; |
@@ -1576,11 +1627,11 @@ static int l2cap_sar_segment_sdu(struct l2cap_chan *chan, struct msghdr *msg, si | |||
1576 | { | 1627 | { |
1577 | struct sk_buff *skb; | 1628 | struct sk_buff *skb; |
1578 | struct sk_buff_head sar_queue; | 1629 | struct sk_buff_head sar_queue; |
1579 | u16 control; | 1630 | u32 control; |
1580 | size_t size = 0; | 1631 | size_t size = 0; |
1581 | 1632 | ||
1582 | skb_queue_head_init(&sar_queue); | 1633 | skb_queue_head_init(&sar_queue); |
1583 | control = L2CAP_SDU_START; | 1634 | control = __set_ctrl_sar(chan, L2CAP_SAR_START); |
1584 | skb = l2cap_create_iframe_pdu(chan, msg, chan->remote_mps, control, len); | 1635 | skb = l2cap_create_iframe_pdu(chan, msg, chan->remote_mps, control, len); |
1585 | if (IS_ERR(skb)) | 1636 | if (IS_ERR(skb)) |
1586 | return PTR_ERR(skb); | 1637 | return PTR_ERR(skb); |
@@ -1593,10 +1644,10 @@ static int l2cap_sar_segment_sdu(struct l2cap_chan *chan, struct msghdr *msg, si | |||
1593 | size_t buflen; | 1644 | size_t buflen; |
1594 | 1645 | ||
1595 | if (len > chan->remote_mps) { | 1646 | if (len > chan->remote_mps) { |
1596 | control = L2CAP_SDU_CONTINUE; | 1647 | control = __set_ctrl_sar(chan, L2CAP_SAR_CONTINUE); |
1597 | buflen = chan->remote_mps; | 1648 | buflen = chan->remote_mps; |
1598 | } else { | 1649 | } else { |
1599 | control = L2CAP_SDU_END; | 1650 | control = __set_ctrl_sar(chan, L2CAP_SAR_END); |
1600 | buflen = len; | 1651 | buflen = len; |
1601 | } | 1652 | } |
1602 | 1653 | ||
@@ -1617,15 +1668,16 @@ static int l2cap_sar_segment_sdu(struct l2cap_chan *chan, struct msghdr *msg, si | |||
1617 | return size; | 1668 | return size; |
1618 | } | 1669 | } |
1619 | 1670 | ||
1620 | int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len) | 1671 | int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len, |
1672 | u32 priority) | ||
1621 | { | 1673 | { |
1622 | struct sk_buff *skb; | 1674 | struct sk_buff *skb; |
1623 | u16 control; | 1675 | u32 control; |
1624 | int err; | 1676 | int err; |
1625 | 1677 | ||
1626 | /* Connectionless channel */ | 1678 | /* Connectionless channel */ |
1627 | if (chan->chan_type == L2CAP_CHAN_CONN_LESS) { | 1679 | if (chan->chan_type == L2CAP_CHAN_CONN_LESS) { |
1628 | skb = l2cap_create_connless_pdu(chan, msg, len); | 1680 | skb = l2cap_create_connless_pdu(chan, msg, len, priority); |
1629 | if (IS_ERR(skb)) | 1681 | if (IS_ERR(skb)) |
1630 | return PTR_ERR(skb); | 1682 | return PTR_ERR(skb); |
1631 | 1683 | ||
@@ -1640,7 +1692,7 @@ int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len) | |||
1640 | return -EMSGSIZE; | 1692 | return -EMSGSIZE; |
1641 | 1693 | ||
1642 | /* Create a basic PDU */ | 1694 | /* Create a basic PDU */ |
1643 | skb = l2cap_create_basic_pdu(chan, msg, len); | 1695 | skb = l2cap_create_basic_pdu(chan, msg, len, priority); |
1644 | if (IS_ERR(skb)) | 1696 | if (IS_ERR(skb)) |
1645 | return PTR_ERR(skb); | 1697 | return PTR_ERR(skb); |
1646 | 1698 | ||
@@ -1652,7 +1704,7 @@ int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len) | |||
1652 | case L2CAP_MODE_STREAMING: | 1704 | case L2CAP_MODE_STREAMING: |
1653 | /* Entire SDU fits into one PDU */ | 1705 | /* Entire SDU fits into one PDU */ |
1654 | if (len <= chan->remote_mps) { | 1706 | if (len <= chan->remote_mps) { |
1655 | control = L2CAP_SDU_UNSEGMENTED; | 1707 | control = __set_ctrl_sar(chan, L2CAP_SAR_UNSEGMENTED); |
1656 | skb = l2cap_create_iframe_pdu(chan, msg, len, control, | 1708 | skb = l2cap_create_iframe_pdu(chan, msg, len, control, |
1657 | 0); | 1709 | 0); |
1658 | if (IS_ERR(skb)) | 1710 | if (IS_ERR(skb)) |
@@ -1850,6 +1902,37 @@ static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val) | |||
1850 | *ptr += L2CAP_CONF_OPT_SIZE + len; | 1902 | *ptr += L2CAP_CONF_OPT_SIZE + len; |
1851 | } | 1903 | } |
1852 | 1904 | ||
1905 | static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan) | ||
1906 | { | ||
1907 | struct l2cap_conf_efs efs; | ||
1908 | |||
1909 | switch(chan->mode) { | ||
1910 | case L2CAP_MODE_ERTM: | ||
1911 | efs.id = chan->local_id; | ||
1912 | efs.stype = chan->local_stype; | ||
1913 | efs.msdu = cpu_to_le16(chan->local_msdu); | ||
1914 | efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime); | ||
1915 | efs.acc_lat = cpu_to_le32(L2CAP_DEFAULT_ACC_LAT); | ||
1916 | efs.flush_to = cpu_to_le32(L2CAP_DEFAULT_FLUSH_TO); | ||
1917 | break; | ||
1918 | |||
1919 | case L2CAP_MODE_STREAMING: | ||
1920 | efs.id = 1; | ||
1921 | efs.stype = L2CAP_SERV_BESTEFFORT; | ||
1922 | efs.msdu = cpu_to_le16(chan->local_msdu); | ||
1923 | efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime); | ||
1924 | efs.acc_lat = 0; | ||
1925 | efs.flush_to = 0; | ||
1926 | break; | ||
1927 | |||
1928 | default: | ||
1929 | return; | ||
1930 | } | ||
1931 | |||
1932 | l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs), | ||
1933 | (unsigned long) &efs); | ||
1934 | } | ||
1935 | |||
1853 | static void l2cap_ack_timeout(unsigned long arg) | 1936 | static void l2cap_ack_timeout(unsigned long arg) |
1854 | { | 1937 | { |
1855 | struct l2cap_chan *chan = (void *) arg; | 1938 | struct l2cap_chan *chan = (void *) arg; |
@@ -1896,11 +1979,36 @@ static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask) | |||
1896 | } | 1979 | } |
1897 | } | 1980 | } |
1898 | 1981 | ||
1982 | static inline bool __l2cap_ews_supported(struct l2cap_chan *chan) | ||
1983 | { | ||
1984 | return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_WINDOW; | ||
1985 | } | ||
1986 | |||
1987 | static inline bool __l2cap_efs_supported(struct l2cap_chan *chan) | ||
1988 | { | ||
1989 | return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_FLOW; | ||
1990 | } | ||
1991 | |||
1992 | static inline void l2cap_txwin_setup(struct l2cap_chan *chan) | ||
1993 | { | ||
1994 | if (chan->tx_win > L2CAP_DEFAULT_TX_WINDOW && | ||
1995 | __l2cap_ews_supported(chan)) { | ||
1996 | /* use extended control field */ | ||
1997 | set_bit(FLAG_EXT_CTRL, &chan->flags); | ||
1998 | chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW; | ||
1999 | } else { | ||
2000 | chan->tx_win = min_t(u16, chan->tx_win, | ||
2001 | L2CAP_DEFAULT_TX_WINDOW); | ||
2002 | chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW; | ||
2003 | } | ||
2004 | } | ||
2005 | |||
1899 | static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data) | 2006 | static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data) |
1900 | { | 2007 | { |
1901 | struct l2cap_conf_req *req = data; | 2008 | struct l2cap_conf_req *req = data; |
1902 | struct l2cap_conf_rfc rfc = { .mode = chan->mode }; | 2009 | struct l2cap_conf_rfc rfc = { .mode = chan->mode }; |
1903 | void *ptr = req->data; | 2010 | void *ptr = req->data; |
2011 | u16 size; | ||
1904 | 2012 | ||
1905 | BT_DBG("chan %p", chan); | 2013 | BT_DBG("chan %p", chan); |
1906 | 2014 | ||
@@ -1913,6 +2021,9 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data) | |||
1913 | if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state)) | 2021 | if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state)) |
1914 | break; | 2022 | break; |
1915 | 2023 | ||
2024 | if (__l2cap_efs_supported(chan)) | ||
2025 | set_bit(FLAG_EFS_ENABLE, &chan->flags); | ||
2026 | |||
1916 | /* fall through */ | 2027 | /* fall through */ |
1917 | default: | 2028 | default: |
1918 | chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask); | 2029 | chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask); |
@@ -1942,17 +2053,27 @@ done: | |||
1942 | 2053 | ||
1943 | case L2CAP_MODE_ERTM: | 2054 | case L2CAP_MODE_ERTM: |
1944 | rfc.mode = L2CAP_MODE_ERTM; | 2055 | rfc.mode = L2CAP_MODE_ERTM; |
1945 | rfc.txwin_size = chan->tx_win; | ||
1946 | rfc.max_transmit = chan->max_tx; | 2056 | rfc.max_transmit = chan->max_tx; |
1947 | rfc.retrans_timeout = 0; | 2057 | rfc.retrans_timeout = 0; |
1948 | rfc.monitor_timeout = 0; | 2058 | rfc.monitor_timeout = 0; |
1949 | rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE); | 2059 | |
1950 | if (L2CAP_DEFAULT_MAX_PDU_SIZE > chan->conn->mtu - 10) | 2060 | size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu - |
1951 | rfc.max_pdu_size = cpu_to_le16(chan->conn->mtu - 10); | 2061 | L2CAP_EXT_HDR_SIZE - |
2062 | L2CAP_SDULEN_SIZE - | ||
2063 | L2CAP_FCS_SIZE); | ||
2064 | rfc.max_pdu_size = cpu_to_le16(size); | ||
2065 | |||
2066 | l2cap_txwin_setup(chan); | ||
2067 | |||
2068 | rfc.txwin_size = min_t(u16, chan->tx_win, | ||
2069 | L2CAP_DEFAULT_TX_WINDOW); | ||
1952 | 2070 | ||
1953 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), | 2071 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), |
1954 | (unsigned long) &rfc); | 2072 | (unsigned long) &rfc); |
1955 | 2073 | ||
2074 | if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) | ||
2075 | l2cap_add_opt_efs(&ptr, chan); | ||
2076 | |||
1956 | if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS)) | 2077 | if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS)) |
1957 | break; | 2078 | break; |
1958 | 2079 | ||
@@ -1961,6 +2082,10 @@ done: | |||
1961 | chan->fcs = L2CAP_FCS_NONE; | 2082 | chan->fcs = L2CAP_FCS_NONE; |
1962 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs); | 2083 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs); |
1963 | } | 2084 | } |
2085 | |||
2086 | if (test_bit(FLAG_EXT_CTRL, &chan->flags)) | ||
2087 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2, | ||
2088 | chan->tx_win); | ||
1964 | break; | 2089 | break; |
1965 | 2090 | ||
1966 | case L2CAP_MODE_STREAMING: | 2091 | case L2CAP_MODE_STREAMING: |
@@ -1969,13 +2094,19 @@ done: | |||
1969 | rfc.max_transmit = 0; | 2094 | rfc.max_transmit = 0; |
1970 | rfc.retrans_timeout = 0; | 2095 | rfc.retrans_timeout = 0; |
1971 | rfc.monitor_timeout = 0; | 2096 | rfc.monitor_timeout = 0; |
1972 | rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE); | 2097 | |
1973 | if (L2CAP_DEFAULT_MAX_PDU_SIZE > chan->conn->mtu - 10) | 2098 | size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu - |
1974 | rfc.max_pdu_size = cpu_to_le16(chan->conn->mtu - 10); | 2099 | L2CAP_EXT_HDR_SIZE - |
2100 | L2CAP_SDULEN_SIZE - | ||
2101 | L2CAP_FCS_SIZE); | ||
2102 | rfc.max_pdu_size = cpu_to_le16(size); | ||
1975 | 2103 | ||
1976 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), | 2104 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), |
1977 | (unsigned long) &rfc); | 2105 | (unsigned long) &rfc); |
1978 | 2106 | ||
2107 | if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) | ||
2108 | l2cap_add_opt_efs(&ptr, chan); | ||
2109 | |||
1979 | if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS)) | 2110 | if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS)) |
1980 | break; | 2111 | break; |
1981 | 2112 | ||
@@ -2002,8 +2133,11 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data) | |||
2002 | int type, hint, olen; | 2133 | int type, hint, olen; |
2003 | unsigned long val; | 2134 | unsigned long val; |
2004 | struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC }; | 2135 | struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC }; |
2136 | struct l2cap_conf_efs efs; | ||
2137 | u8 remote_efs = 0; | ||
2005 | u16 mtu = L2CAP_DEFAULT_MTU; | 2138 | u16 mtu = L2CAP_DEFAULT_MTU; |
2006 | u16 result = L2CAP_CONF_SUCCESS; | 2139 | u16 result = L2CAP_CONF_SUCCESS; |
2140 | u16 size; | ||
2007 | 2141 | ||
2008 | BT_DBG("chan %p", chan); | 2142 | BT_DBG("chan %p", chan); |
2009 | 2143 | ||
@@ -2033,7 +2167,22 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data) | |||
2033 | case L2CAP_CONF_FCS: | 2167 | case L2CAP_CONF_FCS: |
2034 | if (val == L2CAP_FCS_NONE) | 2168 | if (val == L2CAP_FCS_NONE) |
2035 | set_bit(CONF_NO_FCS_RECV, &chan->conf_state); | 2169 | set_bit(CONF_NO_FCS_RECV, &chan->conf_state); |
2170 | break; | ||
2171 | |||
2172 | case L2CAP_CONF_EFS: | ||
2173 | remote_efs = 1; | ||
2174 | if (olen == sizeof(efs)) | ||
2175 | memcpy(&efs, (void *) val, olen); | ||
2176 | break; | ||
2177 | |||
2178 | case L2CAP_CONF_EWS: | ||
2179 | if (!enable_hs) | ||
2180 | return -ECONNREFUSED; | ||
2036 | 2181 | ||
2182 | set_bit(FLAG_EXT_CTRL, &chan->flags); | ||
2183 | set_bit(CONF_EWS_RECV, &chan->conf_state); | ||
2184 | chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW; | ||
2185 | chan->remote_tx_win = val; | ||
2037 | break; | 2186 | break; |
2038 | 2187 | ||
2039 | default: | 2188 | default: |
@@ -2058,6 +2207,13 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data) | |||
2058 | break; | 2207 | break; |
2059 | } | 2208 | } |
2060 | 2209 | ||
2210 | if (remote_efs) { | ||
2211 | if (__l2cap_efs_supported(chan)) | ||
2212 | set_bit(FLAG_EFS_ENABLE, &chan->flags); | ||
2213 | else | ||
2214 | return -ECONNREFUSED; | ||
2215 | } | ||
2216 | |||
2061 | if (chan->mode != rfc.mode) | 2217 | if (chan->mode != rfc.mode) |
2062 | return -ECONNREFUSED; | 2218 | return -ECONNREFUSED; |
2063 | 2219 | ||
@@ -2076,7 +2232,6 @@ done: | |||
2076 | sizeof(rfc), (unsigned long) &rfc); | 2232 | sizeof(rfc), (unsigned long) &rfc); |
2077 | } | 2233 | } |
2078 | 2234 | ||
2079 | |||
2080 | if (result == L2CAP_CONF_SUCCESS) { | 2235 | if (result == L2CAP_CONF_SUCCESS) { |
2081 | /* Configure output options and let the other side know | 2236 | /* Configure output options and let the other side know |
2082 | * which ones we don't like. */ | 2237 | * which ones we don't like. */ |
@@ -2089,6 +2244,26 @@ done: | |||
2089 | } | 2244 | } |
2090 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu); | 2245 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu); |
2091 | 2246 | ||
2247 | if (remote_efs) { | ||
2248 | if (chan->local_stype != L2CAP_SERV_NOTRAFIC && | ||
2249 | efs.stype != L2CAP_SERV_NOTRAFIC && | ||
2250 | efs.stype != chan->local_stype) { | ||
2251 | |||
2252 | result = L2CAP_CONF_UNACCEPT; | ||
2253 | |||
2254 | if (chan->num_conf_req >= 1) | ||
2255 | return -ECONNREFUSED; | ||
2256 | |||
2257 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, | ||
2258 | sizeof(efs), | ||
2259 | (unsigned long) &efs); | ||
2260 | } else { | ||
2261 | /* Send PENDING Conf Rsp */ | ||
2262 | result = L2CAP_CONF_PENDING; | ||
2263 | set_bit(CONF_LOC_CONF_PEND, &chan->conf_state); | ||
2264 | } | ||
2265 | } | ||
2266 | |||
2092 | switch (rfc.mode) { | 2267 | switch (rfc.mode) { |
2093 | case L2CAP_MODE_BASIC: | 2268 | case L2CAP_MODE_BASIC: |
2094 | chan->fcs = L2CAP_FCS_NONE; | 2269 | chan->fcs = L2CAP_FCS_NONE; |
@@ -2096,13 +2271,20 @@ done: | |||
2096 | break; | 2271 | break; |
2097 | 2272 | ||
2098 | case L2CAP_MODE_ERTM: | 2273 | case L2CAP_MODE_ERTM: |
2099 | chan->remote_tx_win = rfc.txwin_size; | 2274 | if (!test_bit(CONF_EWS_RECV, &chan->conf_state)) |
2100 | chan->remote_max_tx = rfc.max_transmit; | 2275 | chan->remote_tx_win = rfc.txwin_size; |
2276 | else | ||
2277 | rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW; | ||
2101 | 2278 | ||
2102 | if (le16_to_cpu(rfc.max_pdu_size) > chan->conn->mtu - 10) | 2279 | chan->remote_max_tx = rfc.max_transmit; |
2103 | rfc.max_pdu_size = cpu_to_le16(chan->conn->mtu - 10); | ||
2104 | 2280 | ||
2105 | chan->remote_mps = le16_to_cpu(rfc.max_pdu_size); | 2281 | size = min_t(u16, le16_to_cpu(rfc.max_pdu_size), |
2282 | chan->conn->mtu - | ||
2283 | L2CAP_EXT_HDR_SIZE - | ||
2284 | L2CAP_SDULEN_SIZE - | ||
2285 | L2CAP_FCS_SIZE); | ||
2286 | rfc.max_pdu_size = cpu_to_le16(size); | ||
2287 | chan->remote_mps = size; | ||
2106 | 2288 | ||
2107 | rfc.retrans_timeout = | 2289 | rfc.retrans_timeout = |
2108 | le16_to_cpu(L2CAP_DEFAULT_RETRANS_TO); | 2290 | le16_to_cpu(L2CAP_DEFAULT_RETRANS_TO); |
@@ -2114,13 +2296,29 @@ done: | |||
2114 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, | 2296 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, |
2115 | sizeof(rfc), (unsigned long) &rfc); | 2297 | sizeof(rfc), (unsigned long) &rfc); |
2116 | 2298 | ||
2299 | if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) { | ||
2300 | chan->remote_id = efs.id; | ||
2301 | chan->remote_stype = efs.stype; | ||
2302 | chan->remote_msdu = le16_to_cpu(efs.msdu); | ||
2303 | chan->remote_flush_to = | ||
2304 | le32_to_cpu(efs.flush_to); | ||
2305 | chan->remote_acc_lat = | ||
2306 | le32_to_cpu(efs.acc_lat); | ||
2307 | chan->remote_sdu_itime = | ||
2308 | le32_to_cpu(efs.sdu_itime); | ||
2309 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, | ||
2310 | sizeof(efs), (unsigned long) &efs); | ||
2311 | } | ||
2117 | break; | 2312 | break; |
2118 | 2313 | ||
2119 | case L2CAP_MODE_STREAMING: | 2314 | case L2CAP_MODE_STREAMING: |
2120 | if (le16_to_cpu(rfc.max_pdu_size) > chan->conn->mtu - 10) | 2315 | size = min_t(u16, le16_to_cpu(rfc.max_pdu_size), |
2121 | rfc.max_pdu_size = cpu_to_le16(chan->conn->mtu - 10); | 2316 | chan->conn->mtu - |
2122 | 2317 | L2CAP_EXT_HDR_SIZE - | |
2123 | chan->remote_mps = le16_to_cpu(rfc.max_pdu_size); | 2318 | L2CAP_SDULEN_SIZE - |
2319 | L2CAP_FCS_SIZE); | ||
2320 | rfc.max_pdu_size = cpu_to_le16(size); | ||
2321 | chan->remote_mps = size; | ||
2124 | 2322 | ||
2125 | set_bit(CONF_MODE_DONE, &chan->conf_state); | 2323 | set_bit(CONF_MODE_DONE, &chan->conf_state); |
2126 | 2324 | ||
@@ -2153,6 +2351,7 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, voi | |||
2153 | int type, olen; | 2351 | int type, olen; |
2154 | unsigned long val; | 2352 | unsigned long val; |
2155 | struct l2cap_conf_rfc rfc; | 2353 | struct l2cap_conf_rfc rfc; |
2354 | struct l2cap_conf_efs efs; | ||
2156 | 2355 | ||
2157 | BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data); | 2356 | BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data); |
2158 | 2357 | ||
@@ -2188,6 +2387,26 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, voi | |||
2188 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, | 2387 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, |
2189 | sizeof(rfc), (unsigned long) &rfc); | 2388 | sizeof(rfc), (unsigned long) &rfc); |
2190 | break; | 2389 | break; |
2390 | |||
2391 | case L2CAP_CONF_EWS: | ||
2392 | chan->tx_win = min_t(u16, val, | ||
2393 | L2CAP_DEFAULT_EXT_WINDOW); | ||
2394 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2, | ||
2395 | chan->tx_win); | ||
2396 | break; | ||
2397 | |||
2398 | case L2CAP_CONF_EFS: | ||
2399 | if (olen == sizeof(efs)) | ||
2400 | memcpy(&efs, (void *)val, olen); | ||
2401 | |||
2402 | if (chan->local_stype != L2CAP_SERV_NOTRAFIC && | ||
2403 | efs.stype != L2CAP_SERV_NOTRAFIC && | ||
2404 | efs.stype != chan->local_stype) | ||
2405 | return -ECONNREFUSED; | ||
2406 | |||
2407 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, | ||
2408 | sizeof(efs), (unsigned long) &efs); | ||
2409 | break; | ||
2191 | } | 2410 | } |
2192 | } | 2411 | } |
2193 | 2412 | ||
@@ -2196,13 +2415,23 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, voi | |||
2196 | 2415 | ||
2197 | chan->mode = rfc.mode; | 2416 | chan->mode = rfc.mode; |
2198 | 2417 | ||
2199 | if (*result == L2CAP_CONF_SUCCESS) { | 2418 | if (*result == L2CAP_CONF_SUCCESS || *result == L2CAP_CONF_PENDING) { |
2200 | switch (rfc.mode) { | 2419 | switch (rfc.mode) { |
2201 | case L2CAP_MODE_ERTM: | 2420 | case L2CAP_MODE_ERTM: |
2202 | chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout); | 2421 | chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout); |
2203 | chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout); | 2422 | chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout); |
2204 | chan->mps = le16_to_cpu(rfc.max_pdu_size); | 2423 | chan->mps = le16_to_cpu(rfc.max_pdu_size); |
2424 | |||
2425 | if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) { | ||
2426 | chan->local_msdu = le16_to_cpu(efs.msdu); | ||
2427 | chan->local_sdu_itime = | ||
2428 | le32_to_cpu(efs.sdu_itime); | ||
2429 | chan->local_acc_lat = le32_to_cpu(efs.acc_lat); | ||
2430 | chan->local_flush_to = | ||
2431 | le32_to_cpu(efs.flush_to); | ||
2432 | } | ||
2205 | break; | 2433 | break; |
2434 | |||
2206 | case L2CAP_MODE_STREAMING: | 2435 | case L2CAP_MODE_STREAMING: |
2207 | chan->mps = le16_to_cpu(rfc.max_pdu_size); | 2436 | chan->mps = le16_to_cpu(rfc.max_pdu_size); |
2208 | } | 2437 | } |
@@ -2330,7 +2559,7 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd | |||
2330 | /* Check if the ACL is secure enough (if not SDP) */ | 2559 | /* Check if the ACL is secure enough (if not SDP) */ |
2331 | if (psm != cpu_to_le16(0x0001) && | 2560 | if (psm != cpu_to_le16(0x0001) && |
2332 | !hci_conn_check_link_mode(conn->hcon)) { | 2561 | !hci_conn_check_link_mode(conn->hcon)) { |
2333 | conn->disc_reason = 0x05; | 2562 | conn->disc_reason = HCI_ERROR_AUTH_FAILURE; |
2334 | result = L2CAP_CR_SEC_BLOCK; | 2563 | result = L2CAP_CR_SEC_BLOCK; |
2335 | goto response; | 2564 | goto response; |
2336 | } | 2565 | } |
@@ -2488,7 +2717,7 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd | |||
2488 | if (sock_owned_by_user(sk)) { | 2717 | if (sock_owned_by_user(sk)) { |
2489 | l2cap_state_change(chan, BT_DISCONN); | 2718 | l2cap_state_change(chan, BT_DISCONN); |
2490 | __clear_chan_timer(chan); | 2719 | __clear_chan_timer(chan); |
2491 | __set_chan_timer(chan, HZ / 5); | 2720 | __set_chan_timer(chan, L2CAP_DISC_TIMEOUT); |
2492 | break; | 2721 | break; |
2493 | } | 2722 | } |
2494 | 2723 | ||
@@ -2602,6 +2831,21 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
2602 | chan->num_conf_req++; | 2831 | chan->num_conf_req++; |
2603 | } | 2832 | } |
2604 | 2833 | ||
2834 | /* Got Conf Rsp PENDING from remote side and asume we sent | ||
2835 | Conf Rsp PENDING in the code above */ | ||
2836 | if (test_bit(CONF_REM_CONF_PEND, &chan->conf_state) && | ||
2837 | test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) { | ||
2838 | |||
2839 | /* check compatibility */ | ||
2840 | |||
2841 | clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state); | ||
2842 | set_bit(CONF_OUTPUT_DONE, &chan->conf_state); | ||
2843 | |||
2844 | l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, | ||
2845 | l2cap_build_conf_rsp(chan, rsp, | ||
2846 | L2CAP_CONF_SUCCESS, 0x0000), rsp); | ||
2847 | } | ||
2848 | |||
2605 | unlock: | 2849 | unlock: |
2606 | bh_unlock_sock(sk); | 2850 | bh_unlock_sock(sk); |
2607 | return 0; | 2851 | return 0; |
@@ -2631,8 +2875,33 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
2631 | switch (result) { | 2875 | switch (result) { |
2632 | case L2CAP_CONF_SUCCESS: | 2876 | case L2CAP_CONF_SUCCESS: |
2633 | l2cap_conf_rfc_get(chan, rsp->data, len); | 2877 | l2cap_conf_rfc_get(chan, rsp->data, len); |
2878 | clear_bit(CONF_REM_CONF_PEND, &chan->conf_state); | ||
2634 | break; | 2879 | break; |
2635 | 2880 | ||
2881 | case L2CAP_CONF_PENDING: | ||
2882 | set_bit(CONF_REM_CONF_PEND, &chan->conf_state); | ||
2883 | |||
2884 | if (test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) { | ||
2885 | char buf[64]; | ||
2886 | |||
2887 | len = l2cap_parse_conf_rsp(chan, rsp->data, len, | ||
2888 | buf, &result); | ||
2889 | if (len < 0) { | ||
2890 | l2cap_send_disconn_req(conn, chan, ECONNRESET); | ||
2891 | goto done; | ||
2892 | } | ||
2893 | |||
2894 | /* check compatibility */ | ||
2895 | |||
2896 | clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state); | ||
2897 | set_bit(CONF_OUTPUT_DONE, &chan->conf_state); | ||
2898 | |||
2899 | l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, | ||
2900 | l2cap_build_conf_rsp(chan, buf, | ||
2901 | L2CAP_CONF_SUCCESS, 0x0000), buf); | ||
2902 | } | ||
2903 | goto done; | ||
2904 | |||
2636 | case L2CAP_CONF_UNACCEPT: | 2905 | case L2CAP_CONF_UNACCEPT: |
2637 | if (chan->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) { | 2906 | if (chan->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) { |
2638 | char req[64]; | 2907 | char req[64]; |
@@ -2661,7 +2930,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
2661 | 2930 | ||
2662 | default: | 2931 | default: |
2663 | sk->sk_err = ECONNRESET; | 2932 | sk->sk_err = ECONNRESET; |
2664 | __set_chan_timer(chan, HZ * 5); | 2933 | __set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT); |
2665 | l2cap_send_disconn_req(conn, chan, ECONNRESET); | 2934 | l2cap_send_disconn_req(conn, chan, ECONNRESET); |
2666 | goto done; | 2935 | goto done; |
2667 | } | 2936 | } |
@@ -2718,7 +2987,7 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd | |||
2718 | if (sock_owned_by_user(sk)) { | 2987 | if (sock_owned_by_user(sk)) { |
2719 | l2cap_state_change(chan, BT_DISCONN); | 2988 | l2cap_state_change(chan, BT_DISCONN); |
2720 | __clear_chan_timer(chan); | 2989 | __clear_chan_timer(chan); |
2721 | __set_chan_timer(chan, HZ / 5); | 2990 | __set_chan_timer(chan, L2CAP_DISC_TIMEOUT); |
2722 | bh_unlock_sock(sk); | 2991 | bh_unlock_sock(sk); |
2723 | return 0; | 2992 | return 0; |
2724 | } | 2993 | } |
@@ -2752,7 +3021,7 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd | |||
2752 | if (sock_owned_by_user(sk)) { | 3021 | if (sock_owned_by_user(sk)) { |
2753 | l2cap_state_change(chan,BT_DISCONN); | 3022 | l2cap_state_change(chan,BT_DISCONN); |
2754 | __clear_chan_timer(chan); | 3023 | __clear_chan_timer(chan); |
2755 | __set_chan_timer(chan, HZ / 5); | 3024 | __set_chan_timer(chan, L2CAP_DISC_TIMEOUT); |
2756 | bh_unlock_sock(sk); | 3025 | bh_unlock_sock(sk); |
2757 | return 0; | 3026 | return 0; |
2758 | } | 3027 | } |
@@ -2782,15 +3051,25 @@ static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cm | |||
2782 | if (!disable_ertm) | 3051 | if (!disable_ertm) |
2783 | feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING | 3052 | feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING |
2784 | | L2CAP_FEAT_FCS; | 3053 | | L2CAP_FEAT_FCS; |
3054 | if (enable_hs) | ||
3055 | feat_mask |= L2CAP_FEAT_EXT_FLOW | ||
3056 | | L2CAP_FEAT_EXT_WINDOW; | ||
3057 | |||
2785 | put_unaligned_le32(feat_mask, rsp->data); | 3058 | put_unaligned_le32(feat_mask, rsp->data); |
2786 | l2cap_send_cmd(conn, cmd->ident, | 3059 | l2cap_send_cmd(conn, cmd->ident, |
2787 | L2CAP_INFO_RSP, sizeof(buf), buf); | 3060 | L2CAP_INFO_RSP, sizeof(buf), buf); |
2788 | } else if (type == L2CAP_IT_FIXED_CHAN) { | 3061 | } else if (type == L2CAP_IT_FIXED_CHAN) { |
2789 | u8 buf[12]; | 3062 | u8 buf[12]; |
2790 | struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf; | 3063 | struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf; |
3064 | |||
3065 | if (enable_hs) | ||
3066 | l2cap_fixed_chan[0] |= L2CAP_FC_A2MP; | ||
3067 | else | ||
3068 | l2cap_fixed_chan[0] &= ~L2CAP_FC_A2MP; | ||
3069 | |||
2791 | rsp->type = cpu_to_le16(L2CAP_IT_FIXED_CHAN); | 3070 | rsp->type = cpu_to_le16(L2CAP_IT_FIXED_CHAN); |
2792 | rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS); | 3071 | rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS); |
2793 | memcpy(buf + 4, l2cap_fixed_chan, 8); | 3072 | memcpy(rsp->data, l2cap_fixed_chan, sizeof(l2cap_fixed_chan)); |
2794 | l2cap_send_cmd(conn, cmd->ident, | 3073 | l2cap_send_cmd(conn, cmd->ident, |
2795 | L2CAP_INFO_RSP, sizeof(buf), buf); | 3074 | L2CAP_INFO_RSP, sizeof(buf), buf); |
2796 | } else { | 3075 | } else { |
@@ -2857,6 +3136,165 @@ static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cm | |||
2857 | return 0; | 3136 | return 0; |
2858 | } | 3137 | } |
2859 | 3138 | ||
3139 | static inline int l2cap_create_channel_req(struct l2cap_conn *conn, | ||
3140 | struct l2cap_cmd_hdr *cmd, u16 cmd_len, | ||
3141 | void *data) | ||
3142 | { | ||
3143 | struct l2cap_create_chan_req *req = data; | ||
3144 | struct l2cap_create_chan_rsp rsp; | ||
3145 | u16 psm, scid; | ||
3146 | |||
3147 | if (cmd_len != sizeof(*req)) | ||
3148 | return -EPROTO; | ||
3149 | |||
3150 | if (!enable_hs) | ||
3151 | return -EINVAL; | ||
3152 | |||
3153 | psm = le16_to_cpu(req->psm); | ||
3154 | scid = le16_to_cpu(req->scid); | ||
3155 | |||
3156 | BT_DBG("psm %d, scid %d, amp_id %d", psm, scid, req->amp_id); | ||
3157 | |||
3158 | /* Placeholder: Always reject */ | ||
3159 | rsp.dcid = 0; | ||
3160 | rsp.scid = cpu_to_le16(scid); | ||
3161 | rsp.result = L2CAP_CR_NO_MEM; | ||
3162 | rsp.status = L2CAP_CS_NO_INFO; | ||
3163 | |||
3164 | l2cap_send_cmd(conn, cmd->ident, L2CAP_CREATE_CHAN_RSP, | ||
3165 | sizeof(rsp), &rsp); | ||
3166 | |||
3167 | return 0; | ||
3168 | } | ||
3169 | |||
3170 | static inline int l2cap_create_channel_rsp(struct l2cap_conn *conn, | ||
3171 | struct l2cap_cmd_hdr *cmd, void *data) | ||
3172 | { | ||
3173 | BT_DBG("conn %p", conn); | ||
3174 | |||
3175 | return l2cap_connect_rsp(conn, cmd, data); | ||
3176 | } | ||
3177 | |||
3178 | static void l2cap_send_move_chan_rsp(struct l2cap_conn *conn, u8 ident, | ||
3179 | u16 icid, u16 result) | ||
3180 | { | ||
3181 | struct l2cap_move_chan_rsp rsp; | ||
3182 | |||
3183 | BT_DBG("icid %d, result %d", icid, result); | ||
3184 | |||
3185 | rsp.icid = cpu_to_le16(icid); | ||
3186 | rsp.result = cpu_to_le16(result); | ||
3187 | |||
3188 | l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_RSP, sizeof(rsp), &rsp); | ||
3189 | } | ||
3190 | |||
3191 | static void l2cap_send_move_chan_cfm(struct l2cap_conn *conn, | ||
3192 | struct l2cap_chan *chan, u16 icid, u16 result) | ||
3193 | { | ||
3194 | struct l2cap_move_chan_cfm cfm; | ||
3195 | u8 ident; | ||
3196 | |||
3197 | BT_DBG("icid %d, result %d", icid, result); | ||
3198 | |||
3199 | ident = l2cap_get_ident(conn); | ||
3200 | if (chan) | ||
3201 | chan->ident = ident; | ||
3202 | |||
3203 | cfm.icid = cpu_to_le16(icid); | ||
3204 | cfm.result = cpu_to_le16(result); | ||
3205 | |||
3206 | l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM, sizeof(cfm), &cfm); | ||
3207 | } | ||
3208 | |||
3209 | static void l2cap_send_move_chan_cfm_rsp(struct l2cap_conn *conn, u8 ident, | ||
3210 | u16 icid) | ||
3211 | { | ||
3212 | struct l2cap_move_chan_cfm_rsp rsp; | ||
3213 | |||
3214 | BT_DBG("icid %d", icid); | ||
3215 | |||
3216 | rsp.icid = cpu_to_le16(icid); | ||
3217 | l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM_RSP, sizeof(rsp), &rsp); | ||
3218 | } | ||
3219 | |||
3220 | static inline int l2cap_move_channel_req(struct l2cap_conn *conn, | ||
3221 | struct l2cap_cmd_hdr *cmd, u16 cmd_len, void *data) | ||
3222 | { | ||
3223 | struct l2cap_move_chan_req *req = data; | ||
3224 | u16 icid = 0; | ||
3225 | u16 result = L2CAP_MR_NOT_ALLOWED; | ||
3226 | |||
3227 | if (cmd_len != sizeof(*req)) | ||
3228 | return -EPROTO; | ||
3229 | |||
3230 | icid = le16_to_cpu(req->icid); | ||
3231 | |||
3232 | BT_DBG("icid %d, dest_amp_id %d", icid, req->dest_amp_id); | ||
3233 | |||
3234 | if (!enable_hs) | ||
3235 | return -EINVAL; | ||
3236 | |||
3237 | /* Placeholder: Always refuse */ | ||
3238 | l2cap_send_move_chan_rsp(conn, cmd->ident, icid, result); | ||
3239 | |||
3240 | return 0; | ||
3241 | } | ||
3242 | |||
3243 | static inline int l2cap_move_channel_rsp(struct l2cap_conn *conn, | ||
3244 | struct l2cap_cmd_hdr *cmd, u16 cmd_len, void *data) | ||
3245 | { | ||
3246 | struct l2cap_move_chan_rsp *rsp = data; | ||
3247 | u16 icid, result; | ||
3248 | |||
3249 | if (cmd_len != sizeof(*rsp)) | ||
3250 | return -EPROTO; | ||
3251 | |||
3252 | icid = le16_to_cpu(rsp->icid); | ||
3253 | result = le16_to_cpu(rsp->result); | ||
3254 | |||
3255 | BT_DBG("icid %d, result %d", icid, result); | ||
3256 | |||
3257 | /* Placeholder: Always unconfirmed */ | ||
3258 | l2cap_send_move_chan_cfm(conn, NULL, icid, L2CAP_MC_UNCONFIRMED); | ||
3259 | |||
3260 | return 0; | ||
3261 | } | ||
3262 | |||
3263 | static inline int l2cap_move_channel_confirm(struct l2cap_conn *conn, | ||
3264 | struct l2cap_cmd_hdr *cmd, u16 cmd_len, void *data) | ||
3265 | { | ||
3266 | struct l2cap_move_chan_cfm *cfm = data; | ||
3267 | u16 icid, result; | ||
3268 | |||
3269 | if (cmd_len != sizeof(*cfm)) | ||
3270 | return -EPROTO; | ||
3271 | |||
3272 | icid = le16_to_cpu(cfm->icid); | ||
3273 | result = le16_to_cpu(cfm->result); | ||
3274 | |||
3275 | BT_DBG("icid %d, result %d", icid, result); | ||
3276 | |||
3277 | l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid); | ||
3278 | |||
3279 | return 0; | ||
3280 | } | ||
3281 | |||
3282 | static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn, | ||
3283 | struct l2cap_cmd_hdr *cmd, u16 cmd_len, void *data) | ||
3284 | { | ||
3285 | struct l2cap_move_chan_cfm_rsp *rsp = data; | ||
3286 | u16 icid; | ||
3287 | |||
3288 | if (cmd_len != sizeof(*rsp)) | ||
3289 | return -EPROTO; | ||
3290 | |||
3291 | icid = le16_to_cpu(rsp->icid); | ||
3292 | |||
3293 | BT_DBG("icid %d", icid); | ||
3294 | |||
3295 | return 0; | ||
3296 | } | ||
3297 | |||
2860 | static inline int l2cap_check_conn_param(u16 min, u16 max, u16 latency, | 3298 | static inline int l2cap_check_conn_param(u16 min, u16 max, u16 latency, |
2861 | u16 to_multiplier) | 3299 | u16 to_multiplier) |
2862 | { | 3300 | { |
@@ -2969,6 +3407,30 @@ static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn, | |||
2969 | err = l2cap_information_rsp(conn, cmd, data); | 3407 | err = l2cap_information_rsp(conn, cmd, data); |
2970 | break; | 3408 | break; |
2971 | 3409 | ||
3410 | case L2CAP_CREATE_CHAN_REQ: | ||
3411 | err = l2cap_create_channel_req(conn, cmd, cmd_len, data); | ||
3412 | break; | ||
3413 | |||
3414 | case L2CAP_CREATE_CHAN_RSP: | ||
3415 | err = l2cap_create_channel_rsp(conn, cmd, data); | ||
3416 | break; | ||
3417 | |||
3418 | case L2CAP_MOVE_CHAN_REQ: | ||
3419 | err = l2cap_move_channel_req(conn, cmd, cmd_len, data); | ||
3420 | break; | ||
3421 | |||
3422 | case L2CAP_MOVE_CHAN_RSP: | ||
3423 | err = l2cap_move_channel_rsp(conn, cmd, cmd_len, data); | ||
3424 | break; | ||
3425 | |||
3426 | case L2CAP_MOVE_CHAN_CFM: | ||
3427 | err = l2cap_move_channel_confirm(conn, cmd, cmd_len, data); | ||
3428 | break; | ||
3429 | |||
3430 | case L2CAP_MOVE_CHAN_CFM_RSP: | ||
3431 | err = l2cap_move_channel_confirm_rsp(conn, cmd, cmd_len, data); | ||
3432 | break; | ||
3433 | |||
2972 | default: | 3434 | default: |
2973 | BT_ERR("Unknown BR/EDR signaling command 0x%2.2x", cmd->code); | 3435 | BT_ERR("Unknown BR/EDR signaling command 0x%2.2x", cmd->code); |
2974 | err = -EINVAL; | 3436 | err = -EINVAL; |
@@ -3047,10 +3509,15 @@ static inline void l2cap_sig_channel(struct l2cap_conn *conn, | |||
3047 | static int l2cap_check_fcs(struct l2cap_chan *chan, struct sk_buff *skb) | 3509 | static int l2cap_check_fcs(struct l2cap_chan *chan, struct sk_buff *skb) |
3048 | { | 3510 | { |
3049 | u16 our_fcs, rcv_fcs; | 3511 | u16 our_fcs, rcv_fcs; |
3050 | int hdr_size = L2CAP_HDR_SIZE + 2; | 3512 | int hdr_size; |
3513 | |||
3514 | if (test_bit(FLAG_EXT_CTRL, &chan->flags)) | ||
3515 | hdr_size = L2CAP_EXT_HDR_SIZE; | ||
3516 | else | ||
3517 | hdr_size = L2CAP_ENH_HDR_SIZE; | ||
3051 | 3518 | ||
3052 | if (chan->fcs == L2CAP_FCS_CRC16) { | 3519 | if (chan->fcs == L2CAP_FCS_CRC16) { |
3053 | skb_trim(skb, skb->len - 2); | 3520 | skb_trim(skb, skb->len - L2CAP_FCS_SIZE); |
3054 | rcv_fcs = get_unaligned_le16(skb->data + skb->len); | 3521 | rcv_fcs = get_unaligned_le16(skb->data + skb->len); |
3055 | our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size); | 3522 | our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size); |
3056 | 3523 | ||
@@ -3062,14 +3529,14 @@ static int l2cap_check_fcs(struct l2cap_chan *chan, struct sk_buff *skb) | |||
3062 | 3529 | ||
3063 | static inline void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan) | 3530 | static inline void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan) |
3064 | { | 3531 | { |
3065 | u16 control = 0; | 3532 | u32 control = 0; |
3066 | 3533 | ||
3067 | chan->frames_sent = 0; | 3534 | chan->frames_sent = 0; |
3068 | 3535 | ||
3069 | control |= chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; | 3536 | control |= __set_reqseq(chan, chan->buffer_seq); |
3070 | 3537 | ||
3071 | if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) { | 3538 | if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) { |
3072 | control |= L2CAP_SUPER_RCV_NOT_READY; | 3539 | control |= __set_ctrl_super(chan, L2CAP_SUPER_RNR); |
3073 | l2cap_send_sframe(chan, control); | 3540 | l2cap_send_sframe(chan, control); |
3074 | set_bit(CONN_RNR_SENT, &chan->conn_state); | 3541 | set_bit(CONN_RNR_SENT, &chan->conn_state); |
3075 | } | 3542 | } |
@@ -3081,12 +3548,12 @@ static inline void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan) | |||
3081 | 3548 | ||
3082 | if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state) && | 3549 | if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state) && |
3083 | chan->frames_sent == 0) { | 3550 | chan->frames_sent == 0) { |
3084 | control |= L2CAP_SUPER_RCV_READY; | 3551 | control |= __set_ctrl_super(chan, L2CAP_SUPER_RR); |
3085 | l2cap_send_sframe(chan, control); | 3552 | l2cap_send_sframe(chan, control); |
3086 | } | 3553 | } |
3087 | } | 3554 | } |
3088 | 3555 | ||
3089 | static int l2cap_add_to_srej_queue(struct l2cap_chan *chan, struct sk_buff *skb, u8 tx_seq, u8 sar) | 3556 | static int l2cap_add_to_srej_queue(struct l2cap_chan *chan, struct sk_buff *skb, u16 tx_seq, u8 sar) |
3090 | { | 3557 | { |
3091 | struct sk_buff *next_skb; | 3558 | struct sk_buff *next_skb; |
3092 | int tx_seq_offset, next_tx_seq_offset; | 3559 | int tx_seq_offset, next_tx_seq_offset; |
@@ -3100,18 +3567,14 @@ static int l2cap_add_to_srej_queue(struct l2cap_chan *chan, struct sk_buff *skb, | |||
3100 | return 0; | 3567 | return 0; |
3101 | } | 3568 | } |
3102 | 3569 | ||
3103 | tx_seq_offset = (tx_seq - chan->buffer_seq) % 64; | 3570 | tx_seq_offset = __seq_offset(chan, tx_seq, chan->buffer_seq); |
3104 | if (tx_seq_offset < 0) | ||
3105 | tx_seq_offset += 64; | ||
3106 | 3571 | ||
3107 | do { | 3572 | do { |
3108 | if (bt_cb(next_skb)->tx_seq == tx_seq) | 3573 | if (bt_cb(next_skb)->tx_seq == tx_seq) |
3109 | return -EINVAL; | 3574 | return -EINVAL; |
3110 | 3575 | ||
3111 | next_tx_seq_offset = (bt_cb(next_skb)->tx_seq - | 3576 | next_tx_seq_offset = __seq_offset(chan, |
3112 | chan->buffer_seq) % 64; | 3577 | bt_cb(next_skb)->tx_seq, chan->buffer_seq); |
3113 | if (next_tx_seq_offset < 0) | ||
3114 | next_tx_seq_offset += 64; | ||
3115 | 3578 | ||
3116 | if (next_tx_seq_offset > tx_seq_offset) { | 3579 | if (next_tx_seq_offset > tx_seq_offset) { |
3117 | __skb_queue_before(&chan->srej_q, next_skb, skb); | 3580 | __skb_queue_before(&chan->srej_q, next_skb, skb); |
@@ -3147,24 +3610,24 @@ static void append_skb_frag(struct sk_buff *skb, | |||
3147 | skb->truesize += new_frag->truesize; | 3610 | skb->truesize += new_frag->truesize; |
3148 | } | 3611 | } |
3149 | 3612 | ||
3150 | static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb, u16 control) | 3613 | static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb, u32 control) |
3151 | { | 3614 | { |
3152 | int err = -EINVAL; | 3615 | int err = -EINVAL; |
3153 | 3616 | ||
3154 | switch (control & L2CAP_CTRL_SAR) { | 3617 | switch (__get_ctrl_sar(chan, control)) { |
3155 | case L2CAP_SDU_UNSEGMENTED: | 3618 | case L2CAP_SAR_UNSEGMENTED: |
3156 | if (chan->sdu) | 3619 | if (chan->sdu) |
3157 | break; | 3620 | break; |
3158 | 3621 | ||
3159 | err = chan->ops->recv(chan->data, skb); | 3622 | err = chan->ops->recv(chan->data, skb); |
3160 | break; | 3623 | break; |
3161 | 3624 | ||
3162 | case L2CAP_SDU_START: | 3625 | case L2CAP_SAR_START: |
3163 | if (chan->sdu) | 3626 | if (chan->sdu) |
3164 | break; | 3627 | break; |
3165 | 3628 | ||
3166 | chan->sdu_len = get_unaligned_le16(skb->data); | 3629 | chan->sdu_len = get_unaligned_le16(skb->data); |
3167 | skb_pull(skb, 2); | 3630 | skb_pull(skb, L2CAP_SDULEN_SIZE); |
3168 | 3631 | ||
3169 | if (chan->sdu_len > chan->imtu) { | 3632 | if (chan->sdu_len > chan->imtu) { |
3170 | err = -EMSGSIZE; | 3633 | err = -EMSGSIZE; |
@@ -3181,7 +3644,7 @@ static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb, u1 | |||
3181 | err = 0; | 3644 | err = 0; |
3182 | break; | 3645 | break; |
3183 | 3646 | ||
3184 | case L2CAP_SDU_CONTINUE: | 3647 | case L2CAP_SAR_CONTINUE: |
3185 | if (!chan->sdu) | 3648 | if (!chan->sdu) |
3186 | break; | 3649 | break; |
3187 | 3650 | ||
@@ -3195,7 +3658,7 @@ static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb, u1 | |||
3195 | err = 0; | 3658 | err = 0; |
3196 | break; | 3659 | break; |
3197 | 3660 | ||
3198 | case L2CAP_SDU_END: | 3661 | case L2CAP_SAR_END: |
3199 | if (!chan->sdu) | 3662 | if (!chan->sdu) |
3200 | break; | 3663 | break; |
3201 | 3664 | ||
@@ -3230,14 +3693,14 @@ static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb, u1 | |||
3230 | 3693 | ||
3231 | static void l2cap_ertm_enter_local_busy(struct l2cap_chan *chan) | 3694 | static void l2cap_ertm_enter_local_busy(struct l2cap_chan *chan) |
3232 | { | 3695 | { |
3233 | u16 control; | 3696 | u32 control; |
3234 | 3697 | ||
3235 | BT_DBG("chan %p, Enter local busy", chan); | 3698 | BT_DBG("chan %p, Enter local busy", chan); |
3236 | 3699 | ||
3237 | set_bit(CONN_LOCAL_BUSY, &chan->conn_state); | 3700 | set_bit(CONN_LOCAL_BUSY, &chan->conn_state); |
3238 | 3701 | ||
3239 | control = chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; | 3702 | control = __set_reqseq(chan, chan->buffer_seq); |
3240 | control |= L2CAP_SUPER_RCV_NOT_READY; | 3703 | control |= __set_ctrl_super(chan, L2CAP_SUPER_RNR); |
3241 | l2cap_send_sframe(chan, control); | 3704 | l2cap_send_sframe(chan, control); |
3242 | 3705 | ||
3243 | set_bit(CONN_RNR_SENT, &chan->conn_state); | 3706 | set_bit(CONN_RNR_SENT, &chan->conn_state); |
@@ -3247,13 +3710,14 @@ static void l2cap_ertm_enter_local_busy(struct l2cap_chan *chan) | |||
3247 | 3710 | ||
3248 | static void l2cap_ertm_exit_local_busy(struct l2cap_chan *chan) | 3711 | static void l2cap_ertm_exit_local_busy(struct l2cap_chan *chan) |
3249 | { | 3712 | { |
3250 | u16 control; | 3713 | u32 control; |
3251 | 3714 | ||
3252 | if (!test_bit(CONN_RNR_SENT, &chan->conn_state)) | 3715 | if (!test_bit(CONN_RNR_SENT, &chan->conn_state)) |
3253 | goto done; | 3716 | goto done; |
3254 | 3717 | ||
3255 | control = chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; | 3718 | control = __set_reqseq(chan, chan->buffer_seq); |
3256 | control |= L2CAP_SUPER_RCV_READY | L2CAP_CTRL_POLL; | 3719 | control |= __set_ctrl_poll(chan); |
3720 | control |= __set_ctrl_super(chan, L2CAP_SUPER_RR); | ||
3257 | l2cap_send_sframe(chan, control); | 3721 | l2cap_send_sframe(chan, control); |
3258 | chan->retry_count = 1; | 3722 | chan->retry_count = 1; |
3259 | 3723 | ||
@@ -3279,10 +3743,10 @@ void l2cap_chan_busy(struct l2cap_chan *chan, int busy) | |||
3279 | } | 3743 | } |
3280 | } | 3744 | } |
3281 | 3745 | ||
3282 | static void l2cap_check_srej_gap(struct l2cap_chan *chan, u8 tx_seq) | 3746 | static void l2cap_check_srej_gap(struct l2cap_chan *chan, u16 tx_seq) |
3283 | { | 3747 | { |
3284 | struct sk_buff *skb; | 3748 | struct sk_buff *skb; |
3285 | u16 control; | 3749 | u32 control; |
3286 | 3750 | ||
3287 | while ((skb = skb_peek(&chan->srej_q)) && | 3751 | while ((skb = skb_peek(&chan->srej_q)) && |
3288 | !test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) { | 3752 | !test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) { |
@@ -3292,7 +3756,7 @@ static void l2cap_check_srej_gap(struct l2cap_chan *chan, u8 tx_seq) | |||
3292 | break; | 3756 | break; |
3293 | 3757 | ||
3294 | skb = skb_dequeue(&chan->srej_q); | 3758 | skb = skb_dequeue(&chan->srej_q); |
3295 | control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT; | 3759 | control = __set_ctrl_sar(chan, bt_cb(skb)->sar); |
3296 | err = l2cap_reassemble_sdu(chan, skb, control); | 3760 | err = l2cap_reassemble_sdu(chan, skb, control); |
3297 | 3761 | ||
3298 | if (err < 0) { | 3762 | if (err < 0) { |
@@ -3300,16 +3764,15 @@ static void l2cap_check_srej_gap(struct l2cap_chan *chan, u8 tx_seq) | |||
3300 | break; | 3764 | break; |
3301 | } | 3765 | } |
3302 | 3766 | ||
3303 | chan->buffer_seq_srej = | 3767 | chan->buffer_seq_srej = __next_seq(chan, chan->buffer_seq_srej); |
3304 | (chan->buffer_seq_srej + 1) % 64; | 3768 | tx_seq = __next_seq(chan, tx_seq); |
3305 | tx_seq = (tx_seq + 1) % 64; | ||
3306 | } | 3769 | } |
3307 | } | 3770 | } |
3308 | 3771 | ||
3309 | static void l2cap_resend_srejframe(struct l2cap_chan *chan, u8 tx_seq) | 3772 | static void l2cap_resend_srejframe(struct l2cap_chan *chan, u16 tx_seq) |
3310 | { | 3773 | { |
3311 | struct srej_list *l, *tmp; | 3774 | struct srej_list *l, *tmp; |
3312 | u16 control; | 3775 | u32 control; |
3313 | 3776 | ||
3314 | list_for_each_entry_safe(l, tmp, &chan->srej_l, list) { | 3777 | list_for_each_entry_safe(l, tmp, &chan->srej_l, list) { |
3315 | if (l->tx_seq == tx_seq) { | 3778 | if (l->tx_seq == tx_seq) { |
@@ -3317,45 +3780,48 @@ static void l2cap_resend_srejframe(struct l2cap_chan *chan, u8 tx_seq) | |||
3317 | kfree(l); | 3780 | kfree(l); |
3318 | return; | 3781 | return; |
3319 | } | 3782 | } |
3320 | control = L2CAP_SUPER_SELECT_REJECT; | 3783 | control = __set_ctrl_super(chan, L2CAP_SUPER_SREJ); |
3321 | control |= l->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT; | 3784 | control |= __set_reqseq(chan, l->tx_seq); |
3322 | l2cap_send_sframe(chan, control); | 3785 | l2cap_send_sframe(chan, control); |
3323 | list_del(&l->list); | 3786 | list_del(&l->list); |
3324 | list_add_tail(&l->list, &chan->srej_l); | 3787 | list_add_tail(&l->list, &chan->srej_l); |
3325 | } | 3788 | } |
3326 | } | 3789 | } |
3327 | 3790 | ||
3328 | static void l2cap_send_srejframe(struct l2cap_chan *chan, u8 tx_seq) | 3791 | static void l2cap_send_srejframe(struct l2cap_chan *chan, u16 tx_seq) |
3329 | { | 3792 | { |
3330 | struct srej_list *new; | 3793 | struct srej_list *new; |
3331 | u16 control; | 3794 | u32 control; |
3332 | 3795 | ||
3333 | while (tx_seq != chan->expected_tx_seq) { | 3796 | while (tx_seq != chan->expected_tx_seq) { |
3334 | control = L2CAP_SUPER_SELECT_REJECT; | 3797 | control = __set_ctrl_super(chan, L2CAP_SUPER_SREJ); |
3335 | control |= chan->expected_tx_seq << L2CAP_CTRL_REQSEQ_SHIFT; | 3798 | control |= __set_reqseq(chan, chan->expected_tx_seq); |
3336 | l2cap_send_sframe(chan, control); | 3799 | l2cap_send_sframe(chan, control); |
3337 | 3800 | ||
3338 | new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC); | 3801 | new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC); |
3339 | new->tx_seq = chan->expected_tx_seq; | 3802 | new->tx_seq = chan->expected_tx_seq; |
3340 | chan->expected_tx_seq = (chan->expected_tx_seq + 1) % 64; | 3803 | |
3804 | chan->expected_tx_seq = __next_seq(chan, chan->expected_tx_seq); | ||
3805 | |||
3341 | list_add_tail(&new->list, &chan->srej_l); | 3806 | list_add_tail(&new->list, &chan->srej_l); |
3342 | } | 3807 | } |
3343 | chan->expected_tx_seq = (chan->expected_tx_seq + 1) % 64; | 3808 | |
3809 | chan->expected_tx_seq = __next_seq(chan, chan->expected_tx_seq); | ||
3344 | } | 3810 | } |
3345 | 3811 | ||
3346 | static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_control, struct sk_buff *skb) | 3812 | static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u32 rx_control, struct sk_buff *skb) |
3347 | { | 3813 | { |
3348 | u8 tx_seq = __get_txseq(rx_control); | 3814 | u16 tx_seq = __get_txseq(chan, rx_control); |
3349 | u8 req_seq = __get_reqseq(rx_control); | 3815 | u16 req_seq = __get_reqseq(chan, rx_control); |
3350 | u8 sar = rx_control >> L2CAP_CTRL_SAR_SHIFT; | 3816 | u8 sar = __get_ctrl_sar(chan, rx_control); |
3351 | int tx_seq_offset, expected_tx_seq_offset; | 3817 | int tx_seq_offset, expected_tx_seq_offset; |
3352 | int num_to_ack = (chan->tx_win/6) + 1; | 3818 | int num_to_ack = (chan->tx_win/6) + 1; |
3353 | int err = 0; | 3819 | int err = 0; |
3354 | 3820 | ||
3355 | BT_DBG("chan %p len %d tx_seq %d rx_control 0x%4.4x", chan, skb->len, | 3821 | BT_DBG("chan %p len %d tx_seq %d rx_control 0x%8.8x", chan, skb->len, |
3356 | tx_seq, rx_control); | 3822 | tx_seq, rx_control); |
3357 | 3823 | ||
3358 | if (L2CAP_CTRL_FINAL & rx_control && | 3824 | if (__is_ctrl_final(chan, rx_control) && |
3359 | test_bit(CONN_WAIT_F, &chan->conn_state)) { | 3825 | test_bit(CONN_WAIT_F, &chan->conn_state)) { |
3360 | __clear_monitor_timer(chan); | 3826 | __clear_monitor_timer(chan); |
3361 | if (chan->unacked_frames > 0) | 3827 | if (chan->unacked_frames > 0) |
@@ -3366,9 +3832,7 @@ static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_cont | |||
3366 | chan->expected_ack_seq = req_seq; | 3832 | chan->expected_ack_seq = req_seq; |
3367 | l2cap_drop_acked_frames(chan); | 3833 | l2cap_drop_acked_frames(chan); |
3368 | 3834 | ||
3369 | tx_seq_offset = (tx_seq - chan->buffer_seq) % 64; | 3835 | tx_seq_offset = __seq_offset(chan, tx_seq, chan->buffer_seq); |
3370 | if (tx_seq_offset < 0) | ||
3371 | tx_seq_offset += 64; | ||
3372 | 3836 | ||
3373 | /* invalid tx_seq */ | 3837 | /* invalid tx_seq */ |
3374 | if (tx_seq_offset >= chan->tx_win) { | 3838 | if (tx_seq_offset >= chan->tx_win) { |
@@ -3416,10 +3880,8 @@ static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_cont | |||
3416 | l2cap_send_srejframe(chan, tx_seq); | 3880 | l2cap_send_srejframe(chan, tx_seq); |
3417 | } | 3881 | } |
3418 | } else { | 3882 | } else { |
3419 | expected_tx_seq_offset = | 3883 | expected_tx_seq_offset = __seq_offset(chan, |
3420 | (chan->expected_tx_seq - chan->buffer_seq) % 64; | 3884 | chan->expected_tx_seq, chan->buffer_seq); |
3421 | if (expected_tx_seq_offset < 0) | ||
3422 | expected_tx_seq_offset += 64; | ||
3423 | 3885 | ||
3424 | /* duplicated tx_seq */ | 3886 | /* duplicated tx_seq */ |
3425 | if (tx_seq_offset < expected_tx_seq_offset) | 3887 | if (tx_seq_offset < expected_tx_seq_offset) |
@@ -3444,7 +3906,7 @@ static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_cont | |||
3444 | return 0; | 3906 | return 0; |
3445 | 3907 | ||
3446 | expected: | 3908 | expected: |
3447 | chan->expected_tx_seq = (chan->expected_tx_seq + 1) % 64; | 3909 | chan->expected_tx_seq = __next_seq(chan, chan->expected_tx_seq); |
3448 | 3910 | ||
3449 | if (test_bit(CONN_SREJ_SENT, &chan->conn_state)) { | 3911 | if (test_bit(CONN_SREJ_SENT, &chan->conn_state)) { |
3450 | bt_cb(skb)->tx_seq = tx_seq; | 3912 | bt_cb(skb)->tx_seq = tx_seq; |
@@ -3454,13 +3916,14 @@ expected: | |||
3454 | } | 3916 | } |
3455 | 3917 | ||
3456 | err = l2cap_reassemble_sdu(chan, skb, rx_control); | 3918 | err = l2cap_reassemble_sdu(chan, skb, rx_control); |
3457 | chan->buffer_seq = (chan->buffer_seq + 1) % 64; | 3919 | chan->buffer_seq = __next_seq(chan, chan->buffer_seq); |
3920 | |||
3458 | if (err < 0) { | 3921 | if (err < 0) { |
3459 | l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); | 3922 | l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); |
3460 | return err; | 3923 | return err; |
3461 | } | 3924 | } |
3462 | 3925 | ||
3463 | if (rx_control & L2CAP_CTRL_FINAL) { | 3926 | if (__is_ctrl_final(chan, rx_control)) { |
3464 | if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state)) | 3927 | if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state)) |
3465 | l2cap_retransmit_frames(chan); | 3928 | l2cap_retransmit_frames(chan); |
3466 | } | 3929 | } |
@@ -3478,15 +3941,15 @@ drop: | |||
3478 | return 0; | 3941 | return 0; |
3479 | } | 3942 | } |
3480 | 3943 | ||
3481 | static inline void l2cap_data_channel_rrframe(struct l2cap_chan *chan, u16 rx_control) | 3944 | static inline void l2cap_data_channel_rrframe(struct l2cap_chan *chan, u32 rx_control) |
3482 | { | 3945 | { |
3483 | BT_DBG("chan %p, req_seq %d ctrl 0x%4.4x", chan, __get_reqseq(rx_control), | 3946 | BT_DBG("chan %p, req_seq %d ctrl 0x%8.8x", chan, |
3484 | rx_control); | 3947 | __get_reqseq(chan, rx_control), rx_control); |
3485 | 3948 | ||
3486 | chan->expected_ack_seq = __get_reqseq(rx_control); | 3949 | chan->expected_ack_seq = __get_reqseq(chan, rx_control); |
3487 | l2cap_drop_acked_frames(chan); | 3950 | l2cap_drop_acked_frames(chan); |
3488 | 3951 | ||
3489 | if (rx_control & L2CAP_CTRL_POLL) { | 3952 | if (__is_ctrl_poll(chan, rx_control)) { |
3490 | set_bit(CONN_SEND_FBIT, &chan->conn_state); | 3953 | set_bit(CONN_SEND_FBIT, &chan->conn_state); |
3491 | if (test_bit(CONN_SREJ_SENT, &chan->conn_state)) { | 3954 | if (test_bit(CONN_SREJ_SENT, &chan->conn_state)) { |
3492 | if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state) && | 3955 | if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state) && |
@@ -3499,7 +3962,7 @@ static inline void l2cap_data_channel_rrframe(struct l2cap_chan *chan, u16 rx_co | |||
3499 | l2cap_send_i_or_rr_or_rnr(chan); | 3962 | l2cap_send_i_or_rr_or_rnr(chan); |
3500 | } | 3963 | } |
3501 | 3964 | ||
3502 | } else if (rx_control & L2CAP_CTRL_FINAL) { | 3965 | } else if (__is_ctrl_final(chan, rx_control)) { |
3503 | clear_bit(CONN_REMOTE_BUSY, &chan->conn_state); | 3966 | clear_bit(CONN_REMOTE_BUSY, &chan->conn_state); |
3504 | 3967 | ||
3505 | if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state)) | 3968 | if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state)) |
@@ -3518,18 +3981,18 @@ static inline void l2cap_data_channel_rrframe(struct l2cap_chan *chan, u16 rx_co | |||
3518 | } | 3981 | } |
3519 | } | 3982 | } |
3520 | 3983 | ||
3521 | static inline void l2cap_data_channel_rejframe(struct l2cap_chan *chan, u16 rx_control) | 3984 | static inline void l2cap_data_channel_rejframe(struct l2cap_chan *chan, u32 rx_control) |
3522 | { | 3985 | { |
3523 | u8 tx_seq = __get_reqseq(rx_control); | 3986 | u16 tx_seq = __get_reqseq(chan, rx_control); |
3524 | 3987 | ||
3525 | BT_DBG("chan %p, req_seq %d ctrl 0x%4.4x", chan, tx_seq, rx_control); | 3988 | BT_DBG("chan %p, req_seq %d ctrl 0x%8.8x", chan, tx_seq, rx_control); |
3526 | 3989 | ||
3527 | clear_bit(CONN_REMOTE_BUSY, &chan->conn_state); | 3990 | clear_bit(CONN_REMOTE_BUSY, &chan->conn_state); |
3528 | 3991 | ||
3529 | chan->expected_ack_seq = tx_seq; | 3992 | chan->expected_ack_seq = tx_seq; |
3530 | l2cap_drop_acked_frames(chan); | 3993 | l2cap_drop_acked_frames(chan); |
3531 | 3994 | ||
3532 | if (rx_control & L2CAP_CTRL_FINAL) { | 3995 | if (__is_ctrl_final(chan, rx_control)) { |
3533 | if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state)) | 3996 | if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state)) |
3534 | l2cap_retransmit_frames(chan); | 3997 | l2cap_retransmit_frames(chan); |
3535 | } else { | 3998 | } else { |
@@ -3539,15 +4002,15 @@ static inline void l2cap_data_channel_rejframe(struct l2cap_chan *chan, u16 rx_c | |||
3539 | set_bit(CONN_REJ_ACT, &chan->conn_state); | 4002 | set_bit(CONN_REJ_ACT, &chan->conn_state); |
3540 | } | 4003 | } |
3541 | } | 4004 | } |
3542 | static inline void l2cap_data_channel_srejframe(struct l2cap_chan *chan, u16 rx_control) | 4005 | static inline void l2cap_data_channel_srejframe(struct l2cap_chan *chan, u32 rx_control) |
3543 | { | 4006 | { |
3544 | u8 tx_seq = __get_reqseq(rx_control); | 4007 | u16 tx_seq = __get_reqseq(chan, rx_control); |
3545 | 4008 | ||
3546 | BT_DBG("chan %p, req_seq %d ctrl 0x%4.4x", chan, tx_seq, rx_control); | 4009 | BT_DBG("chan %p, req_seq %d ctrl 0x%8.8x", chan, tx_seq, rx_control); |
3547 | 4010 | ||
3548 | clear_bit(CONN_REMOTE_BUSY, &chan->conn_state); | 4011 | clear_bit(CONN_REMOTE_BUSY, &chan->conn_state); |
3549 | 4012 | ||
3550 | if (rx_control & L2CAP_CTRL_POLL) { | 4013 | if (__is_ctrl_poll(chan, rx_control)) { |
3551 | chan->expected_ack_seq = tx_seq; | 4014 | chan->expected_ack_seq = tx_seq; |
3552 | l2cap_drop_acked_frames(chan); | 4015 | l2cap_drop_acked_frames(chan); |
3553 | 4016 | ||
@@ -3560,7 +4023,7 @@ static inline void l2cap_data_channel_srejframe(struct l2cap_chan *chan, u16 rx_ | |||
3560 | chan->srej_save_reqseq = tx_seq; | 4023 | chan->srej_save_reqseq = tx_seq; |
3561 | set_bit(CONN_SREJ_ACT, &chan->conn_state); | 4024 | set_bit(CONN_SREJ_ACT, &chan->conn_state); |
3562 | } | 4025 | } |
3563 | } else if (rx_control & L2CAP_CTRL_FINAL) { | 4026 | } else if (__is_ctrl_final(chan, rx_control)) { |
3564 | if (test_bit(CONN_SREJ_ACT, &chan->conn_state) && | 4027 | if (test_bit(CONN_SREJ_ACT, &chan->conn_state) && |
3565 | chan->srej_save_reqseq == tx_seq) | 4028 | chan->srej_save_reqseq == tx_seq) |
3566 | clear_bit(CONN_SREJ_ACT, &chan->conn_state); | 4029 | clear_bit(CONN_SREJ_ACT, &chan->conn_state); |
@@ -3575,37 +4038,39 @@ static inline void l2cap_data_channel_srejframe(struct l2cap_chan *chan, u16 rx_ | |||
3575 | } | 4038 | } |
3576 | } | 4039 | } |
3577 | 4040 | ||
3578 | static inline void l2cap_data_channel_rnrframe(struct l2cap_chan *chan, u16 rx_control) | 4041 | static inline void l2cap_data_channel_rnrframe(struct l2cap_chan *chan, u32 rx_control) |
3579 | { | 4042 | { |
3580 | u8 tx_seq = __get_reqseq(rx_control); | 4043 | u16 tx_seq = __get_reqseq(chan, rx_control); |
3581 | 4044 | ||
3582 | BT_DBG("chan %p, req_seq %d ctrl 0x%4.4x", chan, tx_seq, rx_control); | 4045 | BT_DBG("chan %p, req_seq %d ctrl 0x%8.8x", chan, tx_seq, rx_control); |
3583 | 4046 | ||
3584 | set_bit(CONN_REMOTE_BUSY, &chan->conn_state); | 4047 | set_bit(CONN_REMOTE_BUSY, &chan->conn_state); |
3585 | chan->expected_ack_seq = tx_seq; | 4048 | chan->expected_ack_seq = tx_seq; |
3586 | l2cap_drop_acked_frames(chan); | 4049 | l2cap_drop_acked_frames(chan); |
3587 | 4050 | ||
3588 | if (rx_control & L2CAP_CTRL_POLL) | 4051 | if (__is_ctrl_poll(chan, rx_control)) |
3589 | set_bit(CONN_SEND_FBIT, &chan->conn_state); | 4052 | set_bit(CONN_SEND_FBIT, &chan->conn_state); |
3590 | 4053 | ||
3591 | if (!test_bit(CONN_SREJ_SENT, &chan->conn_state)) { | 4054 | if (!test_bit(CONN_SREJ_SENT, &chan->conn_state)) { |
3592 | __clear_retrans_timer(chan); | 4055 | __clear_retrans_timer(chan); |
3593 | if (rx_control & L2CAP_CTRL_POLL) | 4056 | if (__is_ctrl_poll(chan, rx_control)) |
3594 | l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_FINAL); | 4057 | l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_FINAL); |
3595 | return; | 4058 | return; |
3596 | } | 4059 | } |
3597 | 4060 | ||
3598 | if (rx_control & L2CAP_CTRL_POLL) | 4061 | if (__is_ctrl_poll(chan, rx_control)) { |
3599 | l2cap_send_srejtail(chan); | 4062 | l2cap_send_srejtail(chan); |
3600 | else | 4063 | } else { |
3601 | l2cap_send_sframe(chan, L2CAP_SUPER_RCV_READY); | 4064 | rx_control = __set_ctrl_super(chan, L2CAP_SUPER_RR); |
4065 | l2cap_send_sframe(chan, rx_control); | ||
4066 | } | ||
3602 | } | 4067 | } |
3603 | 4068 | ||
3604 | static inline int l2cap_data_channel_sframe(struct l2cap_chan *chan, u16 rx_control, struct sk_buff *skb) | 4069 | static inline int l2cap_data_channel_sframe(struct l2cap_chan *chan, u32 rx_control, struct sk_buff *skb) |
3605 | { | 4070 | { |
3606 | BT_DBG("chan %p rx_control 0x%4.4x len %d", chan, rx_control, skb->len); | 4071 | BT_DBG("chan %p rx_control 0x%8.8x len %d", chan, rx_control, skb->len); |
3607 | 4072 | ||
3608 | if (L2CAP_CTRL_FINAL & rx_control && | 4073 | if (__is_ctrl_final(chan, rx_control) && |
3609 | test_bit(CONN_WAIT_F, &chan->conn_state)) { | 4074 | test_bit(CONN_WAIT_F, &chan->conn_state)) { |
3610 | __clear_monitor_timer(chan); | 4075 | __clear_monitor_timer(chan); |
3611 | if (chan->unacked_frames > 0) | 4076 | if (chan->unacked_frames > 0) |
@@ -3613,20 +4078,20 @@ static inline int l2cap_data_channel_sframe(struct l2cap_chan *chan, u16 rx_cont | |||
3613 | clear_bit(CONN_WAIT_F, &chan->conn_state); | 4078 | clear_bit(CONN_WAIT_F, &chan->conn_state); |
3614 | } | 4079 | } |
3615 | 4080 | ||
3616 | switch (rx_control & L2CAP_CTRL_SUPERVISE) { | 4081 | switch (__get_ctrl_super(chan, rx_control)) { |
3617 | case L2CAP_SUPER_RCV_READY: | 4082 | case L2CAP_SUPER_RR: |
3618 | l2cap_data_channel_rrframe(chan, rx_control); | 4083 | l2cap_data_channel_rrframe(chan, rx_control); |
3619 | break; | 4084 | break; |
3620 | 4085 | ||
3621 | case L2CAP_SUPER_REJECT: | 4086 | case L2CAP_SUPER_REJ: |
3622 | l2cap_data_channel_rejframe(chan, rx_control); | 4087 | l2cap_data_channel_rejframe(chan, rx_control); |
3623 | break; | 4088 | break; |
3624 | 4089 | ||
3625 | case L2CAP_SUPER_SELECT_REJECT: | 4090 | case L2CAP_SUPER_SREJ: |
3626 | l2cap_data_channel_srejframe(chan, rx_control); | 4091 | l2cap_data_channel_srejframe(chan, rx_control); |
3627 | break; | 4092 | break; |
3628 | 4093 | ||
3629 | case L2CAP_SUPER_RCV_NOT_READY: | 4094 | case L2CAP_SUPER_RNR: |
3630 | l2cap_data_channel_rnrframe(chan, rx_control); | 4095 | l2cap_data_channel_rnrframe(chan, rx_control); |
3631 | break; | 4096 | break; |
3632 | } | 4097 | } |
@@ -3638,12 +4103,12 @@ static inline int l2cap_data_channel_sframe(struct l2cap_chan *chan, u16 rx_cont | |||
3638 | static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb) | 4103 | static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb) |
3639 | { | 4104 | { |
3640 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; | 4105 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; |
3641 | u16 control; | 4106 | u32 control; |
3642 | u8 req_seq; | 4107 | u16 req_seq; |
3643 | int len, next_tx_seq_offset, req_seq_offset; | 4108 | int len, next_tx_seq_offset, req_seq_offset; |
3644 | 4109 | ||
3645 | control = get_unaligned_le16(skb->data); | 4110 | control = __get_control(chan, skb->data); |
3646 | skb_pull(skb, 2); | 4111 | skb_pull(skb, __ctrl_size(chan)); |
3647 | len = skb->len; | 4112 | len = skb->len; |
3648 | 4113 | ||
3649 | /* | 4114 | /* |
@@ -3654,26 +4119,23 @@ static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb) | |||
3654 | if (l2cap_check_fcs(chan, skb)) | 4119 | if (l2cap_check_fcs(chan, skb)) |
3655 | goto drop; | 4120 | goto drop; |
3656 | 4121 | ||
3657 | if (__is_sar_start(control) && __is_iframe(control)) | 4122 | if (__is_sar_start(chan, control) && !__is_sframe(chan, control)) |
3658 | len -= 2; | 4123 | len -= L2CAP_SDULEN_SIZE; |
3659 | 4124 | ||
3660 | if (chan->fcs == L2CAP_FCS_CRC16) | 4125 | if (chan->fcs == L2CAP_FCS_CRC16) |
3661 | len -= 2; | 4126 | len -= L2CAP_FCS_SIZE; |
3662 | 4127 | ||
3663 | if (len > chan->mps) { | 4128 | if (len > chan->mps) { |
3664 | l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); | 4129 | l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); |
3665 | goto drop; | 4130 | goto drop; |
3666 | } | 4131 | } |
3667 | 4132 | ||
3668 | req_seq = __get_reqseq(control); | 4133 | req_seq = __get_reqseq(chan, control); |
3669 | req_seq_offset = (req_seq - chan->expected_ack_seq) % 64; | ||
3670 | if (req_seq_offset < 0) | ||
3671 | req_seq_offset += 64; | ||
3672 | 4134 | ||
3673 | next_tx_seq_offset = | 4135 | req_seq_offset = __seq_offset(chan, req_seq, chan->expected_ack_seq); |
3674 | (chan->next_tx_seq - chan->expected_ack_seq) % 64; | 4136 | |
3675 | if (next_tx_seq_offset < 0) | 4137 | next_tx_seq_offset = __seq_offset(chan, chan->next_tx_seq, |
3676 | next_tx_seq_offset += 64; | 4138 | chan->expected_ack_seq); |
3677 | 4139 | ||
3678 | /* check for invalid req-seq */ | 4140 | /* check for invalid req-seq */ |
3679 | if (req_seq_offset > next_tx_seq_offset) { | 4141 | if (req_seq_offset > next_tx_seq_offset) { |
@@ -3681,7 +4143,7 @@ static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb) | |||
3681 | goto drop; | 4143 | goto drop; |
3682 | } | 4144 | } |
3683 | 4145 | ||
3684 | if (__is_iframe(control)) { | 4146 | if (!__is_sframe(chan, control)) { |
3685 | if (len < 0) { | 4147 | if (len < 0) { |
3686 | l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); | 4148 | l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); |
3687 | goto drop; | 4149 | goto drop; |
@@ -3709,8 +4171,8 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk | |||
3709 | { | 4171 | { |
3710 | struct l2cap_chan *chan; | 4172 | struct l2cap_chan *chan; |
3711 | struct sock *sk = NULL; | 4173 | struct sock *sk = NULL; |
3712 | u16 control; | 4174 | u32 control; |
3713 | u8 tx_seq; | 4175 | u16 tx_seq; |
3714 | int len; | 4176 | int len; |
3715 | 4177 | ||
3716 | chan = l2cap_get_chan_by_scid(conn, cid); | 4178 | chan = l2cap_get_chan_by_scid(conn, cid); |
@@ -3751,23 +4213,23 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk | |||
3751 | goto done; | 4213 | goto done; |
3752 | 4214 | ||
3753 | case L2CAP_MODE_STREAMING: | 4215 | case L2CAP_MODE_STREAMING: |
3754 | control = get_unaligned_le16(skb->data); | 4216 | control = __get_control(chan, skb->data); |
3755 | skb_pull(skb, 2); | 4217 | skb_pull(skb, __ctrl_size(chan)); |
3756 | len = skb->len; | 4218 | len = skb->len; |
3757 | 4219 | ||
3758 | if (l2cap_check_fcs(chan, skb)) | 4220 | if (l2cap_check_fcs(chan, skb)) |
3759 | goto drop; | 4221 | goto drop; |
3760 | 4222 | ||
3761 | if (__is_sar_start(control)) | 4223 | if (__is_sar_start(chan, control)) |
3762 | len -= 2; | 4224 | len -= L2CAP_SDULEN_SIZE; |
3763 | 4225 | ||
3764 | if (chan->fcs == L2CAP_FCS_CRC16) | 4226 | if (chan->fcs == L2CAP_FCS_CRC16) |
3765 | len -= 2; | 4227 | len -= L2CAP_FCS_SIZE; |
3766 | 4228 | ||
3767 | if (len > chan->mps || len < 0 || __is_sframe(control)) | 4229 | if (len > chan->mps || len < 0 || __is_sframe(chan, control)) |
3768 | goto drop; | 4230 | goto drop; |
3769 | 4231 | ||
3770 | tx_seq = __get_txseq(control); | 4232 | tx_seq = __get_txseq(chan, control); |
3771 | 4233 | ||
3772 | if (chan->expected_tx_seq != tx_seq) { | 4234 | if (chan->expected_tx_seq != tx_seq) { |
3773 | /* Frame(s) missing - must discard partial SDU */ | 4235 | /* Frame(s) missing - must discard partial SDU */ |
@@ -3779,7 +4241,7 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk | |||
3779 | /* TODO: Notify userland of missing data */ | 4241 | /* TODO: Notify userland of missing data */ |
3780 | } | 4242 | } |
3781 | 4243 | ||
3782 | chan->expected_tx_seq = (tx_seq + 1) % 64; | 4244 | chan->expected_tx_seq = __next_seq(chan, tx_seq); |
3783 | 4245 | ||
3784 | if (l2cap_reassemble_sdu(chan, skb, control) == -EMSGSIZE) | 4246 | if (l2cap_reassemble_sdu(chan, skb, control) == -EMSGSIZE) |
3785 | l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); | 4247 | l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); |
@@ -3933,12 +4395,12 @@ static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) | |||
3933 | 4395 | ||
3934 | if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) { | 4396 | if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) { |
3935 | lm1 |= HCI_LM_ACCEPT; | 4397 | lm1 |= HCI_LM_ACCEPT; |
3936 | if (c->role_switch) | 4398 | if (test_bit(FLAG_ROLE_SWITCH, &c->flags)) |
3937 | lm1 |= HCI_LM_MASTER; | 4399 | lm1 |= HCI_LM_MASTER; |
3938 | exact++; | 4400 | exact++; |
3939 | } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) { | 4401 | } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) { |
3940 | lm2 |= HCI_LM_ACCEPT; | 4402 | lm2 |= HCI_LM_ACCEPT; |
3941 | if (c->role_switch) | 4403 | if (test_bit(FLAG_ROLE_SWITCH, &c->flags)) |
3942 | lm2 |= HCI_LM_MASTER; | 4404 | lm2 |= HCI_LM_MASTER; |
3943 | } | 4405 | } |
3944 | } | 4406 | } |
@@ -3973,7 +4435,7 @@ static int l2cap_disconn_ind(struct hci_conn *hcon) | |||
3973 | BT_DBG("hcon %p", hcon); | 4435 | BT_DBG("hcon %p", hcon); |
3974 | 4436 | ||
3975 | if ((hcon->type != ACL_LINK && hcon->type != LE_LINK) || !conn) | 4437 | if ((hcon->type != ACL_LINK && hcon->type != LE_LINK) || !conn) |
3976 | return 0x13; | 4438 | return HCI_ERROR_REMOTE_USER_TERM; |
3977 | 4439 | ||
3978 | return conn->disc_reason; | 4440 | return conn->disc_reason; |
3979 | } | 4441 | } |
@@ -3998,7 +4460,7 @@ static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt) | |||
3998 | if (encrypt == 0x00) { | 4460 | if (encrypt == 0x00) { |
3999 | if (chan->sec_level == BT_SECURITY_MEDIUM) { | 4461 | if (chan->sec_level == BT_SECURITY_MEDIUM) { |
4000 | __clear_chan_timer(chan); | 4462 | __clear_chan_timer(chan); |
4001 | __set_chan_timer(chan, HZ * 5); | 4463 | __set_chan_timer(chan, L2CAP_ENC_TIMEOUT); |
4002 | } else if (chan->sec_level == BT_SECURITY_HIGH) | 4464 | } else if (chan->sec_level == BT_SECURITY_HIGH) |
4003 | l2cap_chan_close(chan, ECONNREFUSED); | 4465 | l2cap_chan_close(chan, ECONNREFUSED); |
4004 | } else { | 4466 | } else { |
@@ -4066,7 +4528,7 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) | |||
4066 | L2CAP_CONN_REQ, sizeof(req), &req); | 4528 | L2CAP_CONN_REQ, sizeof(req), &req); |
4067 | } else { | 4529 | } else { |
4068 | __clear_chan_timer(chan); | 4530 | __clear_chan_timer(chan); |
4069 | __set_chan_timer(chan, HZ / 10); | 4531 | __set_chan_timer(chan, L2CAP_DISC_TIMEOUT); |
4070 | } | 4532 | } |
4071 | } else if (chan->state == BT_CONNECT2) { | 4533 | } else if (chan->state == BT_CONNECT2) { |
4072 | struct l2cap_conn_rsp rsp; | 4534 | struct l2cap_conn_rsp rsp; |
@@ -4086,7 +4548,7 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) | |||
4086 | } | 4548 | } |
4087 | } else { | 4549 | } else { |
4088 | l2cap_state_change(chan, BT_DISCONN); | 4550 | l2cap_state_change(chan, BT_DISCONN); |
4089 | __set_chan_timer(chan, HZ / 10); | 4551 | __set_chan_timer(chan, L2CAP_DISC_TIMEOUT); |
4090 | res = L2CAP_CR_SEC_BLOCK; | 4552 | res = L2CAP_CR_SEC_BLOCK; |
4091 | stat = L2CAP_CS_NO_INFO; | 4553 | stat = L2CAP_CS_NO_INFO; |
4092 | } | 4554 | } |
@@ -4306,3 +4768,6 @@ void l2cap_exit(void) | |||
4306 | 4768 | ||
4307 | module_param(disable_ertm, bool, 0644); | 4769 | module_param(disable_ertm, bool, 0644); |
4308 | MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode"); | 4770 | MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode"); |
4771 | |||
4772 | module_param(enable_hs, bool, 0644); | ||
4773 | MODULE_PARM_DESC(enable_hs, "Enable High Speed"); | ||
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 5c406d3136f7..e2e785c74630 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c | |||
@@ -334,7 +334,7 @@ static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __us | |||
334 | opts.mode = chan->mode; | 334 | opts.mode = chan->mode; |
335 | opts.fcs = chan->fcs; | 335 | opts.fcs = chan->fcs; |
336 | opts.max_tx = chan->max_tx; | 336 | opts.max_tx = chan->max_tx; |
337 | opts.txwin_size = (__u16)chan->tx_win; | 337 | opts.txwin_size = chan->tx_win; |
338 | 338 | ||
339 | len = min_t(unsigned int, len, sizeof(opts)); | 339 | len = min_t(unsigned int, len, sizeof(opts)); |
340 | if (copy_to_user(optval, (char *) &opts, len)) | 340 | if (copy_to_user(optval, (char *) &opts, len)) |
@@ -359,10 +359,10 @@ static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __us | |||
359 | break; | 359 | break; |
360 | } | 360 | } |
361 | 361 | ||
362 | if (chan->role_switch) | 362 | if (test_bit(FLAG_ROLE_SWITCH, &chan->flags)) |
363 | opt |= L2CAP_LM_MASTER; | 363 | opt |= L2CAP_LM_MASTER; |
364 | 364 | ||
365 | if (chan->force_reliable) | 365 | if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags)) |
366 | opt |= L2CAP_LM_RELIABLE; | 366 | opt |= L2CAP_LM_RELIABLE; |
367 | 367 | ||
368 | if (put_user(opt, (u32 __user *) optval)) | 368 | if (put_user(opt, (u32 __user *) optval)) |
@@ -449,7 +449,8 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, ch | |||
449 | break; | 449 | break; |
450 | 450 | ||
451 | case BT_FLUSHABLE: | 451 | case BT_FLUSHABLE: |
452 | if (put_user(chan->flushable, (u32 __user *) optval)) | 452 | if (put_user(test_bit(FLAG_FLUSHABLE, &chan->flags), |
453 | (u32 __user *) optval)) | ||
453 | err = -EFAULT; | 454 | err = -EFAULT; |
454 | 455 | ||
455 | break; | 456 | break; |
@@ -461,7 +462,7 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, ch | |||
461 | break; | 462 | break; |
462 | } | 463 | } |
463 | 464 | ||
464 | pwr.force_active = chan->force_active; | 465 | pwr.force_active = test_bit(FLAG_FORCE_ACTIVE, &chan->flags); |
465 | 466 | ||
466 | len = min_t(unsigned int, len, sizeof(pwr)); | 467 | len = min_t(unsigned int, len, sizeof(pwr)); |
467 | if (copy_to_user(optval, (char *) &pwr, len)) | 468 | if (copy_to_user(optval, (char *) &pwr, len)) |
@@ -469,6 +470,16 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, ch | |||
469 | 470 | ||
470 | break; | 471 | break; |
471 | 472 | ||
473 | case BT_CHANNEL_POLICY: | ||
474 | if (!enable_hs) { | ||
475 | err = -ENOPROTOOPT; | ||
476 | break; | ||
477 | } | ||
478 | |||
479 | if (put_user(chan->chan_policy, (u32 __user *) optval)) | ||
480 | err = -EFAULT; | ||
481 | break; | ||
482 | |||
472 | default: | 483 | default: |
473 | err = -ENOPROTOOPT; | 484 | err = -ENOPROTOOPT; |
474 | break; | 485 | break; |
@@ -503,7 +514,7 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us | |||
503 | opts.mode = chan->mode; | 514 | opts.mode = chan->mode; |
504 | opts.fcs = chan->fcs; | 515 | opts.fcs = chan->fcs; |
505 | opts.max_tx = chan->max_tx; | 516 | opts.max_tx = chan->max_tx; |
506 | opts.txwin_size = (__u16)chan->tx_win; | 517 | opts.txwin_size = chan->tx_win; |
507 | 518 | ||
508 | len = min_t(unsigned int, sizeof(opts), optlen); | 519 | len = min_t(unsigned int, sizeof(opts), optlen); |
509 | if (copy_from_user((char *) &opts, optval, len)) { | 520 | if (copy_from_user((char *) &opts, optval, len)) { |
@@ -511,7 +522,7 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us | |||
511 | break; | 522 | break; |
512 | } | 523 | } |
513 | 524 | ||
514 | if (opts.txwin_size > L2CAP_DEFAULT_TX_WINDOW) { | 525 | if (opts.txwin_size > L2CAP_DEFAULT_EXT_WINDOW) { |
515 | err = -EINVAL; | 526 | err = -EINVAL; |
516 | break; | 527 | break; |
517 | } | 528 | } |
@@ -535,7 +546,7 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us | |||
535 | chan->omtu = opts.omtu; | 546 | chan->omtu = opts.omtu; |
536 | chan->fcs = opts.fcs; | 547 | chan->fcs = opts.fcs; |
537 | chan->max_tx = opts.max_tx; | 548 | chan->max_tx = opts.max_tx; |
538 | chan->tx_win = (__u8)opts.txwin_size; | 549 | chan->tx_win = opts.txwin_size; |
539 | break; | 550 | break; |
540 | 551 | ||
541 | case L2CAP_LM: | 552 | case L2CAP_LM: |
@@ -551,8 +562,15 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us | |||
551 | if (opt & L2CAP_LM_SECURE) | 562 | if (opt & L2CAP_LM_SECURE) |
552 | chan->sec_level = BT_SECURITY_HIGH; | 563 | chan->sec_level = BT_SECURITY_HIGH; |
553 | 564 | ||
554 | chan->role_switch = (opt & L2CAP_LM_MASTER); | 565 | if (opt & L2CAP_LM_MASTER) |
555 | chan->force_reliable = (opt & L2CAP_LM_RELIABLE); | 566 | set_bit(FLAG_ROLE_SWITCH, &chan->flags); |
567 | else | ||
568 | clear_bit(FLAG_ROLE_SWITCH, &chan->flags); | ||
569 | |||
570 | if (opt & L2CAP_LM_RELIABLE) | ||
571 | set_bit(FLAG_FORCE_RELIABLE, &chan->flags); | ||
572 | else | ||
573 | clear_bit(FLAG_FORCE_RELIABLE, &chan->flags); | ||
556 | break; | 574 | break; |
557 | 575 | ||
558 | default: | 576 | default: |
@@ -658,7 +676,10 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch | |||
658 | } | 676 | } |
659 | } | 677 | } |
660 | 678 | ||
661 | chan->flushable = opt; | 679 | if (opt) |
680 | set_bit(FLAG_FLUSHABLE, &chan->flags); | ||
681 | else | ||
682 | clear_bit(FLAG_FLUSHABLE, &chan->flags); | ||
662 | break; | 683 | break; |
663 | 684 | ||
664 | case BT_POWER: | 685 | case BT_POWER: |
@@ -675,7 +696,36 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch | |||
675 | err = -EFAULT; | 696 | err = -EFAULT; |
676 | break; | 697 | break; |
677 | } | 698 | } |
678 | chan->force_active = pwr.force_active; | 699 | |
700 | if (pwr.force_active) | ||
701 | set_bit(FLAG_FORCE_ACTIVE, &chan->flags); | ||
702 | else | ||
703 | clear_bit(FLAG_FORCE_ACTIVE, &chan->flags); | ||
704 | break; | ||
705 | |||
706 | case BT_CHANNEL_POLICY: | ||
707 | if (!enable_hs) { | ||
708 | err = -ENOPROTOOPT; | ||
709 | break; | ||
710 | } | ||
711 | |||
712 | if (get_user(opt, (u32 __user *) optval)) { | ||
713 | err = -EFAULT; | ||
714 | break; | ||
715 | } | ||
716 | |||
717 | if (opt > BT_CHANNEL_POLICY_AMP_PREFERRED) { | ||
718 | err = -EINVAL; | ||
719 | break; | ||
720 | } | ||
721 | |||
722 | if (chan->mode != L2CAP_MODE_ERTM && | ||
723 | chan->mode != L2CAP_MODE_STREAMING) { | ||
724 | err = -EOPNOTSUPP; | ||
725 | break; | ||
726 | } | ||
727 | |||
728 | chan->chan_policy = (u8) opt; | ||
679 | break; | 729 | break; |
680 | 730 | ||
681 | default: | 731 | default: |
@@ -709,7 +759,7 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms | |||
709 | return -ENOTCONN; | 759 | return -ENOTCONN; |
710 | } | 760 | } |
711 | 761 | ||
712 | err = l2cap_chan_send(chan, msg, len); | 762 | err = l2cap_chan_send(chan, msg, len, sk->sk_priority); |
713 | 763 | ||
714 | release_sock(sk); | 764 | release_sock(sk); |
715 | return err; | 765 | return err; |
@@ -931,11 +981,9 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent) | |||
931 | chan->fcs = pchan->fcs; | 981 | chan->fcs = pchan->fcs; |
932 | chan->max_tx = pchan->max_tx; | 982 | chan->max_tx = pchan->max_tx; |
933 | chan->tx_win = pchan->tx_win; | 983 | chan->tx_win = pchan->tx_win; |
984 | chan->tx_win_max = pchan->tx_win_max; | ||
934 | chan->sec_level = pchan->sec_level; | 985 | chan->sec_level = pchan->sec_level; |
935 | chan->role_switch = pchan->role_switch; | 986 | chan->flags = pchan->flags; |
936 | chan->force_reliable = pchan->force_reliable; | ||
937 | chan->flushable = pchan->flushable; | ||
938 | chan->force_active = pchan->force_active; | ||
939 | 987 | ||
940 | security_sk_clone(parent, sk); | 988 | security_sk_clone(parent, sk); |
941 | } else { | 989 | } else { |
@@ -964,12 +1012,10 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent) | |||
964 | chan->max_tx = L2CAP_DEFAULT_MAX_TX; | 1012 | chan->max_tx = L2CAP_DEFAULT_MAX_TX; |
965 | chan->fcs = L2CAP_FCS_CRC16; | 1013 | chan->fcs = L2CAP_FCS_CRC16; |
966 | chan->tx_win = L2CAP_DEFAULT_TX_WINDOW; | 1014 | chan->tx_win = L2CAP_DEFAULT_TX_WINDOW; |
1015 | chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW; | ||
967 | chan->sec_level = BT_SECURITY_LOW; | 1016 | chan->sec_level = BT_SECURITY_LOW; |
968 | chan->role_switch = 0; | 1017 | chan->flags = 0; |
969 | chan->force_reliable = 0; | 1018 | set_bit(FLAG_FORCE_ACTIVE, &chan->flags); |
970 | chan->flushable = BT_FLUSHABLE_OFF; | ||
971 | chan->force_active = BT_POWER_FORCE_ACTIVE_ON; | ||
972 | |||
973 | } | 1019 | } |
974 | 1020 | ||
975 | /* Default config options */ | 1021 | /* Default config options */ |
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 2c7634296866..94739d3c4f59 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c | |||
@@ -33,22 +33,23 @@ | |||
33 | #define MGMT_VERSION 0 | 33 | #define MGMT_VERSION 0 |
34 | #define MGMT_REVISION 1 | 34 | #define MGMT_REVISION 1 |
35 | 35 | ||
36 | #define INQUIRY_LEN_BREDR 0x08 /* TGAP(100) */ | ||
37 | |||
36 | struct pending_cmd { | 38 | struct pending_cmd { |
37 | struct list_head list; | 39 | struct list_head list; |
38 | __u16 opcode; | 40 | u16 opcode; |
39 | int index; | 41 | int index; |
40 | void *param; | 42 | void *param; |
41 | struct sock *sk; | 43 | struct sock *sk; |
42 | void *user_data; | 44 | void *user_data; |
43 | }; | 45 | }; |
44 | 46 | ||
45 | static LIST_HEAD(cmd_list); | ||
46 | |||
47 | static int cmd_status(struct sock *sk, u16 index, u16 cmd, u8 status) | 47 | static int cmd_status(struct sock *sk, u16 index, u16 cmd, u8 status) |
48 | { | 48 | { |
49 | struct sk_buff *skb; | 49 | struct sk_buff *skb; |
50 | struct mgmt_hdr *hdr; | 50 | struct mgmt_hdr *hdr; |
51 | struct mgmt_ev_cmd_status *ev; | 51 | struct mgmt_ev_cmd_status *ev; |
52 | int err; | ||
52 | 53 | ||
53 | BT_DBG("sock %p, index %u, cmd %u, status %u", sk, index, cmd, status); | 54 | BT_DBG("sock %p, index %u, cmd %u, status %u", sk, index, cmd, status); |
54 | 55 | ||
@@ -66,10 +67,11 @@ static int cmd_status(struct sock *sk, u16 index, u16 cmd, u8 status) | |||
66 | ev->status = status; | 67 | ev->status = status; |
67 | put_unaligned_le16(cmd, &ev->opcode); | 68 | put_unaligned_le16(cmd, &ev->opcode); |
68 | 69 | ||
69 | if (sock_queue_rcv_skb(sk, skb) < 0) | 70 | err = sock_queue_rcv_skb(sk, skb); |
71 | if (err < 0) | ||
70 | kfree_skb(skb); | 72 | kfree_skb(skb); |
71 | 73 | ||
72 | return 0; | 74 | return err; |
73 | } | 75 | } |
74 | 76 | ||
75 | static int cmd_complete(struct sock *sk, u16 index, u16 cmd, void *rp, | 77 | static int cmd_complete(struct sock *sk, u16 index, u16 cmd, void *rp, |
@@ -78,6 +80,7 @@ static int cmd_complete(struct sock *sk, u16 index, u16 cmd, void *rp, | |||
78 | struct sk_buff *skb; | 80 | struct sk_buff *skb; |
79 | struct mgmt_hdr *hdr; | 81 | struct mgmt_hdr *hdr; |
80 | struct mgmt_ev_cmd_complete *ev; | 82 | struct mgmt_ev_cmd_complete *ev; |
83 | int err; | ||
81 | 84 | ||
82 | BT_DBG("sock %p", sk); | 85 | BT_DBG("sock %p", sk); |
83 | 86 | ||
@@ -97,10 +100,11 @@ static int cmd_complete(struct sock *sk, u16 index, u16 cmd, void *rp, | |||
97 | if (rp) | 100 | if (rp) |
98 | memcpy(ev->data, rp, rp_len); | 101 | memcpy(ev->data, rp, rp_len); |
99 | 102 | ||
100 | if (sock_queue_rcv_skb(sk, skb) < 0) | 103 | err = sock_queue_rcv_skb(sk, skb); |
104 | if (err < 0) | ||
101 | kfree_skb(skb); | 105 | kfree_skb(skb); |
102 | 106 | ||
103 | return 0; | 107 | return err;; |
104 | } | 108 | } |
105 | 109 | ||
106 | static int read_version(struct sock *sk) | 110 | static int read_version(struct sock *sk) |
@@ -120,6 +124,7 @@ static int read_index_list(struct sock *sk) | |||
120 | { | 124 | { |
121 | struct mgmt_rp_read_index_list *rp; | 125 | struct mgmt_rp_read_index_list *rp; |
122 | struct list_head *p; | 126 | struct list_head *p; |
127 | struct hci_dev *d; | ||
123 | size_t rp_len; | 128 | size_t rp_len; |
124 | u16 count; | 129 | u16 count; |
125 | int i, err; | 130 | int i, err; |
@@ -143,10 +148,9 @@ static int read_index_list(struct sock *sk) | |||
143 | put_unaligned_le16(count, &rp->num_controllers); | 148 | put_unaligned_le16(count, &rp->num_controllers); |
144 | 149 | ||
145 | i = 0; | 150 | i = 0; |
146 | list_for_each(p, &hci_dev_list) { | 151 | list_for_each_entry(d, &hci_dev_list, list) { |
147 | struct hci_dev *d = list_entry(p, struct hci_dev, list); | 152 | if (test_and_clear_bit(HCI_AUTO_OFF, &d->flags)) |
148 | 153 | cancel_delayed_work(&d->power_off); | |
149 | hci_del_off_timer(d); | ||
150 | 154 | ||
151 | if (test_bit(HCI_SETUP, &d->flags)) | 155 | if (test_bit(HCI_SETUP, &d->flags)) |
152 | continue; | 156 | continue; |
@@ -176,7 +180,8 @@ static int read_controller_info(struct sock *sk, u16 index) | |||
176 | if (!hdev) | 180 | if (!hdev) |
177 | return cmd_status(sk, index, MGMT_OP_READ_INFO, ENODEV); | 181 | return cmd_status(sk, index, MGMT_OP_READ_INFO, ENODEV); |
178 | 182 | ||
179 | hci_del_off_timer(hdev); | 183 | if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->flags)) |
184 | cancel_delayed_work_sync(&hdev->power_off); | ||
180 | 185 | ||
181 | hci_dev_lock_bh(hdev); | 186 | hci_dev_lock_bh(hdev); |
182 | 187 | ||
@@ -221,7 +226,8 @@ static void mgmt_pending_free(struct pending_cmd *cmd) | |||
221 | } | 226 | } |
222 | 227 | ||
223 | static struct pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode, | 228 | static struct pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode, |
224 | u16 index, void *data, u16 len) | 229 | struct hci_dev *hdev, |
230 | void *data, u16 len) | ||
225 | { | 231 | { |
226 | struct pending_cmd *cmd; | 232 | struct pending_cmd *cmd; |
227 | 233 | ||
@@ -230,7 +236,7 @@ static struct pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode, | |||
230 | return NULL; | 236 | return NULL; |
231 | 237 | ||
232 | cmd->opcode = opcode; | 238 | cmd->opcode = opcode; |
233 | cmd->index = index; | 239 | cmd->index = hdev->id; |
234 | 240 | ||
235 | cmd->param = kmalloc(len, GFP_ATOMIC); | 241 | cmd->param = kmalloc(len, GFP_ATOMIC); |
236 | if (!cmd->param) { | 242 | if (!cmd->param) { |
@@ -244,48 +250,36 @@ static struct pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode, | |||
244 | cmd->sk = sk; | 250 | cmd->sk = sk; |
245 | sock_hold(sk); | 251 | sock_hold(sk); |
246 | 252 | ||
247 | list_add(&cmd->list, &cmd_list); | 253 | list_add(&cmd->list, &hdev->mgmt_pending); |
248 | 254 | ||
249 | return cmd; | 255 | return cmd; |
250 | } | 256 | } |
251 | 257 | ||
252 | static void mgmt_pending_foreach(u16 opcode, int index, | 258 | static void mgmt_pending_foreach(u16 opcode, struct hci_dev *hdev, |
253 | void (*cb)(struct pending_cmd *cmd, void *data), | 259 | void (*cb)(struct pending_cmd *cmd, void *data), |
254 | void *data) | 260 | void *data) |
255 | { | 261 | { |
256 | struct list_head *p, *n; | 262 | struct list_head *p, *n; |
257 | 263 | ||
258 | list_for_each_safe(p, n, &cmd_list) { | 264 | list_for_each_safe(p, n, &hdev->mgmt_pending) { |
259 | struct pending_cmd *cmd; | 265 | struct pending_cmd *cmd; |
260 | 266 | ||
261 | cmd = list_entry(p, struct pending_cmd, list); | 267 | cmd = list_entry(p, struct pending_cmd, list); |
262 | 268 | ||
263 | if (cmd->opcode != opcode) | 269 | if (opcode > 0 && cmd->opcode != opcode) |
264 | continue; | ||
265 | |||
266 | if (index >= 0 && cmd->index != index) | ||
267 | continue; | 270 | continue; |
268 | 271 | ||
269 | cb(cmd, data); | 272 | cb(cmd, data); |
270 | } | 273 | } |
271 | } | 274 | } |
272 | 275 | ||
273 | static struct pending_cmd *mgmt_pending_find(u16 opcode, int index) | 276 | static struct pending_cmd *mgmt_pending_find(u16 opcode, struct hci_dev *hdev) |
274 | { | 277 | { |
275 | struct list_head *p; | 278 | struct pending_cmd *cmd; |
276 | |||
277 | list_for_each(p, &cmd_list) { | ||
278 | struct pending_cmd *cmd; | ||
279 | |||
280 | cmd = list_entry(p, struct pending_cmd, list); | ||
281 | |||
282 | if (cmd->opcode != opcode) | ||
283 | continue; | ||
284 | |||
285 | if (index >= 0 && cmd->index != index) | ||
286 | continue; | ||
287 | 279 | ||
288 | return cmd; | 280 | list_for_each_entry(cmd, &hdev->mgmt_pending, list) { |
281 | if (cmd->opcode == opcode) | ||
282 | return cmd; | ||
289 | } | 283 | } |
290 | 284 | ||
291 | return NULL; | 285 | return NULL; |
@@ -323,12 +317,12 @@ static int set_powered(struct sock *sk, u16 index, unsigned char *data, u16 len) | |||
323 | goto failed; | 317 | goto failed; |
324 | } | 318 | } |
325 | 319 | ||
326 | if (mgmt_pending_find(MGMT_OP_SET_POWERED, index)) { | 320 | if (mgmt_pending_find(MGMT_OP_SET_POWERED, hdev)) { |
327 | err = cmd_status(sk, index, MGMT_OP_SET_POWERED, EBUSY); | 321 | err = cmd_status(sk, index, MGMT_OP_SET_POWERED, EBUSY); |
328 | goto failed; | 322 | goto failed; |
329 | } | 323 | } |
330 | 324 | ||
331 | cmd = mgmt_pending_add(sk, MGMT_OP_SET_POWERED, index, data, len); | 325 | cmd = mgmt_pending_add(sk, MGMT_OP_SET_POWERED, hdev, data, len); |
332 | if (!cmd) { | 326 | if (!cmd) { |
333 | err = -ENOMEM; | 327 | err = -ENOMEM; |
334 | goto failed; | 328 | goto failed; |
@@ -337,7 +331,7 @@ static int set_powered(struct sock *sk, u16 index, unsigned char *data, u16 len) | |||
337 | if (cp->val) | 331 | if (cp->val) |
338 | queue_work(hdev->workqueue, &hdev->power_on); | 332 | queue_work(hdev->workqueue, &hdev->power_on); |
339 | else | 333 | else |
340 | queue_work(hdev->workqueue, &hdev->power_off); | 334 | queue_work(hdev->workqueue, &hdev->power_off.work); |
341 | 335 | ||
342 | err = 0; | 336 | err = 0; |
343 | 337 | ||
@@ -350,7 +344,7 @@ failed: | |||
350 | static int set_discoverable(struct sock *sk, u16 index, unsigned char *data, | 344 | static int set_discoverable(struct sock *sk, u16 index, unsigned char *data, |
351 | u16 len) | 345 | u16 len) |
352 | { | 346 | { |
353 | struct mgmt_mode *cp; | 347 | struct mgmt_cp_set_discoverable *cp; |
354 | struct hci_dev *hdev; | 348 | struct hci_dev *hdev; |
355 | struct pending_cmd *cmd; | 349 | struct pending_cmd *cmd; |
356 | u8 scan; | 350 | u8 scan; |
@@ -374,8 +368,8 @@ static int set_discoverable(struct sock *sk, u16 index, unsigned char *data, | |||
374 | goto failed; | 368 | goto failed; |
375 | } | 369 | } |
376 | 370 | ||
377 | if (mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, index) || | 371 | if (mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, hdev) || |
378 | mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, index)) { | 372 | mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, hdev)) { |
379 | err = cmd_status(sk, index, MGMT_OP_SET_DISCOVERABLE, EBUSY); | 373 | err = cmd_status(sk, index, MGMT_OP_SET_DISCOVERABLE, EBUSY); |
380 | goto failed; | 374 | goto failed; |
381 | } | 375 | } |
@@ -386,7 +380,7 @@ static int set_discoverable(struct sock *sk, u16 index, unsigned char *data, | |||
386 | goto failed; | 380 | goto failed; |
387 | } | 381 | } |
388 | 382 | ||
389 | cmd = mgmt_pending_add(sk, MGMT_OP_SET_DISCOVERABLE, index, data, len); | 383 | cmd = mgmt_pending_add(sk, MGMT_OP_SET_DISCOVERABLE, hdev, data, len); |
390 | if (!cmd) { | 384 | if (!cmd) { |
391 | err = -ENOMEM; | 385 | err = -ENOMEM; |
392 | goto failed; | 386 | goto failed; |
@@ -396,11 +390,16 @@ static int set_discoverable(struct sock *sk, u16 index, unsigned char *data, | |||
396 | 390 | ||
397 | if (cp->val) | 391 | if (cp->val) |
398 | scan |= SCAN_INQUIRY; | 392 | scan |= SCAN_INQUIRY; |
393 | else | ||
394 | cancel_delayed_work(&hdev->discov_off); | ||
399 | 395 | ||
400 | err = hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); | 396 | err = hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); |
401 | if (err < 0) | 397 | if (err < 0) |
402 | mgmt_pending_remove(cmd); | 398 | mgmt_pending_remove(cmd); |
403 | 399 | ||
400 | if (cp->val) | ||
401 | hdev->discov_timeout = get_unaligned_le16(&cp->timeout); | ||
402 | |||
404 | failed: | 403 | failed: |
405 | hci_dev_unlock_bh(hdev); | 404 | hci_dev_unlock_bh(hdev); |
406 | hci_dev_put(hdev); | 405 | hci_dev_put(hdev); |
@@ -435,8 +434,8 @@ static int set_connectable(struct sock *sk, u16 index, unsigned char *data, | |||
435 | goto failed; | 434 | goto failed; |
436 | } | 435 | } |
437 | 436 | ||
438 | if (mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, index) || | 437 | if (mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, hdev) || |
439 | mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, index)) { | 438 | mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, hdev)) { |
440 | err = cmd_status(sk, index, MGMT_OP_SET_CONNECTABLE, EBUSY); | 439 | err = cmd_status(sk, index, MGMT_OP_SET_CONNECTABLE, EBUSY); |
441 | goto failed; | 440 | goto failed; |
442 | } | 441 | } |
@@ -446,7 +445,7 @@ static int set_connectable(struct sock *sk, u16 index, unsigned char *data, | |||
446 | goto failed; | 445 | goto failed; |
447 | } | 446 | } |
448 | 447 | ||
449 | cmd = mgmt_pending_add(sk, MGMT_OP_SET_CONNECTABLE, index, data, len); | 448 | cmd = mgmt_pending_add(sk, MGMT_OP_SET_CONNECTABLE, hdev, data, len); |
450 | if (!cmd) { | 449 | if (!cmd) { |
451 | err = -ENOMEM; | 450 | err = -ENOMEM; |
452 | goto failed; | 451 | goto failed; |
@@ -468,8 +467,8 @@ failed: | |||
468 | return err; | 467 | return err; |
469 | } | 468 | } |
470 | 469 | ||
471 | static int mgmt_event(u16 event, u16 index, void *data, u16 data_len, | 470 | static int mgmt_event(u16 event, struct hci_dev *hdev, void *data, |
472 | struct sock *skip_sk) | 471 | u16 data_len, struct sock *skip_sk) |
473 | { | 472 | { |
474 | struct sk_buff *skb; | 473 | struct sk_buff *skb; |
475 | struct mgmt_hdr *hdr; | 474 | struct mgmt_hdr *hdr; |
@@ -482,7 +481,10 @@ static int mgmt_event(u16 event, u16 index, void *data, u16 data_len, | |||
482 | 481 | ||
483 | hdr = (void *) skb_put(skb, sizeof(*hdr)); | 482 | hdr = (void *) skb_put(skb, sizeof(*hdr)); |
484 | hdr->opcode = cpu_to_le16(event); | 483 | hdr->opcode = cpu_to_le16(event); |
485 | hdr->index = cpu_to_le16(index); | 484 | if (hdev) |
485 | hdr->index = cpu_to_le16(hdev->id); | ||
486 | else | ||
487 | hdr->index = cpu_to_le16(MGMT_INDEX_NONE); | ||
486 | hdr->len = cpu_to_le16(data_len); | 488 | hdr->len = cpu_to_le16(data_len); |
487 | 489 | ||
488 | if (data) | 490 | if (data) |
@@ -534,7 +536,7 @@ static int set_pairable(struct sock *sk, u16 index, unsigned char *data, | |||
534 | 536 | ||
535 | ev.val = cp->val; | 537 | ev.val = cp->val; |
536 | 538 | ||
537 | err = mgmt_event(MGMT_EV_PAIRABLE, index, &ev, sizeof(ev), sk); | 539 | err = mgmt_event(MGMT_EV_PAIRABLE, hdev, &ev, sizeof(ev), sk); |
538 | 540 | ||
539 | failed: | 541 | failed: |
540 | hci_dev_unlock_bh(hdev); | 542 | hci_dev_unlock_bh(hdev); |
@@ -587,7 +589,7 @@ static void create_eir(struct hci_dev *hdev, u8 *data) | |||
587 | u16 eir_len = 0; | 589 | u16 eir_len = 0; |
588 | u16 uuid16_list[HCI_MAX_EIR_LENGTH / sizeof(u16)]; | 590 | u16 uuid16_list[HCI_MAX_EIR_LENGTH / sizeof(u16)]; |
589 | int i, truncated = 0; | 591 | int i, truncated = 0; |
590 | struct list_head *p; | 592 | struct bt_uuid *uuid; |
591 | size_t name_len; | 593 | size_t name_len; |
592 | 594 | ||
593 | name_len = strlen(hdev->dev_name); | 595 | name_len = strlen(hdev->dev_name); |
@@ -612,8 +614,7 @@ static void create_eir(struct hci_dev *hdev, u8 *data) | |||
612 | memset(uuid16_list, 0, sizeof(uuid16_list)); | 614 | memset(uuid16_list, 0, sizeof(uuid16_list)); |
613 | 615 | ||
614 | /* Group all UUID16 types */ | 616 | /* Group all UUID16 types */ |
615 | list_for_each(p, &hdev->uuids) { | 617 | list_for_each_entry(uuid, &hdev->uuids, list) { |
616 | struct bt_uuid *uuid = list_entry(p, struct bt_uuid, list); | ||
617 | u16 uuid16; | 618 | u16 uuid16; |
618 | 619 | ||
619 | uuid16 = get_uuid16(uuid->uuid); | 620 | uuid16 = get_uuid16(uuid->uuid); |
@@ -689,14 +690,11 @@ static int update_eir(struct hci_dev *hdev) | |||
689 | 690 | ||
690 | static u8 get_service_classes(struct hci_dev *hdev) | 691 | static u8 get_service_classes(struct hci_dev *hdev) |
691 | { | 692 | { |
692 | struct list_head *p; | 693 | struct bt_uuid *uuid; |
693 | u8 val = 0; | 694 | u8 val = 0; |
694 | 695 | ||
695 | list_for_each(p, &hdev->uuids) { | 696 | list_for_each_entry(uuid, &hdev->uuids, list) |
696 | struct bt_uuid *uuid = list_entry(p, struct bt_uuid, list); | ||
697 | |||
698 | val |= uuid->svc_hint; | 697 | val |= uuid->svc_hint; |
699 | } | ||
700 | 698 | ||
701 | return val; | 699 | return val; |
702 | } | 700 | } |
@@ -895,6 +893,9 @@ static int set_service_cache(struct sock *sk, u16 index, unsigned char *data, | |||
895 | if (err == 0) | 893 | if (err == 0) |
896 | err = cmd_complete(sk, index, MGMT_OP_SET_SERVICE_CACHE, NULL, | 894 | err = cmd_complete(sk, index, MGMT_OP_SET_SERVICE_CACHE, NULL, |
897 | 0); | 895 | 0); |
896 | else | ||
897 | cmd_status(sk, index, MGMT_OP_SET_SERVICE_CACHE, -err); | ||
898 | |||
898 | 899 | ||
899 | hci_dev_unlock_bh(hdev); | 900 | hci_dev_unlock_bh(hdev); |
900 | hci_dev_put(hdev); | 901 | hci_dev_put(hdev); |
@@ -902,30 +903,32 @@ static int set_service_cache(struct sock *sk, u16 index, unsigned char *data, | |||
902 | return err; | 903 | return err; |
903 | } | 904 | } |
904 | 905 | ||
905 | static int load_keys(struct sock *sk, u16 index, unsigned char *data, u16 len) | 906 | static int load_link_keys(struct sock *sk, u16 index, unsigned char *data, |
907 | u16 len) | ||
906 | { | 908 | { |
907 | struct hci_dev *hdev; | 909 | struct hci_dev *hdev; |
908 | struct mgmt_cp_load_keys *cp; | 910 | struct mgmt_cp_load_link_keys *cp; |
909 | u16 key_count, expected_len; | 911 | u16 key_count, expected_len; |
910 | int i; | 912 | int i; |
911 | 913 | ||
912 | cp = (void *) data; | 914 | cp = (void *) data; |
913 | 915 | ||
914 | if (len < sizeof(*cp)) | 916 | if (len < sizeof(*cp)) |
915 | return -EINVAL; | 917 | return cmd_status(sk, index, MGMT_OP_LOAD_LINK_KEYS, EINVAL); |
916 | 918 | ||
917 | key_count = get_unaligned_le16(&cp->key_count); | 919 | key_count = get_unaligned_le16(&cp->key_count); |
918 | 920 | ||
919 | expected_len = sizeof(*cp) + key_count * sizeof(struct mgmt_key_info); | 921 | expected_len = sizeof(*cp) + key_count * |
922 | sizeof(struct mgmt_link_key_info); | ||
920 | if (expected_len != len) { | 923 | if (expected_len != len) { |
921 | BT_ERR("load_keys: expected %u bytes, got %u bytes", | 924 | BT_ERR("load_link_keys: expected %u bytes, got %u bytes", |
922 | len, expected_len); | 925 | len, expected_len); |
923 | return -EINVAL; | 926 | return cmd_status(sk, index, MGMT_OP_LOAD_LINK_KEYS, EINVAL); |
924 | } | 927 | } |
925 | 928 | ||
926 | hdev = hci_dev_get(index); | 929 | hdev = hci_dev_get(index); |
927 | if (!hdev) | 930 | if (!hdev) |
928 | return cmd_status(sk, index, MGMT_OP_LOAD_KEYS, ENODEV); | 931 | return cmd_status(sk, index, MGMT_OP_LOAD_LINK_KEYS, ENODEV); |
929 | 932 | ||
930 | BT_DBG("hci%u debug_keys %u key_count %u", index, cp->debug_keys, | 933 | BT_DBG("hci%u debug_keys %u key_count %u", index, cp->debug_keys, |
931 | key_count); | 934 | key_count); |
@@ -942,7 +945,7 @@ static int load_keys(struct sock *sk, u16 index, unsigned char *data, u16 len) | |||
942 | clear_bit(HCI_DEBUG_KEYS, &hdev->flags); | 945 | clear_bit(HCI_DEBUG_KEYS, &hdev->flags); |
943 | 946 | ||
944 | for (i = 0; i < key_count; i++) { | 947 | for (i = 0; i < key_count; i++) { |
945 | struct mgmt_key_info *key = &cp->keys[i]; | 948 | struct mgmt_link_key_info *key = &cp->keys[i]; |
946 | 949 | ||
947 | hci_add_link_key(hdev, NULL, 0, &key->bdaddr, key->val, key->type, | 950 | hci_add_link_key(hdev, NULL, 0, &key->bdaddr, key->val, key->type, |
948 | key->pin_len); | 951 | key->pin_len); |
@@ -954,27 +957,28 @@ static int load_keys(struct sock *sk, u16 index, unsigned char *data, u16 len) | |||
954 | return 0; | 957 | return 0; |
955 | } | 958 | } |
956 | 959 | ||
957 | static int remove_key(struct sock *sk, u16 index, unsigned char *data, u16 len) | 960 | static int remove_keys(struct sock *sk, u16 index, unsigned char *data, |
961 | u16 len) | ||
958 | { | 962 | { |
959 | struct hci_dev *hdev; | 963 | struct hci_dev *hdev; |
960 | struct mgmt_cp_remove_key *cp; | 964 | struct mgmt_cp_remove_keys *cp; |
961 | struct hci_conn *conn; | 965 | struct hci_conn *conn; |
962 | int err; | 966 | int err; |
963 | 967 | ||
964 | cp = (void *) data; | 968 | cp = (void *) data; |
965 | 969 | ||
966 | if (len != sizeof(*cp)) | 970 | if (len != sizeof(*cp)) |
967 | return cmd_status(sk, index, MGMT_OP_REMOVE_KEY, EINVAL); | 971 | return cmd_status(sk, index, MGMT_OP_REMOVE_KEYS, EINVAL); |
968 | 972 | ||
969 | hdev = hci_dev_get(index); | 973 | hdev = hci_dev_get(index); |
970 | if (!hdev) | 974 | if (!hdev) |
971 | return cmd_status(sk, index, MGMT_OP_REMOVE_KEY, ENODEV); | 975 | return cmd_status(sk, index, MGMT_OP_REMOVE_KEYS, ENODEV); |
972 | 976 | ||
973 | hci_dev_lock_bh(hdev); | 977 | hci_dev_lock_bh(hdev); |
974 | 978 | ||
975 | err = hci_remove_link_key(hdev, &cp->bdaddr); | 979 | err = hci_remove_link_key(hdev, &cp->bdaddr); |
976 | if (err < 0) { | 980 | if (err < 0) { |
977 | err = cmd_status(sk, index, MGMT_OP_REMOVE_KEY, -err); | 981 | err = cmd_status(sk, index, MGMT_OP_REMOVE_KEYS, -err); |
978 | goto unlock; | 982 | goto unlock; |
979 | } | 983 | } |
980 | 984 | ||
@@ -1026,7 +1030,7 @@ static int disconnect(struct sock *sk, u16 index, unsigned char *data, u16 len) | |||
1026 | goto failed; | 1030 | goto failed; |
1027 | } | 1031 | } |
1028 | 1032 | ||
1029 | if (mgmt_pending_find(MGMT_OP_DISCONNECT, index)) { | 1033 | if (mgmt_pending_find(MGMT_OP_DISCONNECT, hdev)) { |
1030 | err = cmd_status(sk, index, MGMT_OP_DISCONNECT, EBUSY); | 1034 | err = cmd_status(sk, index, MGMT_OP_DISCONNECT, EBUSY); |
1031 | goto failed; | 1035 | goto failed; |
1032 | } | 1036 | } |
@@ -1040,7 +1044,7 @@ static int disconnect(struct sock *sk, u16 index, unsigned char *data, u16 len) | |||
1040 | goto failed; | 1044 | goto failed; |
1041 | } | 1045 | } |
1042 | 1046 | ||
1043 | cmd = mgmt_pending_add(sk, MGMT_OP_DISCONNECT, index, data, len); | 1047 | cmd = mgmt_pending_add(sk, MGMT_OP_DISCONNECT, hdev, data, len); |
1044 | if (!cmd) { | 1048 | if (!cmd) { |
1045 | err = -ENOMEM; | 1049 | err = -ENOMEM; |
1046 | goto failed; | 1050 | goto failed; |
@@ -1060,10 +1064,23 @@ failed: | |||
1060 | return err; | 1064 | return err; |
1061 | } | 1065 | } |
1062 | 1066 | ||
1067 | static u8 link_to_mgmt(u8 link_type) | ||
1068 | { | ||
1069 | switch (link_type) { | ||
1070 | case LE_LINK: | ||
1071 | return MGMT_ADDR_LE; | ||
1072 | case ACL_LINK: | ||
1073 | return MGMT_ADDR_BREDR; | ||
1074 | default: | ||
1075 | return MGMT_ADDR_INVALID; | ||
1076 | } | ||
1077 | } | ||
1078 | |||
1063 | static int get_connections(struct sock *sk, u16 index) | 1079 | static int get_connections(struct sock *sk, u16 index) |
1064 | { | 1080 | { |
1065 | struct mgmt_rp_get_connections *rp; | 1081 | struct mgmt_rp_get_connections *rp; |
1066 | struct hci_dev *hdev; | 1082 | struct hci_dev *hdev; |
1083 | struct hci_conn *c; | ||
1067 | struct list_head *p; | 1084 | struct list_head *p; |
1068 | size_t rp_len; | 1085 | size_t rp_len; |
1069 | u16 count; | 1086 | u16 count; |
@@ -1082,7 +1099,7 @@ static int get_connections(struct sock *sk, u16 index) | |||
1082 | count++; | 1099 | count++; |
1083 | } | 1100 | } |
1084 | 1101 | ||
1085 | rp_len = sizeof(*rp) + (count * sizeof(bdaddr_t)); | 1102 | rp_len = sizeof(*rp) + (count * sizeof(struct mgmt_addr_info)); |
1086 | rp = kmalloc(rp_len, GFP_ATOMIC); | 1103 | rp = kmalloc(rp_len, GFP_ATOMIC); |
1087 | if (!rp) { | 1104 | if (!rp) { |
1088 | err = -ENOMEM; | 1105 | err = -ENOMEM; |
@@ -1092,12 +1109,17 @@ static int get_connections(struct sock *sk, u16 index) | |||
1092 | put_unaligned_le16(count, &rp->conn_count); | 1109 | put_unaligned_le16(count, &rp->conn_count); |
1093 | 1110 | ||
1094 | i = 0; | 1111 | i = 0; |
1095 | list_for_each(p, &hdev->conn_hash.list) { | 1112 | list_for_each_entry(c, &hdev->conn_hash.list, list) { |
1096 | struct hci_conn *c = list_entry(p, struct hci_conn, list); | 1113 | bacpy(&rp->addr[i].bdaddr, &c->dst); |
1097 | 1114 | rp->addr[i].type = link_to_mgmt(c->type); | |
1098 | bacpy(&rp->conn[i++], &c->dst); | 1115 | if (rp->addr[i].type == MGMT_ADDR_INVALID) |
1116 | continue; | ||
1117 | i++; | ||
1099 | } | 1118 | } |
1100 | 1119 | ||
1120 | /* Recalculate length in case of filtered SCO connections, etc */ | ||
1121 | rp_len = sizeof(*rp) + (i * sizeof(struct mgmt_addr_info)); | ||
1122 | |||
1101 | err = cmd_complete(sk, index, MGMT_OP_GET_CONNECTIONS, rp, rp_len); | 1123 | err = cmd_complete(sk, index, MGMT_OP_GET_CONNECTIONS, rp, rp_len); |
1102 | 1124 | ||
1103 | unlock: | 1125 | unlock: |
@@ -1113,7 +1135,7 @@ static int send_pin_code_neg_reply(struct sock *sk, u16 index, | |||
1113 | struct pending_cmd *cmd; | 1135 | struct pending_cmd *cmd; |
1114 | int err; | 1136 | int err; |
1115 | 1137 | ||
1116 | cmd = mgmt_pending_add(sk, MGMT_OP_PIN_CODE_NEG_REPLY, index, cp, | 1138 | cmd = mgmt_pending_add(sk, MGMT_OP_PIN_CODE_NEG_REPLY, hdev, cp, |
1117 | sizeof(*cp)); | 1139 | sizeof(*cp)); |
1118 | if (!cmd) | 1140 | if (!cmd) |
1119 | return -ENOMEM; | 1141 | return -ENOMEM; |
@@ -1174,7 +1196,7 @@ static int pin_code_reply(struct sock *sk, u16 index, unsigned char *data, | |||
1174 | goto failed; | 1196 | goto failed; |
1175 | } | 1197 | } |
1176 | 1198 | ||
1177 | cmd = mgmt_pending_add(sk, MGMT_OP_PIN_CODE_REPLY, index, data, len); | 1199 | cmd = mgmt_pending_add(sk, MGMT_OP_PIN_CODE_REPLY, hdev, data, len); |
1178 | if (!cmd) { | 1200 | if (!cmd) { |
1179 | err = -ENOMEM; | 1201 | err = -ENOMEM; |
1180 | goto failed; | 1202 | goto failed; |
@@ -1265,19 +1287,12 @@ static int set_io_capability(struct sock *sk, u16 index, unsigned char *data, | |||
1265 | static inline struct pending_cmd *find_pairing(struct hci_conn *conn) | 1287 | static inline struct pending_cmd *find_pairing(struct hci_conn *conn) |
1266 | { | 1288 | { |
1267 | struct hci_dev *hdev = conn->hdev; | 1289 | struct hci_dev *hdev = conn->hdev; |
1268 | struct list_head *p; | 1290 | struct pending_cmd *cmd; |
1269 | |||
1270 | list_for_each(p, &cmd_list) { | ||
1271 | struct pending_cmd *cmd; | ||
1272 | |||
1273 | cmd = list_entry(p, struct pending_cmd, list); | ||
1274 | 1291 | ||
1292 | list_for_each_entry(cmd, &hdev->mgmt_pending, list) { | ||
1275 | if (cmd->opcode != MGMT_OP_PAIR_DEVICE) | 1293 | if (cmd->opcode != MGMT_OP_PAIR_DEVICE) |
1276 | continue; | 1294 | continue; |
1277 | 1295 | ||
1278 | if (cmd->index != hdev->id) | ||
1279 | continue; | ||
1280 | |||
1281 | if (cmd->user_data != conn) | 1296 | if (cmd->user_data != conn) |
1282 | continue; | 1297 | continue; |
1283 | 1298 | ||
@@ -1310,16 +1325,19 @@ static void pairing_complete(struct pending_cmd *cmd, u8 status) | |||
1310 | static void pairing_complete_cb(struct hci_conn *conn, u8 status) | 1325 | static void pairing_complete_cb(struct hci_conn *conn, u8 status) |
1311 | { | 1326 | { |
1312 | struct pending_cmd *cmd; | 1327 | struct pending_cmd *cmd; |
1328 | struct hci_dev *hdev = conn->hdev; | ||
1313 | 1329 | ||
1314 | BT_DBG("status %u", status); | 1330 | BT_DBG("status %u", status); |
1315 | 1331 | ||
1332 | hci_dev_lock_bh(hdev); | ||
1333 | |||
1316 | cmd = find_pairing(conn); | 1334 | cmd = find_pairing(conn); |
1317 | if (!cmd) { | 1335 | if (!cmd) |
1318 | BT_DBG("Unable to find a pending command"); | 1336 | BT_DBG("Unable to find a pending command"); |
1319 | return; | 1337 | else |
1320 | } | 1338 | pairing_complete(cmd, status); |
1321 | 1339 | ||
1322 | pairing_complete(cmd, status); | 1340 | hci_dev_unlock_bh(hdev); |
1323 | } | 1341 | } |
1324 | 1342 | ||
1325 | static int pair_device(struct sock *sk, u16 index, unsigned char *data, u16 len) | 1343 | static int pair_device(struct sock *sk, u16 index, unsigned char *data, u16 len) |
@@ -1370,7 +1388,7 @@ static int pair_device(struct sock *sk, u16 index, unsigned char *data, u16 len) | |||
1370 | goto unlock; | 1388 | goto unlock; |
1371 | } | 1389 | } |
1372 | 1390 | ||
1373 | cmd = mgmt_pending_add(sk, MGMT_OP_PAIR_DEVICE, index, data, len); | 1391 | cmd = mgmt_pending_add(sk, MGMT_OP_PAIR_DEVICE, hdev, data, len); |
1374 | if (!cmd) { | 1392 | if (!cmd) { |
1375 | err = -ENOMEM; | 1393 | err = -ENOMEM; |
1376 | hci_conn_put(conn); | 1394 | hci_conn_put(conn); |
@@ -1432,7 +1450,7 @@ static int user_confirm_reply(struct sock *sk, u16 index, unsigned char *data, | |||
1432 | goto failed; | 1450 | goto failed; |
1433 | } | 1451 | } |
1434 | 1452 | ||
1435 | cmd = mgmt_pending_add(sk, mgmt_op, index, data, len); | 1453 | cmd = mgmt_pending_add(sk, mgmt_op, hdev, data, len); |
1436 | if (!cmd) { | 1454 | if (!cmd) { |
1437 | err = -ENOMEM; | 1455 | err = -ENOMEM; |
1438 | goto failed; | 1456 | goto failed; |
@@ -1469,7 +1487,7 @@ static int set_local_name(struct sock *sk, u16 index, unsigned char *data, | |||
1469 | 1487 | ||
1470 | hci_dev_lock_bh(hdev); | 1488 | hci_dev_lock_bh(hdev); |
1471 | 1489 | ||
1472 | cmd = mgmt_pending_add(sk, MGMT_OP_SET_LOCAL_NAME, index, data, len); | 1490 | cmd = mgmt_pending_add(sk, MGMT_OP_SET_LOCAL_NAME, hdev, data, len); |
1473 | if (!cmd) { | 1491 | if (!cmd) { |
1474 | err = -ENOMEM; | 1492 | err = -ENOMEM; |
1475 | goto failed; | 1493 | goto failed; |
@@ -1515,12 +1533,12 @@ static int read_local_oob_data(struct sock *sk, u16 index) | |||
1515 | goto unlock; | 1533 | goto unlock; |
1516 | } | 1534 | } |
1517 | 1535 | ||
1518 | if (mgmt_pending_find(MGMT_OP_READ_LOCAL_OOB_DATA, index)) { | 1536 | if (mgmt_pending_find(MGMT_OP_READ_LOCAL_OOB_DATA, hdev)) { |
1519 | err = cmd_status(sk, index, MGMT_OP_READ_LOCAL_OOB_DATA, EBUSY); | 1537 | err = cmd_status(sk, index, MGMT_OP_READ_LOCAL_OOB_DATA, EBUSY); |
1520 | goto unlock; | 1538 | goto unlock; |
1521 | } | 1539 | } |
1522 | 1540 | ||
1523 | cmd = mgmt_pending_add(sk, MGMT_OP_READ_LOCAL_OOB_DATA, index, NULL, 0); | 1541 | cmd = mgmt_pending_add(sk, MGMT_OP_READ_LOCAL_OOB_DATA, hdev, NULL, 0); |
1524 | if (!cmd) { | 1542 | if (!cmd) { |
1525 | err = -ENOMEM; | 1543 | err = -ENOMEM; |
1526 | goto unlock; | 1544 | goto unlock; |
@@ -1607,8 +1625,6 @@ static int remove_remote_oob_data(struct sock *sk, u16 index, | |||
1607 | 1625 | ||
1608 | static int start_discovery(struct sock *sk, u16 index) | 1626 | static int start_discovery(struct sock *sk, u16 index) |
1609 | { | 1627 | { |
1610 | u8 lap[3] = { 0x33, 0x8b, 0x9e }; | ||
1611 | struct hci_cp_inquiry cp; | ||
1612 | struct pending_cmd *cmd; | 1628 | struct pending_cmd *cmd; |
1613 | struct hci_dev *hdev; | 1629 | struct hci_dev *hdev; |
1614 | int err; | 1630 | int err; |
@@ -1621,18 +1637,18 @@ static int start_discovery(struct sock *sk, u16 index) | |||
1621 | 1637 | ||
1622 | hci_dev_lock_bh(hdev); | 1638 | hci_dev_lock_bh(hdev); |
1623 | 1639 | ||
1624 | cmd = mgmt_pending_add(sk, MGMT_OP_START_DISCOVERY, index, NULL, 0); | 1640 | if (!test_bit(HCI_UP, &hdev->flags)) { |
1641 | err = cmd_status(sk, index, MGMT_OP_START_DISCOVERY, ENETDOWN); | ||
1642 | goto failed; | ||
1643 | } | ||
1644 | |||
1645 | cmd = mgmt_pending_add(sk, MGMT_OP_START_DISCOVERY, hdev, NULL, 0); | ||
1625 | if (!cmd) { | 1646 | if (!cmd) { |
1626 | err = -ENOMEM; | 1647 | err = -ENOMEM; |
1627 | goto failed; | 1648 | goto failed; |
1628 | } | 1649 | } |
1629 | 1650 | ||
1630 | memset(&cp, 0, sizeof(cp)); | 1651 | err = hci_do_inquiry(hdev, INQUIRY_LEN_BREDR); |
1631 | memcpy(&cp.lap, lap, 3); | ||
1632 | cp.length = 0x08; | ||
1633 | cp.num_rsp = 0x00; | ||
1634 | |||
1635 | err = hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp); | ||
1636 | if (err < 0) | 1652 | if (err < 0) |
1637 | mgmt_pending_remove(cmd); | 1653 | mgmt_pending_remove(cmd); |
1638 | 1654 | ||
@@ -1657,13 +1673,13 @@ static int stop_discovery(struct sock *sk, u16 index) | |||
1657 | 1673 | ||
1658 | hci_dev_lock_bh(hdev); | 1674 | hci_dev_lock_bh(hdev); |
1659 | 1675 | ||
1660 | cmd = mgmt_pending_add(sk, MGMT_OP_STOP_DISCOVERY, index, NULL, 0); | 1676 | cmd = mgmt_pending_add(sk, MGMT_OP_STOP_DISCOVERY, hdev, NULL, 0); |
1661 | if (!cmd) { | 1677 | if (!cmd) { |
1662 | err = -ENOMEM; | 1678 | err = -ENOMEM; |
1663 | goto failed; | 1679 | goto failed; |
1664 | } | 1680 | } |
1665 | 1681 | ||
1666 | err = hci_send_cmd(hdev, HCI_OP_INQUIRY_CANCEL, 0, NULL); | 1682 | err = hci_cancel_inquiry(hdev); |
1667 | if (err < 0) | 1683 | if (err < 0) |
1668 | mgmt_pending_remove(cmd); | 1684 | mgmt_pending_remove(cmd); |
1669 | 1685 | ||
@@ -1678,7 +1694,6 @@ static int block_device(struct sock *sk, u16 index, unsigned char *data, | |||
1678 | u16 len) | 1694 | u16 len) |
1679 | { | 1695 | { |
1680 | struct hci_dev *hdev; | 1696 | struct hci_dev *hdev; |
1681 | struct pending_cmd *cmd; | ||
1682 | struct mgmt_cp_block_device *cp = (void *) data; | 1697 | struct mgmt_cp_block_device *cp = (void *) data; |
1683 | int err; | 1698 | int err; |
1684 | 1699 | ||
@@ -1695,23 +1710,13 @@ static int block_device(struct sock *sk, u16 index, unsigned char *data, | |||
1695 | 1710 | ||
1696 | hci_dev_lock_bh(hdev); | 1711 | hci_dev_lock_bh(hdev); |
1697 | 1712 | ||
1698 | cmd = mgmt_pending_add(sk, MGMT_OP_BLOCK_DEVICE, index, NULL, 0); | ||
1699 | if (!cmd) { | ||
1700 | err = -ENOMEM; | ||
1701 | goto failed; | ||
1702 | } | ||
1703 | |||
1704 | err = hci_blacklist_add(hdev, &cp->bdaddr); | 1713 | err = hci_blacklist_add(hdev, &cp->bdaddr); |
1705 | |||
1706 | if (err < 0) | 1714 | if (err < 0) |
1707 | err = cmd_status(sk, index, MGMT_OP_BLOCK_DEVICE, -err); | 1715 | err = cmd_status(sk, index, MGMT_OP_BLOCK_DEVICE, -err); |
1708 | else | 1716 | else |
1709 | err = cmd_complete(sk, index, MGMT_OP_BLOCK_DEVICE, | 1717 | err = cmd_complete(sk, index, MGMT_OP_BLOCK_DEVICE, |
1710 | NULL, 0); | 1718 | NULL, 0); |
1711 | 1719 | ||
1712 | mgmt_pending_remove(cmd); | ||
1713 | |||
1714 | failed: | ||
1715 | hci_dev_unlock_bh(hdev); | 1720 | hci_dev_unlock_bh(hdev); |
1716 | hci_dev_put(hdev); | 1721 | hci_dev_put(hdev); |
1717 | 1722 | ||
@@ -1722,7 +1727,6 @@ static int unblock_device(struct sock *sk, u16 index, unsigned char *data, | |||
1722 | u16 len) | 1727 | u16 len) |
1723 | { | 1728 | { |
1724 | struct hci_dev *hdev; | 1729 | struct hci_dev *hdev; |
1725 | struct pending_cmd *cmd; | ||
1726 | struct mgmt_cp_unblock_device *cp = (void *) data; | 1730 | struct mgmt_cp_unblock_device *cp = (void *) data; |
1727 | int err; | 1731 | int err; |
1728 | 1732 | ||
@@ -1739,12 +1743,6 @@ static int unblock_device(struct sock *sk, u16 index, unsigned char *data, | |||
1739 | 1743 | ||
1740 | hci_dev_lock_bh(hdev); | 1744 | hci_dev_lock_bh(hdev); |
1741 | 1745 | ||
1742 | cmd = mgmt_pending_add(sk, MGMT_OP_UNBLOCK_DEVICE, index, NULL, 0); | ||
1743 | if (!cmd) { | ||
1744 | err = -ENOMEM; | ||
1745 | goto failed; | ||
1746 | } | ||
1747 | |||
1748 | err = hci_blacklist_del(hdev, &cp->bdaddr); | 1746 | err = hci_blacklist_del(hdev, &cp->bdaddr); |
1749 | 1747 | ||
1750 | if (err < 0) | 1748 | if (err < 0) |
@@ -1753,9 +1751,6 @@ static int unblock_device(struct sock *sk, u16 index, unsigned char *data, | |||
1753 | err = cmd_complete(sk, index, MGMT_OP_UNBLOCK_DEVICE, | 1751 | err = cmd_complete(sk, index, MGMT_OP_UNBLOCK_DEVICE, |
1754 | NULL, 0); | 1752 | NULL, 0); |
1755 | 1753 | ||
1756 | mgmt_pending_remove(cmd); | ||
1757 | |||
1758 | failed: | ||
1759 | hci_dev_unlock_bh(hdev); | 1754 | hci_dev_unlock_bh(hdev); |
1760 | hci_dev_put(hdev); | 1755 | hci_dev_put(hdev); |
1761 | 1756 | ||
@@ -1883,11 +1878,11 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) | |||
1883 | case MGMT_OP_SET_SERVICE_CACHE: | 1878 | case MGMT_OP_SET_SERVICE_CACHE: |
1884 | err = set_service_cache(sk, index, buf + sizeof(*hdr), len); | 1879 | err = set_service_cache(sk, index, buf + sizeof(*hdr), len); |
1885 | break; | 1880 | break; |
1886 | case MGMT_OP_LOAD_KEYS: | 1881 | case MGMT_OP_LOAD_LINK_KEYS: |
1887 | err = load_keys(sk, index, buf + sizeof(*hdr), len); | 1882 | err = load_link_keys(sk, index, buf + sizeof(*hdr), len); |
1888 | break; | 1883 | break; |
1889 | case MGMT_OP_REMOVE_KEY: | 1884 | case MGMT_OP_REMOVE_KEYS: |
1890 | err = remove_key(sk, index, buf + sizeof(*hdr), len); | 1885 | err = remove_keys(sk, index, buf + sizeof(*hdr), len); |
1891 | break; | 1886 | break; |
1892 | case MGMT_OP_DISCONNECT: | 1887 | case MGMT_OP_DISCONNECT: |
1893 | err = disconnect(sk, index, buf + sizeof(*hdr), len); | 1888 | err = disconnect(sk, index, buf + sizeof(*hdr), len); |
@@ -1958,14 +1953,26 @@ done: | |||
1958 | return err; | 1953 | return err; |
1959 | } | 1954 | } |
1960 | 1955 | ||
1961 | int mgmt_index_added(u16 index) | 1956 | static void cmd_status_rsp(struct pending_cmd *cmd, void *data) |
1962 | { | 1957 | { |
1963 | return mgmt_event(MGMT_EV_INDEX_ADDED, index, NULL, 0, NULL); | 1958 | u8 *status = data; |
1959 | |||
1960 | cmd_status(cmd->sk, cmd->index, cmd->opcode, *status); | ||
1961 | mgmt_pending_remove(cmd); | ||
1964 | } | 1962 | } |
1965 | 1963 | ||
1966 | int mgmt_index_removed(u16 index) | 1964 | int mgmt_index_added(struct hci_dev *hdev) |
1967 | { | 1965 | { |
1968 | return mgmt_event(MGMT_EV_INDEX_REMOVED, index, NULL, 0, NULL); | 1966 | return mgmt_event(MGMT_EV_INDEX_ADDED, hdev, NULL, 0, NULL); |
1967 | } | ||
1968 | |||
1969 | int mgmt_index_removed(struct hci_dev *hdev) | ||
1970 | { | ||
1971 | u8 status = ENODEV; | ||
1972 | |||
1973 | mgmt_pending_foreach(0, hdev, cmd_status_rsp, &status); | ||
1974 | |||
1975 | return mgmt_event(MGMT_EV_INDEX_REMOVED, hdev, NULL, 0, NULL); | ||
1969 | } | 1976 | } |
1970 | 1977 | ||
1971 | struct cmd_lookup { | 1978 | struct cmd_lookup { |
@@ -1993,17 +2000,22 @@ static void mode_rsp(struct pending_cmd *cmd, void *data) | |||
1993 | mgmt_pending_free(cmd); | 2000 | mgmt_pending_free(cmd); |
1994 | } | 2001 | } |
1995 | 2002 | ||
1996 | int mgmt_powered(u16 index, u8 powered) | 2003 | int mgmt_powered(struct hci_dev *hdev, u8 powered) |
1997 | { | 2004 | { |
1998 | struct mgmt_mode ev; | 2005 | struct mgmt_mode ev; |
1999 | struct cmd_lookup match = { powered, NULL }; | 2006 | struct cmd_lookup match = { powered, NULL }; |
2000 | int ret; | 2007 | int ret; |
2001 | 2008 | ||
2002 | mgmt_pending_foreach(MGMT_OP_SET_POWERED, index, mode_rsp, &match); | 2009 | mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, mode_rsp, &match); |
2010 | |||
2011 | if (!powered) { | ||
2012 | u8 status = ENETDOWN; | ||
2013 | mgmt_pending_foreach(0, hdev, cmd_status_rsp, &status); | ||
2014 | } | ||
2003 | 2015 | ||
2004 | ev.val = powered; | 2016 | ev.val = powered; |
2005 | 2017 | ||
2006 | ret = mgmt_event(MGMT_EV_POWERED, index, &ev, sizeof(ev), match.sk); | 2018 | ret = mgmt_event(MGMT_EV_POWERED, hdev, &ev, sizeof(ev), match.sk); |
2007 | 2019 | ||
2008 | if (match.sk) | 2020 | if (match.sk) |
2009 | sock_put(match.sk); | 2021 | sock_put(match.sk); |
@@ -2011,17 +2023,17 @@ int mgmt_powered(u16 index, u8 powered) | |||
2011 | return ret; | 2023 | return ret; |
2012 | } | 2024 | } |
2013 | 2025 | ||
2014 | int mgmt_discoverable(u16 index, u8 discoverable) | 2026 | int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable) |
2015 | { | 2027 | { |
2016 | struct mgmt_mode ev; | 2028 | struct mgmt_mode ev; |
2017 | struct cmd_lookup match = { discoverable, NULL }; | 2029 | struct cmd_lookup match = { discoverable, NULL }; |
2018 | int ret; | 2030 | int ret; |
2019 | 2031 | ||
2020 | mgmt_pending_foreach(MGMT_OP_SET_DISCOVERABLE, index, mode_rsp, &match); | 2032 | mgmt_pending_foreach(MGMT_OP_SET_DISCOVERABLE, hdev, mode_rsp, &match); |
2021 | 2033 | ||
2022 | ev.val = discoverable; | 2034 | ev.val = discoverable; |
2023 | 2035 | ||
2024 | ret = mgmt_event(MGMT_EV_DISCOVERABLE, index, &ev, sizeof(ev), | 2036 | ret = mgmt_event(MGMT_EV_DISCOVERABLE, hdev, &ev, sizeof(ev), |
2025 | match.sk); | 2037 | match.sk); |
2026 | 2038 | ||
2027 | if (match.sk) | 2039 | if (match.sk) |
@@ -2030,17 +2042,17 @@ int mgmt_discoverable(u16 index, u8 discoverable) | |||
2030 | return ret; | 2042 | return ret; |
2031 | } | 2043 | } |
2032 | 2044 | ||
2033 | int mgmt_connectable(u16 index, u8 connectable) | 2045 | int mgmt_connectable(struct hci_dev *hdev, u8 connectable) |
2034 | { | 2046 | { |
2035 | struct mgmt_mode ev; | 2047 | struct mgmt_mode ev; |
2036 | struct cmd_lookup match = { connectable, NULL }; | 2048 | struct cmd_lookup match = { connectable, NULL }; |
2037 | int ret; | 2049 | int ret; |
2038 | 2050 | ||
2039 | mgmt_pending_foreach(MGMT_OP_SET_CONNECTABLE, index, mode_rsp, &match); | 2051 | mgmt_pending_foreach(MGMT_OP_SET_CONNECTABLE, hdev, mode_rsp, &match); |
2040 | 2052 | ||
2041 | ev.val = connectable; | 2053 | ev.val = connectable; |
2042 | 2054 | ||
2043 | ret = mgmt_event(MGMT_EV_CONNECTABLE, index, &ev, sizeof(ev), match.sk); | 2055 | ret = mgmt_event(MGMT_EV_CONNECTABLE, hdev, &ev, sizeof(ev), match.sk); |
2044 | 2056 | ||
2045 | if (match.sk) | 2057 | if (match.sk) |
2046 | sock_put(match.sk); | 2058 | sock_put(match.sk); |
@@ -2048,9 +2060,23 @@ int mgmt_connectable(u16 index, u8 connectable) | |||
2048 | return ret; | 2060 | return ret; |
2049 | } | 2061 | } |
2050 | 2062 | ||
2051 | int mgmt_new_key(u16 index, struct link_key *key, u8 persistent) | 2063 | int mgmt_write_scan_failed(struct hci_dev *hdev, u8 scan, u8 status) |
2064 | { | ||
2065 | if (scan & SCAN_PAGE) | ||
2066 | mgmt_pending_foreach(MGMT_OP_SET_CONNECTABLE, hdev, | ||
2067 | cmd_status_rsp, &status); | ||
2068 | |||
2069 | if (scan & SCAN_INQUIRY) | ||
2070 | mgmt_pending_foreach(MGMT_OP_SET_DISCOVERABLE, hdev, | ||
2071 | cmd_status_rsp, &status); | ||
2072 | |||
2073 | return 0; | ||
2074 | } | ||
2075 | |||
2076 | int mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key, | ||
2077 | u8 persistent) | ||
2052 | { | 2078 | { |
2053 | struct mgmt_ev_new_key ev; | 2079 | struct mgmt_ev_new_link_key ev; |
2054 | 2080 | ||
2055 | memset(&ev, 0, sizeof(ev)); | 2081 | memset(&ev, 0, sizeof(ev)); |
2056 | 2082 | ||
@@ -2060,17 +2086,17 @@ int mgmt_new_key(u16 index, struct link_key *key, u8 persistent) | |||
2060 | memcpy(ev.key.val, key->val, 16); | 2086 | memcpy(ev.key.val, key->val, 16); |
2061 | ev.key.pin_len = key->pin_len; | 2087 | ev.key.pin_len = key->pin_len; |
2062 | 2088 | ||
2063 | return mgmt_event(MGMT_EV_NEW_KEY, index, &ev, sizeof(ev), NULL); | 2089 | return mgmt_event(MGMT_EV_NEW_LINK_KEY, hdev, &ev, sizeof(ev), NULL); |
2064 | } | 2090 | } |
2065 | 2091 | ||
2066 | int mgmt_connected(u16 index, bdaddr_t *bdaddr, u8 link_type) | 2092 | int mgmt_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type) |
2067 | { | 2093 | { |
2068 | struct mgmt_ev_connected ev; | 2094 | struct mgmt_addr_info ev; |
2069 | 2095 | ||
2070 | bacpy(&ev.bdaddr, bdaddr); | 2096 | bacpy(&ev.bdaddr, bdaddr); |
2071 | ev.link_type = link_type; | 2097 | ev.type = link_to_mgmt(link_type); |
2072 | 2098 | ||
2073 | return mgmt_event(MGMT_EV_CONNECTED, index, &ev, sizeof(ev), NULL); | 2099 | return mgmt_event(MGMT_EV_CONNECTED, hdev, &ev, sizeof(ev), NULL); |
2074 | } | 2100 | } |
2075 | 2101 | ||
2076 | static void disconnect_rsp(struct pending_cmd *cmd, void *data) | 2102 | static void disconnect_rsp(struct pending_cmd *cmd, void *data) |
@@ -2089,17 +2115,18 @@ static void disconnect_rsp(struct pending_cmd *cmd, void *data) | |||
2089 | mgmt_pending_remove(cmd); | 2115 | mgmt_pending_remove(cmd); |
2090 | } | 2116 | } |
2091 | 2117 | ||
2092 | int mgmt_disconnected(u16 index, bdaddr_t *bdaddr) | 2118 | int mgmt_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) |
2093 | { | 2119 | { |
2094 | struct mgmt_ev_disconnected ev; | 2120 | struct mgmt_addr_info ev; |
2095 | struct sock *sk = NULL; | 2121 | struct sock *sk = NULL; |
2096 | int err; | 2122 | int err; |
2097 | 2123 | ||
2098 | mgmt_pending_foreach(MGMT_OP_DISCONNECT, index, disconnect_rsp, &sk); | 2124 | mgmt_pending_foreach(MGMT_OP_DISCONNECT, hdev, disconnect_rsp, &sk); |
2099 | 2125 | ||
2100 | bacpy(&ev.bdaddr, bdaddr); | 2126 | bacpy(&ev.bdaddr, bdaddr); |
2127 | ev.type = link_to_mgmt(type); | ||
2101 | 2128 | ||
2102 | err = mgmt_event(MGMT_EV_DISCONNECTED, index, &ev, sizeof(ev), sk); | 2129 | err = mgmt_event(MGMT_EV_DISCONNECTED, hdev, &ev, sizeof(ev), sk); |
2103 | 2130 | ||
2104 | if (sk) | 2131 | if (sk) |
2105 | sock_put(sk); | 2132 | sock_put(sk); |
@@ -2107,57 +2134,60 @@ int mgmt_disconnected(u16 index, bdaddr_t *bdaddr) | |||
2107 | return err; | 2134 | return err; |
2108 | } | 2135 | } |
2109 | 2136 | ||
2110 | int mgmt_disconnect_failed(u16 index) | 2137 | int mgmt_disconnect_failed(struct hci_dev *hdev) |
2111 | { | 2138 | { |
2112 | struct pending_cmd *cmd; | 2139 | struct pending_cmd *cmd; |
2113 | int err; | 2140 | int err; |
2114 | 2141 | ||
2115 | cmd = mgmt_pending_find(MGMT_OP_DISCONNECT, index); | 2142 | cmd = mgmt_pending_find(MGMT_OP_DISCONNECT, hdev); |
2116 | if (!cmd) | 2143 | if (!cmd) |
2117 | return -ENOENT; | 2144 | return -ENOENT; |
2118 | 2145 | ||
2119 | err = cmd_status(cmd->sk, index, MGMT_OP_DISCONNECT, EIO); | 2146 | err = cmd_status(cmd->sk, hdev->id, MGMT_OP_DISCONNECT, EIO); |
2120 | 2147 | ||
2121 | mgmt_pending_remove(cmd); | 2148 | mgmt_pending_remove(cmd); |
2122 | 2149 | ||
2123 | return err; | 2150 | return err; |
2124 | } | 2151 | } |
2125 | 2152 | ||
2126 | int mgmt_connect_failed(u16 index, bdaddr_t *bdaddr, u8 status) | 2153 | int mgmt_connect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type, |
2154 | u8 status) | ||
2127 | { | 2155 | { |
2128 | struct mgmt_ev_connect_failed ev; | 2156 | struct mgmt_ev_connect_failed ev; |
2129 | 2157 | ||
2130 | bacpy(&ev.bdaddr, bdaddr); | 2158 | bacpy(&ev.addr.bdaddr, bdaddr); |
2159 | ev.addr.type = link_to_mgmt(type); | ||
2131 | ev.status = status; | 2160 | ev.status = status; |
2132 | 2161 | ||
2133 | return mgmt_event(MGMT_EV_CONNECT_FAILED, index, &ev, sizeof(ev), NULL); | 2162 | return mgmt_event(MGMT_EV_CONNECT_FAILED, hdev, &ev, sizeof(ev), NULL); |
2134 | } | 2163 | } |
2135 | 2164 | ||
2136 | int mgmt_pin_code_request(u16 index, bdaddr_t *bdaddr, u8 secure) | 2165 | int mgmt_pin_code_request(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 secure) |
2137 | { | 2166 | { |
2138 | struct mgmt_ev_pin_code_request ev; | 2167 | struct mgmt_ev_pin_code_request ev; |
2139 | 2168 | ||
2140 | bacpy(&ev.bdaddr, bdaddr); | 2169 | bacpy(&ev.bdaddr, bdaddr); |
2141 | ev.secure = secure; | 2170 | ev.secure = secure; |
2142 | 2171 | ||
2143 | return mgmt_event(MGMT_EV_PIN_CODE_REQUEST, index, &ev, sizeof(ev), | 2172 | return mgmt_event(MGMT_EV_PIN_CODE_REQUEST, hdev, &ev, sizeof(ev), |
2144 | NULL); | 2173 | NULL); |
2145 | } | 2174 | } |
2146 | 2175 | ||
2147 | int mgmt_pin_code_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status) | 2176 | int mgmt_pin_code_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, |
2177 | u8 status) | ||
2148 | { | 2178 | { |
2149 | struct pending_cmd *cmd; | 2179 | struct pending_cmd *cmd; |
2150 | struct mgmt_rp_pin_code_reply rp; | 2180 | struct mgmt_rp_pin_code_reply rp; |
2151 | int err; | 2181 | int err; |
2152 | 2182 | ||
2153 | cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_REPLY, index); | 2183 | cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_REPLY, hdev); |
2154 | if (!cmd) | 2184 | if (!cmd) |
2155 | return -ENOENT; | 2185 | return -ENOENT; |
2156 | 2186 | ||
2157 | bacpy(&rp.bdaddr, bdaddr); | 2187 | bacpy(&rp.bdaddr, bdaddr); |
2158 | rp.status = status; | 2188 | rp.status = status; |
2159 | 2189 | ||
2160 | err = cmd_complete(cmd->sk, index, MGMT_OP_PIN_CODE_REPLY, &rp, | 2190 | err = cmd_complete(cmd->sk, hdev->id, MGMT_OP_PIN_CODE_REPLY, &rp, |
2161 | sizeof(rp)); | 2191 | sizeof(rp)); |
2162 | 2192 | ||
2163 | mgmt_pending_remove(cmd); | 2193 | mgmt_pending_remove(cmd); |
@@ -2165,20 +2195,21 @@ int mgmt_pin_code_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status) | |||
2165 | return err; | 2195 | return err; |
2166 | } | 2196 | } |
2167 | 2197 | ||
2168 | int mgmt_pin_code_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status) | 2198 | int mgmt_pin_code_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, |
2199 | u8 status) | ||
2169 | { | 2200 | { |
2170 | struct pending_cmd *cmd; | 2201 | struct pending_cmd *cmd; |
2171 | struct mgmt_rp_pin_code_reply rp; | 2202 | struct mgmt_rp_pin_code_reply rp; |
2172 | int err; | 2203 | int err; |
2173 | 2204 | ||
2174 | cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_NEG_REPLY, index); | 2205 | cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_NEG_REPLY, hdev); |
2175 | if (!cmd) | 2206 | if (!cmd) |
2176 | return -ENOENT; | 2207 | return -ENOENT; |
2177 | 2208 | ||
2178 | bacpy(&rp.bdaddr, bdaddr); | 2209 | bacpy(&rp.bdaddr, bdaddr); |
2179 | rp.status = status; | 2210 | rp.status = status; |
2180 | 2211 | ||
2181 | err = cmd_complete(cmd->sk, index, MGMT_OP_PIN_CODE_NEG_REPLY, &rp, | 2212 | err = cmd_complete(cmd->sk, hdev->id, MGMT_OP_PIN_CODE_NEG_REPLY, &rp, |
2182 | sizeof(rp)); | 2213 | sizeof(rp)); |
2183 | 2214 | ||
2184 | mgmt_pending_remove(cmd); | 2215 | mgmt_pending_remove(cmd); |
@@ -2186,97 +2217,93 @@ int mgmt_pin_code_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status) | |||
2186 | return err; | 2217 | return err; |
2187 | } | 2218 | } |
2188 | 2219 | ||
2189 | int mgmt_user_confirm_request(u16 index, bdaddr_t *bdaddr, __le32 value, | 2220 | int mgmt_user_confirm_request(struct hci_dev *hdev, bdaddr_t *bdaddr, |
2190 | u8 confirm_hint) | 2221 | __le32 value, u8 confirm_hint) |
2191 | { | 2222 | { |
2192 | struct mgmt_ev_user_confirm_request ev; | 2223 | struct mgmt_ev_user_confirm_request ev; |
2193 | 2224 | ||
2194 | BT_DBG("hci%u", index); | 2225 | BT_DBG("%s", hdev->name); |
2195 | 2226 | ||
2196 | bacpy(&ev.bdaddr, bdaddr); | 2227 | bacpy(&ev.bdaddr, bdaddr); |
2197 | ev.confirm_hint = confirm_hint; | 2228 | ev.confirm_hint = confirm_hint; |
2198 | put_unaligned_le32(value, &ev.value); | 2229 | put_unaligned_le32(value, &ev.value); |
2199 | 2230 | ||
2200 | return mgmt_event(MGMT_EV_USER_CONFIRM_REQUEST, index, &ev, sizeof(ev), | 2231 | return mgmt_event(MGMT_EV_USER_CONFIRM_REQUEST, hdev, &ev, sizeof(ev), |
2201 | NULL); | 2232 | NULL); |
2202 | } | 2233 | } |
2203 | 2234 | ||
2204 | static int confirm_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status, | 2235 | static int confirm_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, |
2205 | u8 opcode) | 2236 | u8 status, u8 opcode) |
2206 | { | 2237 | { |
2207 | struct pending_cmd *cmd; | 2238 | struct pending_cmd *cmd; |
2208 | struct mgmt_rp_user_confirm_reply rp; | 2239 | struct mgmt_rp_user_confirm_reply rp; |
2209 | int err; | 2240 | int err; |
2210 | 2241 | ||
2211 | cmd = mgmt_pending_find(opcode, index); | 2242 | cmd = mgmt_pending_find(opcode, hdev); |
2212 | if (!cmd) | 2243 | if (!cmd) |
2213 | return -ENOENT; | 2244 | return -ENOENT; |
2214 | 2245 | ||
2215 | bacpy(&rp.bdaddr, bdaddr); | 2246 | bacpy(&rp.bdaddr, bdaddr); |
2216 | rp.status = status; | 2247 | rp.status = status; |
2217 | err = cmd_complete(cmd->sk, index, opcode, &rp, sizeof(rp)); | 2248 | err = cmd_complete(cmd->sk, hdev->id, opcode, &rp, sizeof(rp)); |
2218 | 2249 | ||
2219 | mgmt_pending_remove(cmd); | 2250 | mgmt_pending_remove(cmd); |
2220 | 2251 | ||
2221 | return err; | 2252 | return err; |
2222 | } | 2253 | } |
2223 | 2254 | ||
2224 | int mgmt_user_confirm_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status) | 2255 | int mgmt_user_confirm_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, |
2256 | u8 status) | ||
2225 | { | 2257 | { |
2226 | return confirm_reply_complete(index, bdaddr, status, | 2258 | return confirm_reply_complete(hdev, bdaddr, status, |
2227 | MGMT_OP_USER_CONFIRM_REPLY); | 2259 | MGMT_OP_USER_CONFIRM_REPLY); |
2228 | } | 2260 | } |
2229 | 2261 | ||
2230 | int mgmt_user_confirm_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status) | 2262 | int mgmt_user_confirm_neg_reply_complete(struct hci_dev *hdev, |
2263 | bdaddr_t *bdaddr, u8 status) | ||
2231 | { | 2264 | { |
2232 | return confirm_reply_complete(index, bdaddr, status, | 2265 | return confirm_reply_complete(hdev, bdaddr, status, |
2233 | MGMT_OP_USER_CONFIRM_NEG_REPLY); | 2266 | MGMT_OP_USER_CONFIRM_NEG_REPLY); |
2234 | } | 2267 | } |
2235 | 2268 | ||
2236 | int mgmt_auth_failed(u16 index, bdaddr_t *bdaddr, u8 status) | 2269 | int mgmt_auth_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 status) |
2237 | { | 2270 | { |
2238 | struct mgmt_ev_auth_failed ev; | 2271 | struct mgmt_ev_auth_failed ev; |
2239 | 2272 | ||
2240 | bacpy(&ev.bdaddr, bdaddr); | 2273 | bacpy(&ev.bdaddr, bdaddr); |
2241 | ev.status = status; | 2274 | ev.status = status; |
2242 | 2275 | ||
2243 | return mgmt_event(MGMT_EV_AUTH_FAILED, index, &ev, sizeof(ev), NULL); | 2276 | return mgmt_event(MGMT_EV_AUTH_FAILED, hdev, &ev, sizeof(ev), NULL); |
2244 | } | 2277 | } |
2245 | 2278 | ||
2246 | int mgmt_set_local_name_complete(u16 index, u8 *name, u8 status) | 2279 | int mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status) |
2247 | { | 2280 | { |
2248 | struct pending_cmd *cmd; | 2281 | struct pending_cmd *cmd; |
2249 | struct hci_dev *hdev; | ||
2250 | struct mgmt_cp_set_local_name ev; | 2282 | struct mgmt_cp_set_local_name ev; |
2251 | int err; | 2283 | int err; |
2252 | 2284 | ||
2253 | memset(&ev, 0, sizeof(ev)); | 2285 | memset(&ev, 0, sizeof(ev)); |
2254 | memcpy(ev.name, name, HCI_MAX_NAME_LENGTH); | 2286 | memcpy(ev.name, name, HCI_MAX_NAME_LENGTH); |
2255 | 2287 | ||
2256 | cmd = mgmt_pending_find(MGMT_OP_SET_LOCAL_NAME, index); | 2288 | cmd = mgmt_pending_find(MGMT_OP_SET_LOCAL_NAME, hdev); |
2257 | if (!cmd) | 2289 | if (!cmd) |
2258 | goto send_event; | 2290 | goto send_event; |
2259 | 2291 | ||
2260 | if (status) { | 2292 | if (status) { |
2261 | err = cmd_status(cmd->sk, index, MGMT_OP_SET_LOCAL_NAME, EIO); | 2293 | err = cmd_status(cmd->sk, hdev->id, MGMT_OP_SET_LOCAL_NAME, |
2294 | EIO); | ||
2262 | goto failed; | 2295 | goto failed; |
2263 | } | 2296 | } |
2264 | 2297 | ||
2265 | hdev = hci_dev_get(index); | 2298 | update_eir(hdev); |
2266 | if (hdev) { | ||
2267 | hci_dev_lock_bh(hdev); | ||
2268 | update_eir(hdev); | ||
2269 | hci_dev_unlock_bh(hdev); | ||
2270 | hci_dev_put(hdev); | ||
2271 | } | ||
2272 | 2299 | ||
2273 | err = cmd_complete(cmd->sk, index, MGMT_OP_SET_LOCAL_NAME, &ev, | 2300 | err = cmd_complete(cmd->sk, hdev->id, MGMT_OP_SET_LOCAL_NAME, &ev, |
2274 | sizeof(ev)); | 2301 | sizeof(ev)); |
2275 | if (err < 0) | 2302 | if (err < 0) |
2276 | goto failed; | 2303 | goto failed; |
2277 | 2304 | ||
2278 | send_event: | 2305 | send_event: |
2279 | err = mgmt_event(MGMT_EV_LOCAL_NAME_CHANGED, index, &ev, sizeof(ev), | 2306 | err = mgmt_event(MGMT_EV_LOCAL_NAME_CHANGED, hdev, &ev, sizeof(ev), |
2280 | cmd ? cmd->sk : NULL); | 2307 | cmd ? cmd->sk : NULL); |
2281 | 2308 | ||
2282 | failed: | 2309 | failed: |
@@ -2285,29 +2312,30 @@ failed: | |||
2285 | return err; | 2312 | return err; |
2286 | } | 2313 | } |
2287 | 2314 | ||
2288 | int mgmt_read_local_oob_data_reply_complete(u16 index, u8 *hash, u8 *randomizer, | 2315 | int mgmt_read_local_oob_data_reply_complete(struct hci_dev *hdev, u8 *hash, |
2289 | u8 status) | 2316 | u8 *randomizer, u8 status) |
2290 | { | 2317 | { |
2291 | struct pending_cmd *cmd; | 2318 | struct pending_cmd *cmd; |
2292 | int err; | 2319 | int err; |
2293 | 2320 | ||
2294 | BT_DBG("hci%u status %u", index, status); | 2321 | BT_DBG("%s status %u", hdev->name, status); |
2295 | 2322 | ||
2296 | cmd = mgmt_pending_find(MGMT_OP_READ_LOCAL_OOB_DATA, index); | 2323 | cmd = mgmt_pending_find(MGMT_OP_READ_LOCAL_OOB_DATA, hdev); |
2297 | if (!cmd) | 2324 | if (!cmd) |
2298 | return -ENOENT; | 2325 | return -ENOENT; |
2299 | 2326 | ||
2300 | if (status) { | 2327 | if (status) { |
2301 | err = cmd_status(cmd->sk, index, MGMT_OP_READ_LOCAL_OOB_DATA, | 2328 | err = cmd_status(cmd->sk, hdev->id, |
2302 | EIO); | 2329 | MGMT_OP_READ_LOCAL_OOB_DATA, EIO); |
2303 | } else { | 2330 | } else { |
2304 | struct mgmt_rp_read_local_oob_data rp; | 2331 | struct mgmt_rp_read_local_oob_data rp; |
2305 | 2332 | ||
2306 | memcpy(rp.hash, hash, sizeof(rp.hash)); | 2333 | memcpy(rp.hash, hash, sizeof(rp.hash)); |
2307 | memcpy(rp.randomizer, randomizer, sizeof(rp.randomizer)); | 2334 | memcpy(rp.randomizer, randomizer, sizeof(rp.randomizer)); |
2308 | 2335 | ||
2309 | err = cmd_complete(cmd->sk, index, MGMT_OP_READ_LOCAL_OOB_DATA, | 2336 | err = cmd_complete(cmd->sk, hdev->id, |
2310 | &rp, sizeof(rp)); | 2337 | MGMT_OP_READ_LOCAL_OOB_DATA, |
2338 | &rp, sizeof(rp)); | ||
2311 | } | 2339 | } |
2312 | 2340 | ||
2313 | mgmt_pending_remove(cmd); | 2341 | mgmt_pending_remove(cmd); |
@@ -2315,14 +2343,15 @@ int mgmt_read_local_oob_data_reply_complete(u16 index, u8 *hash, u8 *randomizer, | |||
2315 | return err; | 2343 | return err; |
2316 | } | 2344 | } |
2317 | 2345 | ||
2318 | int mgmt_device_found(u16 index, bdaddr_t *bdaddr, u8 *dev_class, s8 rssi, | 2346 | int mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type, |
2319 | u8 *eir) | 2347 | u8 *dev_class, s8 rssi, u8 *eir) |
2320 | { | 2348 | { |
2321 | struct mgmt_ev_device_found ev; | 2349 | struct mgmt_ev_device_found ev; |
2322 | 2350 | ||
2323 | memset(&ev, 0, sizeof(ev)); | 2351 | memset(&ev, 0, sizeof(ev)); |
2324 | 2352 | ||
2325 | bacpy(&ev.bdaddr, bdaddr); | 2353 | bacpy(&ev.addr.bdaddr, bdaddr); |
2354 | ev.addr.type = link_to_mgmt(type); | ||
2326 | ev.rssi = rssi; | 2355 | ev.rssi = rssi; |
2327 | 2356 | ||
2328 | if (eir) | 2357 | if (eir) |
@@ -2331,10 +2360,10 @@ int mgmt_device_found(u16 index, bdaddr_t *bdaddr, u8 *dev_class, s8 rssi, | |||
2331 | if (dev_class) | 2360 | if (dev_class) |
2332 | memcpy(ev.dev_class, dev_class, sizeof(ev.dev_class)); | 2361 | memcpy(ev.dev_class, dev_class, sizeof(ev.dev_class)); |
2333 | 2362 | ||
2334 | return mgmt_event(MGMT_EV_DEVICE_FOUND, index, &ev, sizeof(ev), NULL); | 2363 | return mgmt_event(MGMT_EV_DEVICE_FOUND, hdev, &ev, sizeof(ev), NULL); |
2335 | } | 2364 | } |
2336 | 2365 | ||
2337 | int mgmt_remote_name(u16 index, bdaddr_t *bdaddr, u8 *name) | 2366 | int mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *name) |
2338 | { | 2367 | { |
2339 | struct mgmt_ev_remote_name ev; | 2368 | struct mgmt_ev_remote_name ev; |
2340 | 2369 | ||
@@ -2343,37 +2372,64 @@ int mgmt_remote_name(u16 index, bdaddr_t *bdaddr, u8 *name) | |||
2343 | bacpy(&ev.bdaddr, bdaddr); | 2372 | bacpy(&ev.bdaddr, bdaddr); |
2344 | memcpy(ev.name, name, HCI_MAX_NAME_LENGTH); | 2373 | memcpy(ev.name, name, HCI_MAX_NAME_LENGTH); |
2345 | 2374 | ||
2346 | return mgmt_event(MGMT_EV_REMOTE_NAME, index, &ev, sizeof(ev), NULL); | 2375 | return mgmt_event(MGMT_EV_REMOTE_NAME, hdev, &ev, sizeof(ev), NULL); |
2347 | } | 2376 | } |
2348 | 2377 | ||
2349 | int mgmt_discovering(u16 index, u8 discovering) | 2378 | int mgmt_inquiry_failed(struct hci_dev *hdev, u8 status) |
2350 | { | 2379 | { |
2351 | return mgmt_event(MGMT_EV_DISCOVERING, index, &discovering, | 2380 | struct pending_cmd *cmd; |
2381 | int err; | ||
2382 | |||
2383 | cmd = mgmt_pending_find(MGMT_OP_START_DISCOVERY, hdev); | ||
2384 | if (!cmd) | ||
2385 | return -ENOENT; | ||
2386 | |||
2387 | err = cmd_status(cmd->sk, hdev->id, cmd->opcode, status); | ||
2388 | mgmt_pending_remove(cmd); | ||
2389 | |||
2390 | return err; | ||
2391 | } | ||
2392 | |||
2393 | int mgmt_discovering(struct hci_dev *hdev, u8 discovering) | ||
2394 | { | ||
2395 | struct pending_cmd *cmd; | ||
2396 | |||
2397 | if (discovering) | ||
2398 | cmd = mgmt_pending_find(MGMT_OP_START_DISCOVERY, hdev); | ||
2399 | else | ||
2400 | cmd = mgmt_pending_find(MGMT_OP_STOP_DISCOVERY, hdev); | ||
2401 | |||
2402 | if (cmd != NULL) { | ||
2403 | cmd_complete(cmd->sk, hdev->id, cmd->opcode, NULL, 0); | ||
2404 | mgmt_pending_remove(cmd); | ||
2405 | } | ||
2406 | |||
2407 | return mgmt_event(MGMT_EV_DISCOVERING, hdev, &discovering, | ||
2352 | sizeof(discovering), NULL); | 2408 | sizeof(discovering), NULL); |
2353 | } | 2409 | } |
2354 | 2410 | ||
2355 | int mgmt_device_blocked(u16 index, bdaddr_t *bdaddr) | 2411 | int mgmt_device_blocked(struct hci_dev *hdev, bdaddr_t *bdaddr) |
2356 | { | 2412 | { |
2357 | struct pending_cmd *cmd; | 2413 | struct pending_cmd *cmd; |
2358 | struct mgmt_ev_device_blocked ev; | 2414 | struct mgmt_ev_device_blocked ev; |
2359 | 2415 | ||
2360 | cmd = mgmt_pending_find(MGMT_OP_BLOCK_DEVICE, index); | 2416 | cmd = mgmt_pending_find(MGMT_OP_BLOCK_DEVICE, hdev); |
2361 | 2417 | ||
2362 | bacpy(&ev.bdaddr, bdaddr); | 2418 | bacpy(&ev.bdaddr, bdaddr); |
2363 | 2419 | ||
2364 | return mgmt_event(MGMT_EV_DEVICE_BLOCKED, index, &ev, sizeof(ev), | 2420 | return mgmt_event(MGMT_EV_DEVICE_BLOCKED, hdev, &ev, sizeof(ev), |
2365 | cmd ? cmd->sk : NULL); | 2421 | cmd ? cmd->sk : NULL); |
2366 | } | 2422 | } |
2367 | 2423 | ||
2368 | int mgmt_device_unblocked(u16 index, bdaddr_t *bdaddr) | 2424 | int mgmt_device_unblocked(struct hci_dev *hdev, bdaddr_t *bdaddr) |
2369 | { | 2425 | { |
2370 | struct pending_cmd *cmd; | 2426 | struct pending_cmd *cmd; |
2371 | struct mgmt_ev_device_unblocked ev; | 2427 | struct mgmt_ev_device_unblocked ev; |
2372 | 2428 | ||
2373 | cmd = mgmt_pending_find(MGMT_OP_UNBLOCK_DEVICE, index); | 2429 | cmd = mgmt_pending_find(MGMT_OP_UNBLOCK_DEVICE, hdev); |
2374 | 2430 | ||
2375 | bacpy(&ev.bdaddr, bdaddr); | 2431 | bacpy(&ev.bdaddr, bdaddr); |
2376 | 2432 | ||
2377 | return mgmt_event(MGMT_EV_DEVICE_UNBLOCKED, index, &ev, sizeof(ev), | 2433 | return mgmt_event(MGMT_EV_DEVICE_UNBLOCKED, hdev, &ev, sizeof(ev), |
2378 | cmd ? cmd->sk : NULL); | 2434 | cmd ? cmd->sk : NULL); |
2379 | } | 2435 | } |
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index 4e32e18211f9..8743f369ed3f 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c | |||
@@ -65,7 +65,8 @@ static DEFINE_MUTEX(rfcomm_mutex); | |||
65 | 65 | ||
66 | static LIST_HEAD(session_list); | 66 | static LIST_HEAD(session_list); |
67 | 67 | ||
68 | static int rfcomm_send_frame(struct rfcomm_session *s, u8 *data, int len); | 68 | static int rfcomm_send_frame(struct rfcomm_session *s, u8 *data, int len, |
69 | u32 priority); | ||
69 | static int rfcomm_send_sabm(struct rfcomm_session *s, u8 dlci); | 70 | static int rfcomm_send_sabm(struct rfcomm_session *s, u8 dlci); |
70 | static int rfcomm_send_disc(struct rfcomm_session *s, u8 dlci); | 71 | static int rfcomm_send_disc(struct rfcomm_session *s, u8 dlci); |
71 | static int rfcomm_queue_disc(struct rfcomm_dlc *d); | 72 | static int rfcomm_queue_disc(struct rfcomm_dlc *d); |
@@ -377,13 +378,11 @@ static void rfcomm_dlc_unlink(struct rfcomm_dlc *d) | |||
377 | static struct rfcomm_dlc *rfcomm_dlc_get(struct rfcomm_session *s, u8 dlci) | 378 | static struct rfcomm_dlc *rfcomm_dlc_get(struct rfcomm_session *s, u8 dlci) |
378 | { | 379 | { |
379 | struct rfcomm_dlc *d; | 380 | struct rfcomm_dlc *d; |
380 | struct list_head *p; | ||
381 | 381 | ||
382 | list_for_each(p, &s->dlcs) { | 382 | list_for_each_entry(d, &s->dlcs, list) |
383 | d = list_entry(p, struct rfcomm_dlc, list); | ||
384 | if (d->dlci == dlci) | 383 | if (d->dlci == dlci) |
385 | return d; | 384 | return d; |
386 | } | 385 | |
387 | return NULL; | 386 | return NULL; |
388 | } | 387 | } |
389 | 388 | ||
@@ -749,19 +748,34 @@ void rfcomm_session_getaddr(struct rfcomm_session *s, bdaddr_t *src, bdaddr_t *d | |||
749 | } | 748 | } |
750 | 749 | ||
751 | /* ---- RFCOMM frame sending ---- */ | 750 | /* ---- RFCOMM frame sending ---- */ |
752 | static int rfcomm_send_frame(struct rfcomm_session *s, u8 *data, int len) | 751 | static int rfcomm_send_frame(struct rfcomm_session *s, u8 *data, int len, |
752 | u32 priority) | ||
753 | { | 753 | { |
754 | struct socket *sock = s->sock; | 754 | struct socket *sock = s->sock; |
755 | struct sock *sk = sock->sk; | ||
755 | struct kvec iv = { data, len }; | 756 | struct kvec iv = { data, len }; |
756 | struct msghdr msg; | 757 | struct msghdr msg; |
757 | 758 | ||
758 | BT_DBG("session %p len %d", s, len); | 759 | BT_DBG("session %p len %d priority %u", s, len, priority); |
760 | |||
761 | if (sk->sk_priority != priority) { | ||
762 | lock_sock(sk); | ||
763 | sk->sk_priority = priority; | ||
764 | release_sock(sk); | ||
765 | } | ||
759 | 766 | ||
760 | memset(&msg, 0, sizeof(msg)); | 767 | memset(&msg, 0, sizeof(msg)); |
761 | 768 | ||
762 | return kernel_sendmsg(sock, &msg, &iv, 1, len); | 769 | return kernel_sendmsg(sock, &msg, &iv, 1, len); |
763 | } | 770 | } |
764 | 771 | ||
772 | static int rfcomm_send_cmd(struct rfcomm_session *s, struct rfcomm_cmd *cmd) | ||
773 | { | ||
774 | BT_DBG("%p cmd %u", s, cmd->ctrl); | ||
775 | |||
776 | return rfcomm_send_frame(s, (void *) cmd, sizeof(*cmd), HCI_PRIO_MAX); | ||
777 | } | ||
778 | |||
765 | static int rfcomm_send_sabm(struct rfcomm_session *s, u8 dlci) | 779 | static int rfcomm_send_sabm(struct rfcomm_session *s, u8 dlci) |
766 | { | 780 | { |
767 | struct rfcomm_cmd cmd; | 781 | struct rfcomm_cmd cmd; |
@@ -773,7 +787,7 @@ static int rfcomm_send_sabm(struct rfcomm_session *s, u8 dlci) | |||
773 | cmd.len = __len8(0); | 787 | cmd.len = __len8(0); |
774 | cmd.fcs = __fcs2((u8 *) &cmd); | 788 | cmd.fcs = __fcs2((u8 *) &cmd); |
775 | 789 | ||
776 | return rfcomm_send_frame(s, (void *) &cmd, sizeof(cmd)); | 790 | return rfcomm_send_cmd(s, &cmd); |
777 | } | 791 | } |
778 | 792 | ||
779 | static int rfcomm_send_ua(struct rfcomm_session *s, u8 dlci) | 793 | static int rfcomm_send_ua(struct rfcomm_session *s, u8 dlci) |
@@ -787,7 +801,7 @@ static int rfcomm_send_ua(struct rfcomm_session *s, u8 dlci) | |||
787 | cmd.len = __len8(0); | 801 | cmd.len = __len8(0); |
788 | cmd.fcs = __fcs2((u8 *) &cmd); | 802 | cmd.fcs = __fcs2((u8 *) &cmd); |
789 | 803 | ||
790 | return rfcomm_send_frame(s, (void *) &cmd, sizeof(cmd)); | 804 | return rfcomm_send_cmd(s, &cmd); |
791 | } | 805 | } |
792 | 806 | ||
793 | static int rfcomm_send_disc(struct rfcomm_session *s, u8 dlci) | 807 | static int rfcomm_send_disc(struct rfcomm_session *s, u8 dlci) |
@@ -801,7 +815,7 @@ static int rfcomm_send_disc(struct rfcomm_session *s, u8 dlci) | |||
801 | cmd.len = __len8(0); | 815 | cmd.len = __len8(0); |
802 | cmd.fcs = __fcs2((u8 *) &cmd); | 816 | cmd.fcs = __fcs2((u8 *) &cmd); |
803 | 817 | ||
804 | return rfcomm_send_frame(s, (void *) &cmd, sizeof(cmd)); | 818 | return rfcomm_send_cmd(s, &cmd); |
805 | } | 819 | } |
806 | 820 | ||
807 | static int rfcomm_queue_disc(struct rfcomm_dlc *d) | 821 | static int rfcomm_queue_disc(struct rfcomm_dlc *d) |
@@ -815,6 +829,8 @@ static int rfcomm_queue_disc(struct rfcomm_dlc *d) | |||
815 | if (!skb) | 829 | if (!skb) |
816 | return -ENOMEM; | 830 | return -ENOMEM; |
817 | 831 | ||
832 | skb->priority = HCI_PRIO_MAX; | ||
833 | |||
818 | cmd = (void *) __skb_put(skb, sizeof(*cmd)); | 834 | cmd = (void *) __skb_put(skb, sizeof(*cmd)); |
819 | cmd->addr = d->addr; | 835 | cmd->addr = d->addr; |
820 | cmd->ctrl = __ctrl(RFCOMM_DISC, 1); | 836 | cmd->ctrl = __ctrl(RFCOMM_DISC, 1); |
@@ -837,7 +853,7 @@ static int rfcomm_send_dm(struct rfcomm_session *s, u8 dlci) | |||
837 | cmd.len = __len8(0); | 853 | cmd.len = __len8(0); |
838 | cmd.fcs = __fcs2((u8 *) &cmd); | 854 | cmd.fcs = __fcs2((u8 *) &cmd); |
839 | 855 | ||
840 | return rfcomm_send_frame(s, (void *) &cmd, sizeof(cmd)); | 856 | return rfcomm_send_cmd(s, &cmd); |
841 | } | 857 | } |
842 | 858 | ||
843 | static int rfcomm_send_nsc(struct rfcomm_session *s, int cr, u8 type) | 859 | static int rfcomm_send_nsc(struct rfcomm_session *s, int cr, u8 type) |
@@ -862,7 +878,7 @@ static int rfcomm_send_nsc(struct rfcomm_session *s, int cr, u8 type) | |||
862 | 878 | ||
863 | *ptr = __fcs(buf); ptr++; | 879 | *ptr = __fcs(buf); ptr++; |
864 | 880 | ||
865 | return rfcomm_send_frame(s, buf, ptr - buf); | 881 | return rfcomm_send_frame(s, buf, ptr - buf, HCI_PRIO_MAX); |
866 | } | 882 | } |
867 | 883 | ||
868 | static int rfcomm_send_pn(struct rfcomm_session *s, int cr, struct rfcomm_dlc *d) | 884 | static int rfcomm_send_pn(struct rfcomm_session *s, int cr, struct rfcomm_dlc *d) |
@@ -904,7 +920,7 @@ static int rfcomm_send_pn(struct rfcomm_session *s, int cr, struct rfcomm_dlc *d | |||
904 | 920 | ||
905 | *ptr = __fcs(buf); ptr++; | 921 | *ptr = __fcs(buf); ptr++; |
906 | 922 | ||
907 | return rfcomm_send_frame(s, buf, ptr - buf); | 923 | return rfcomm_send_frame(s, buf, ptr - buf, HCI_PRIO_MAX); |
908 | } | 924 | } |
909 | 925 | ||
910 | int rfcomm_send_rpn(struct rfcomm_session *s, int cr, u8 dlci, | 926 | int rfcomm_send_rpn(struct rfcomm_session *s, int cr, u8 dlci, |
@@ -942,7 +958,7 @@ int rfcomm_send_rpn(struct rfcomm_session *s, int cr, u8 dlci, | |||
942 | 958 | ||
943 | *ptr = __fcs(buf); ptr++; | 959 | *ptr = __fcs(buf); ptr++; |
944 | 960 | ||
945 | return rfcomm_send_frame(s, buf, ptr - buf); | 961 | return rfcomm_send_frame(s, buf, ptr - buf, HCI_PRIO_MAX); |
946 | } | 962 | } |
947 | 963 | ||
948 | static int rfcomm_send_rls(struct rfcomm_session *s, int cr, u8 dlci, u8 status) | 964 | static int rfcomm_send_rls(struct rfcomm_session *s, int cr, u8 dlci, u8 status) |
@@ -969,7 +985,7 @@ static int rfcomm_send_rls(struct rfcomm_session *s, int cr, u8 dlci, u8 status) | |||
969 | 985 | ||
970 | *ptr = __fcs(buf); ptr++; | 986 | *ptr = __fcs(buf); ptr++; |
971 | 987 | ||
972 | return rfcomm_send_frame(s, buf, ptr - buf); | 988 | return rfcomm_send_frame(s, buf, ptr - buf, HCI_PRIO_MAX); |
973 | } | 989 | } |
974 | 990 | ||
975 | static int rfcomm_send_msc(struct rfcomm_session *s, int cr, u8 dlci, u8 v24_sig) | 991 | static int rfcomm_send_msc(struct rfcomm_session *s, int cr, u8 dlci, u8 v24_sig) |
@@ -996,7 +1012,7 @@ static int rfcomm_send_msc(struct rfcomm_session *s, int cr, u8 dlci, u8 v24_sig | |||
996 | 1012 | ||
997 | *ptr = __fcs(buf); ptr++; | 1013 | *ptr = __fcs(buf); ptr++; |
998 | 1014 | ||
999 | return rfcomm_send_frame(s, buf, ptr - buf); | 1015 | return rfcomm_send_frame(s, buf, ptr - buf, HCI_PRIO_MAX); |
1000 | } | 1016 | } |
1001 | 1017 | ||
1002 | static int rfcomm_send_fcoff(struct rfcomm_session *s, int cr) | 1018 | static int rfcomm_send_fcoff(struct rfcomm_session *s, int cr) |
@@ -1018,7 +1034,7 @@ static int rfcomm_send_fcoff(struct rfcomm_session *s, int cr) | |||
1018 | 1034 | ||
1019 | *ptr = __fcs(buf); ptr++; | 1035 | *ptr = __fcs(buf); ptr++; |
1020 | 1036 | ||
1021 | return rfcomm_send_frame(s, buf, ptr - buf); | 1037 | return rfcomm_send_frame(s, buf, ptr - buf, HCI_PRIO_MAX); |
1022 | } | 1038 | } |
1023 | 1039 | ||
1024 | static int rfcomm_send_fcon(struct rfcomm_session *s, int cr) | 1040 | static int rfcomm_send_fcon(struct rfcomm_session *s, int cr) |
@@ -1040,7 +1056,7 @@ static int rfcomm_send_fcon(struct rfcomm_session *s, int cr) | |||
1040 | 1056 | ||
1041 | *ptr = __fcs(buf); ptr++; | 1057 | *ptr = __fcs(buf); ptr++; |
1042 | 1058 | ||
1043 | return rfcomm_send_frame(s, buf, ptr - buf); | 1059 | return rfcomm_send_frame(s, buf, ptr - buf, HCI_PRIO_MAX); |
1044 | } | 1060 | } |
1045 | 1061 | ||
1046 | static int rfcomm_send_test(struct rfcomm_session *s, int cr, u8 *pattern, int len) | 1062 | static int rfcomm_send_test(struct rfcomm_session *s, int cr, u8 *pattern, int len) |
@@ -1091,7 +1107,7 @@ static int rfcomm_send_credits(struct rfcomm_session *s, u8 addr, u8 credits) | |||
1091 | 1107 | ||
1092 | *ptr = __fcs(buf); ptr++; | 1108 | *ptr = __fcs(buf); ptr++; |
1093 | 1109 | ||
1094 | return rfcomm_send_frame(s, buf, ptr - buf); | 1110 | return rfcomm_send_frame(s, buf, ptr - buf, HCI_PRIO_MAX); |
1095 | } | 1111 | } |
1096 | 1112 | ||
1097 | static void rfcomm_make_uih(struct sk_buff *skb, u8 addr) | 1113 | static void rfcomm_make_uih(struct sk_buff *skb, u8 addr) |
@@ -1769,7 +1785,8 @@ static inline int rfcomm_process_tx(struct rfcomm_dlc *d) | |||
1769 | return skb_queue_len(&d->tx_queue); | 1785 | return skb_queue_len(&d->tx_queue); |
1770 | 1786 | ||
1771 | while (d->tx_credits && (skb = skb_dequeue(&d->tx_queue))) { | 1787 | while (d->tx_credits && (skb = skb_dequeue(&d->tx_queue))) { |
1772 | err = rfcomm_send_frame(d->session, skb->data, skb->len); | 1788 | err = rfcomm_send_frame(d->session, skb->data, skb->len, |
1789 | skb->priority); | ||
1773 | if (err < 0) { | 1790 | if (err < 0) { |
1774 | skb_queue_head(&d->tx_queue, skb); | 1791 | skb_queue_head(&d->tx_queue, skb); |
1775 | break; | 1792 | break; |
@@ -2120,15 +2137,13 @@ static struct hci_cb rfcomm_cb = { | |||
2120 | static int rfcomm_dlc_debugfs_show(struct seq_file *f, void *x) | 2137 | static int rfcomm_dlc_debugfs_show(struct seq_file *f, void *x) |
2121 | { | 2138 | { |
2122 | struct rfcomm_session *s; | 2139 | struct rfcomm_session *s; |
2123 | struct list_head *pp, *p; | ||
2124 | 2140 | ||
2125 | rfcomm_lock(); | 2141 | rfcomm_lock(); |
2126 | 2142 | ||
2127 | list_for_each(p, &session_list) { | 2143 | list_for_each_entry(s, &session_list, list) { |
2128 | s = list_entry(p, struct rfcomm_session, list); | 2144 | struct rfcomm_dlc *d; |
2129 | list_for_each(pp, &s->dlcs) { | 2145 | list_for_each_entry(d, &s->dlcs, list) { |
2130 | struct sock *sk = s->sock->sk; | 2146 | struct sock *sk = s->sock->sk; |
2131 | struct rfcomm_dlc *d = list_entry(pp, struct rfcomm_dlc, list); | ||
2132 | 2147 | ||
2133 | seq_printf(f, "%s %s %ld %d %d %d %d\n", | 2148 | seq_printf(f, "%s %s %ld %d %d %d %d\n", |
2134 | batostr(&bt_sk(sk)->src), | 2149 | batostr(&bt_sk(sk)->src), |
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index 5417f6127323..aea2bdd1510f 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c | |||
@@ -600,6 +600,8 @@ static int rfcomm_sock_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
600 | break; | 600 | break; |
601 | } | 601 | } |
602 | 602 | ||
603 | skb->priority = sk->sk_priority; | ||
604 | |||
603 | err = rfcomm_dlc_send(d, skb); | 605 | err = rfcomm_dlc_send(d, skb); |
604 | if (err < 0) { | 606 | if (err < 0) { |
605 | kfree_skb(skb); | 607 | kfree_skb(skb); |
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c index c258796313e0..fa8f4de53b99 100644 --- a/net/bluetooth/rfcomm/tty.c +++ b/net/bluetooth/rfcomm/tty.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/capability.h> | 34 | #include <linux/capability.h> |
35 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
36 | #include <linux/skbuff.h> | 36 | #include <linux/skbuff.h> |
37 | #include <linux/workqueue.h> | ||
37 | 38 | ||
38 | #include <net/bluetooth/bluetooth.h> | 39 | #include <net/bluetooth/bluetooth.h> |
39 | #include <net/bluetooth/hci_core.h> | 40 | #include <net/bluetooth/hci_core.h> |
@@ -65,7 +66,7 @@ struct rfcomm_dev { | |||
65 | struct rfcomm_dlc *dlc; | 66 | struct rfcomm_dlc *dlc; |
66 | struct tty_struct *tty; | 67 | struct tty_struct *tty; |
67 | wait_queue_head_t wait; | 68 | wait_queue_head_t wait; |
68 | struct tasklet_struct wakeup_task; | 69 | struct work_struct wakeup_task; |
69 | 70 | ||
70 | struct device *tty_dev; | 71 | struct device *tty_dev; |
71 | 72 | ||
@@ -81,7 +82,7 @@ static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb); | |||
81 | static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err); | 82 | static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err); |
82 | static void rfcomm_dev_modem_status(struct rfcomm_dlc *dlc, u8 v24_sig); | 83 | static void rfcomm_dev_modem_status(struct rfcomm_dlc *dlc, u8 v24_sig); |
83 | 84 | ||
84 | static void rfcomm_tty_wakeup(unsigned long arg); | 85 | static void rfcomm_tty_wakeup(struct work_struct *work); |
85 | 86 | ||
86 | /* ---- Device functions ---- */ | 87 | /* ---- Device functions ---- */ |
87 | static void rfcomm_dev_destruct(struct rfcomm_dev *dev) | 88 | static void rfcomm_dev_destruct(struct rfcomm_dev *dev) |
@@ -133,13 +134,10 @@ static inline void rfcomm_dev_put(struct rfcomm_dev *dev) | |||
133 | static struct rfcomm_dev *__rfcomm_dev_get(int id) | 134 | static struct rfcomm_dev *__rfcomm_dev_get(int id) |
134 | { | 135 | { |
135 | struct rfcomm_dev *dev; | 136 | struct rfcomm_dev *dev; |
136 | struct list_head *p; | ||
137 | 137 | ||
138 | list_for_each(p, &rfcomm_dev_list) { | 138 | list_for_each_entry(dev, &rfcomm_dev_list, list) |
139 | dev = list_entry(p, struct rfcomm_dev, list); | ||
140 | if (dev->id == id) | 139 | if (dev->id == id) |
141 | return dev; | 140 | return dev; |
142 | } | ||
143 | 141 | ||
144 | return NULL; | 142 | return NULL; |
145 | } | 143 | } |
@@ -197,7 +195,7 @@ static DEVICE_ATTR(channel, S_IRUGO, show_channel, NULL); | |||
197 | 195 | ||
198 | static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc) | 196 | static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc) |
199 | { | 197 | { |
200 | struct rfcomm_dev *dev; | 198 | struct rfcomm_dev *dev, *entry; |
201 | struct list_head *head = &rfcomm_dev_list, *p; | 199 | struct list_head *head = &rfcomm_dev_list, *p; |
202 | int err = 0; | 200 | int err = 0; |
203 | 201 | ||
@@ -212,8 +210,8 @@ static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc) | |||
212 | if (req->dev_id < 0) { | 210 | if (req->dev_id < 0) { |
213 | dev->id = 0; | 211 | dev->id = 0; |
214 | 212 | ||
215 | list_for_each(p, &rfcomm_dev_list) { | 213 | list_for_each_entry(entry, &rfcomm_dev_list, list) { |
216 | if (list_entry(p, struct rfcomm_dev, list)->id != dev->id) | 214 | if (entry->id != dev->id) |
217 | break; | 215 | break; |
218 | 216 | ||
219 | dev->id++; | 217 | dev->id++; |
@@ -222,9 +220,7 @@ static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc) | |||
222 | } else { | 220 | } else { |
223 | dev->id = req->dev_id; | 221 | dev->id = req->dev_id; |
224 | 222 | ||
225 | list_for_each(p, &rfcomm_dev_list) { | 223 | list_for_each_entry(entry, &rfcomm_dev_list, list) { |
226 | struct rfcomm_dev *entry = list_entry(p, struct rfcomm_dev, list); | ||
227 | |||
228 | if (entry->id == dev->id) { | 224 | if (entry->id == dev->id) { |
229 | err = -EADDRINUSE; | 225 | err = -EADDRINUSE; |
230 | goto out; | 226 | goto out; |
@@ -257,7 +253,7 @@ static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc) | |||
257 | atomic_set(&dev->opened, 0); | 253 | atomic_set(&dev->opened, 0); |
258 | 254 | ||
259 | init_waitqueue_head(&dev->wait); | 255 | init_waitqueue_head(&dev->wait); |
260 | tasklet_init(&dev->wakeup_task, rfcomm_tty_wakeup, (unsigned long) dev); | 256 | INIT_WORK(&dev->wakeup_task, rfcomm_tty_wakeup); |
261 | 257 | ||
262 | skb_queue_head_init(&dev->pending); | 258 | skb_queue_head_init(&dev->pending); |
263 | 259 | ||
@@ -351,7 +347,7 @@ static void rfcomm_wfree(struct sk_buff *skb) | |||
351 | struct rfcomm_dev *dev = (void *) skb->sk; | 347 | struct rfcomm_dev *dev = (void *) skb->sk; |
352 | atomic_sub(skb->truesize, &dev->wmem_alloc); | 348 | atomic_sub(skb->truesize, &dev->wmem_alloc); |
353 | if (test_bit(RFCOMM_TTY_ATTACHED, &dev->flags)) | 349 | if (test_bit(RFCOMM_TTY_ATTACHED, &dev->flags)) |
354 | tasklet_schedule(&dev->wakeup_task); | 350 | queue_work(system_nrt_wq, &dev->wakeup_task); |
355 | rfcomm_dev_put(dev); | 351 | rfcomm_dev_put(dev); |
356 | } | 352 | } |
357 | 353 | ||
@@ -455,9 +451,9 @@ static int rfcomm_release_dev(void __user *arg) | |||
455 | 451 | ||
456 | static int rfcomm_get_dev_list(void __user *arg) | 452 | static int rfcomm_get_dev_list(void __user *arg) |
457 | { | 453 | { |
454 | struct rfcomm_dev *dev; | ||
458 | struct rfcomm_dev_list_req *dl; | 455 | struct rfcomm_dev_list_req *dl; |
459 | struct rfcomm_dev_info *di; | 456 | struct rfcomm_dev_info *di; |
460 | struct list_head *p; | ||
461 | int n = 0, size, err; | 457 | int n = 0, size, err; |
462 | u16 dev_num; | 458 | u16 dev_num; |
463 | 459 | ||
@@ -479,8 +475,7 @@ static int rfcomm_get_dev_list(void __user *arg) | |||
479 | 475 | ||
480 | read_lock_bh(&rfcomm_dev_lock); | 476 | read_lock_bh(&rfcomm_dev_lock); |
481 | 477 | ||
482 | list_for_each(p, &rfcomm_dev_list) { | 478 | list_for_each_entry(dev, &rfcomm_dev_list, list) { |
483 | struct rfcomm_dev *dev = list_entry(p, struct rfcomm_dev, list); | ||
484 | if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags)) | 479 | if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags)) |
485 | continue; | 480 | continue; |
486 | (di + n)->id = dev->id; | 481 | (di + n)->id = dev->id; |
@@ -635,9 +630,10 @@ static void rfcomm_dev_modem_status(struct rfcomm_dlc *dlc, u8 v24_sig) | |||
635 | } | 630 | } |
636 | 631 | ||
637 | /* ---- TTY functions ---- */ | 632 | /* ---- TTY functions ---- */ |
638 | static void rfcomm_tty_wakeup(unsigned long arg) | 633 | static void rfcomm_tty_wakeup(struct work_struct *work) |
639 | { | 634 | { |
640 | struct rfcomm_dev *dev = (void *) arg; | 635 | struct rfcomm_dev *dev = container_of(work, struct rfcomm_dev, |
636 | wakeup_task); | ||
641 | struct tty_struct *tty = dev->tty; | 637 | struct tty_struct *tty = dev->tty; |
642 | if (!tty) | 638 | if (!tty) |
643 | return; | 639 | return; |
@@ -762,7 +758,7 @@ static void rfcomm_tty_close(struct tty_struct *tty, struct file *filp) | |||
762 | rfcomm_dlc_close(dev->dlc, 0); | 758 | rfcomm_dlc_close(dev->dlc, 0); |
763 | 759 | ||
764 | clear_bit(RFCOMM_TTY_ATTACHED, &dev->flags); | 760 | clear_bit(RFCOMM_TTY_ATTACHED, &dev->flags); |
765 | tasklet_kill(&dev->wakeup_task); | 761 | cancel_work_sync(&dev->wakeup_task); |
766 | 762 | ||
767 | rfcomm_dlc_lock(dev->dlc); | 763 | rfcomm_dlc_lock(dev->dlc); |
768 | tty->driver_data = NULL; | 764 | tty->driver_data = NULL; |
@@ -1155,9 +1151,11 @@ static const struct tty_operations rfcomm_ops = { | |||
1155 | 1151 | ||
1156 | int __init rfcomm_init_ttys(void) | 1152 | int __init rfcomm_init_ttys(void) |
1157 | { | 1153 | { |
1154 | int error; | ||
1155 | |||
1158 | rfcomm_tty_driver = alloc_tty_driver(RFCOMM_TTY_PORTS); | 1156 | rfcomm_tty_driver = alloc_tty_driver(RFCOMM_TTY_PORTS); |
1159 | if (!rfcomm_tty_driver) | 1157 | if (!rfcomm_tty_driver) |
1160 | return -1; | 1158 | return -ENOMEM; |
1161 | 1159 | ||
1162 | rfcomm_tty_driver->owner = THIS_MODULE; | 1160 | rfcomm_tty_driver->owner = THIS_MODULE; |
1163 | rfcomm_tty_driver->driver_name = "rfcomm"; | 1161 | rfcomm_tty_driver->driver_name = "rfcomm"; |
@@ -1172,10 +1170,11 @@ int __init rfcomm_init_ttys(void) | |||
1172 | rfcomm_tty_driver->init_termios.c_lflag &= ~ICANON; | 1170 | rfcomm_tty_driver->init_termios.c_lflag &= ~ICANON; |
1173 | tty_set_operations(rfcomm_tty_driver, &rfcomm_ops); | 1171 | tty_set_operations(rfcomm_tty_driver, &rfcomm_ops); |
1174 | 1172 | ||
1175 | if (tty_register_driver(rfcomm_tty_driver)) { | 1173 | error = tty_register_driver(rfcomm_tty_driver); |
1174 | if (error) { | ||
1176 | BT_ERR("Can't register RFCOMM TTY driver"); | 1175 | BT_ERR("Can't register RFCOMM TTY driver"); |
1177 | put_tty_driver(rfcomm_tty_driver); | 1176 | put_tty_driver(rfcomm_tty_driver); |
1178 | return -1; | 1177 | return error; |
1179 | } | 1178 | } |
1180 | 1179 | ||
1181 | BT_INFO("RFCOMM TTY layer initialized"); | 1180 | BT_INFO("RFCOMM TTY layer initialized"); |
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 759b63572641..94e94ca35384 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c | |||
@@ -181,7 +181,8 @@ static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data) | |||
181 | if (!skb) | 181 | if (!skb) |
182 | return; | 182 | return; |
183 | 183 | ||
184 | hci_send_acl(conn->hcon, skb, 0); | 184 | skb->priority = HCI_PRIO_MAX; |
185 | hci_send_acl(conn->hchan, skb, 0); | ||
185 | 186 | ||
186 | mod_timer(&conn->security_timer, jiffies + | 187 | mod_timer(&conn->security_timer, jiffies + |
187 | msecs_to_jiffies(SMP_TIMEOUT)); | 188 | msecs_to_jiffies(SMP_TIMEOUT)); |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index cbc003b2914a..7dc05ecf040a 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -3218,6 +3218,26 @@ void skb_tstamp_tx(struct sk_buff *orig_skb, | |||
3218 | } | 3218 | } |
3219 | EXPORT_SYMBOL_GPL(skb_tstamp_tx); | 3219 | EXPORT_SYMBOL_GPL(skb_tstamp_tx); |
3220 | 3220 | ||
3221 | void skb_complete_wifi_ack(struct sk_buff *skb, bool acked) | ||
3222 | { | ||
3223 | struct sock *sk = skb->sk; | ||
3224 | struct sock_exterr_skb *serr; | ||
3225 | int err; | ||
3226 | |||
3227 | skb->wifi_acked_valid = 1; | ||
3228 | skb->wifi_acked = acked; | ||
3229 | |||
3230 | serr = SKB_EXT_ERR(skb); | ||
3231 | memset(serr, 0, sizeof(*serr)); | ||
3232 | serr->ee.ee_errno = ENOMSG; | ||
3233 | serr->ee.ee_origin = SO_EE_ORIGIN_TXSTATUS; | ||
3234 | |||
3235 | err = sock_queue_err_skb(sk, skb); | ||
3236 | if (err) | ||
3237 | kfree_skb(skb); | ||
3238 | } | ||
3239 | EXPORT_SYMBOL_GPL(skb_complete_wifi_ack); | ||
3240 | |||
3221 | 3241 | ||
3222 | /** | 3242 | /** |
3223 | * skb_partial_csum_set - set up and verify partial csum values for packet | 3243 | * skb_partial_csum_set - set up and verify partial csum values for packet |
diff --git a/net/core/sock.c b/net/core/sock.c index 2de9dc295956..9a8b3fac1401 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -740,6 +740,11 @@ set_rcvbuf: | |||
740 | case SO_RXQ_OVFL: | 740 | case SO_RXQ_OVFL: |
741 | sock_valbool_flag(sk, SOCK_RXQ_OVFL, valbool); | 741 | sock_valbool_flag(sk, SOCK_RXQ_OVFL, valbool); |
742 | break; | 742 | break; |
743 | |||
744 | case SO_WIFI_STATUS: | ||
745 | sock_valbool_flag(sk, SOCK_WIFI_STATUS, valbool); | ||
746 | break; | ||
747 | |||
743 | default: | 748 | default: |
744 | ret = -ENOPROTOOPT; | 749 | ret = -ENOPROTOOPT; |
745 | break; | 750 | break; |
@@ -961,6 +966,10 @@ int sock_getsockopt(struct socket *sock, int level, int optname, | |||
961 | v.val = !!sock_flag(sk, SOCK_RXQ_OVFL); | 966 | v.val = !!sock_flag(sk, SOCK_RXQ_OVFL); |
962 | break; | 967 | break; |
963 | 968 | ||
969 | case SO_WIFI_STATUS: | ||
970 | v.val = !!sock_flag(sk, SOCK_WIFI_STATUS); | ||
971 | break; | ||
972 | |||
964 | default: | 973 | default: |
965 | return -ENOPROTOOPT; | 974 | return -ENOPROTOOPT; |
966 | } | 975 | } |
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c index 93b243422659..476b106c0b1c 100644 --- a/net/mac80211/agg-rx.c +++ b/net/mac80211/agg-rx.c | |||
@@ -177,7 +177,8 @@ static void ieee80211_send_addba_resp(struct ieee80211_sub_if_data *sdata, u8 *d | |||
177 | memcpy(mgmt->da, da, ETH_ALEN); | 177 | memcpy(mgmt->da, da, ETH_ALEN); |
178 | memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); | 178 | memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); |
179 | if (sdata->vif.type == NL80211_IFTYPE_AP || | 179 | if (sdata->vif.type == NL80211_IFTYPE_AP || |
180 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN) | 180 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN || |
181 | sdata->vif.type == NL80211_IFTYPE_MESH_POINT) | ||
181 | memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN); | 182 | memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN); |
182 | else if (sdata->vif.type == NL80211_IFTYPE_STATION) | 183 | else if (sdata->vif.type == NL80211_IFTYPE_STATION) |
183 | memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN); | 184 | memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN); |
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index b3f65520e7a7..39d72ccaffb3 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c | |||
@@ -78,7 +78,8 @@ static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata, | |||
78 | memcpy(mgmt->da, da, ETH_ALEN); | 78 | memcpy(mgmt->da, da, ETH_ALEN); |
79 | memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); | 79 | memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); |
80 | if (sdata->vif.type == NL80211_IFTYPE_AP || | 80 | if (sdata->vif.type == NL80211_IFTYPE_AP || |
81 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN) | 81 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN || |
82 | sdata->vif.type == NL80211_IFTYPE_MESH_POINT) | ||
82 | memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN); | 83 | memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN); |
83 | else if (sdata->vif.type == NL80211_IFTYPE_STATION) | 84 | else if (sdata->vif.type == NL80211_IFTYPE_STATION) |
84 | memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN); | 85 | memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN); |
@@ -372,13 +373,8 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid, | |||
372 | pubsta->addr, tid); | 373 | pubsta->addr, tid); |
373 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 374 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
374 | 375 | ||
375 | /* | ||
376 | * The aggregation code is not prepared to handle | ||
377 | * anything but STA/AP due to the BSSID handling. | ||
378 | * IBSS could work in the code but isn't supported | ||
379 | * by drivers or the standard. | ||
380 | */ | ||
381 | if (sdata->vif.type != NL80211_IFTYPE_STATION && | 376 | if (sdata->vif.type != NL80211_IFTYPE_STATION && |
377 | sdata->vif.type != NL80211_IFTYPE_MESH_POINT && | ||
382 | sdata->vif.type != NL80211_IFTYPE_AP_VLAN && | 378 | sdata->vif.type != NL80211_IFTYPE_AP_VLAN && |
383 | sdata->vif.type != NL80211_IFTYPE_AP) | 379 | sdata->vif.type != NL80211_IFTYPE_AP) |
384 | return -EINVAL; | 380 | return -EINVAL; |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index d06c65fa5526..1063a7e57d62 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -411,7 +411,8 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) | |||
411 | BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) | | 411 | BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) | |
412 | BIT(NL80211_STA_FLAG_WME) | | 412 | BIT(NL80211_STA_FLAG_WME) | |
413 | BIT(NL80211_STA_FLAG_MFP) | | 413 | BIT(NL80211_STA_FLAG_MFP) | |
414 | BIT(NL80211_STA_FLAG_AUTHENTICATED); | 414 | BIT(NL80211_STA_FLAG_AUTHENTICATED) | |
415 | BIT(NL80211_STA_FLAG_TDLS_PEER); | ||
415 | if (test_sta_flag(sta, WLAN_STA_AUTHORIZED)) | 416 | if (test_sta_flag(sta, WLAN_STA_AUTHORIZED)) |
416 | sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_AUTHORIZED); | 417 | sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_AUTHORIZED); |
417 | if (test_sta_flag(sta, WLAN_STA_SHORT_PREAMBLE)) | 418 | if (test_sta_flag(sta, WLAN_STA_SHORT_PREAMBLE)) |
@@ -422,6 +423,8 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) | |||
422 | sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_MFP); | 423 | sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_MFP); |
423 | if (test_sta_flag(sta, WLAN_STA_AUTH)) | 424 | if (test_sta_flag(sta, WLAN_STA_AUTH)) |
424 | sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_AUTHENTICATED); | 425 | sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_AUTHENTICATED); |
426 | if (test_sta_flag(sta, WLAN_STA_TDLS_PEER)) | ||
427 | sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_TDLS_PEER); | ||
425 | } | 428 | } |
426 | 429 | ||
427 | 430 | ||
@@ -488,6 +491,31 @@ static void ieee80211_config_ap_ssid(struct ieee80211_sub_if_data *sdata, | |||
488 | (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE); | 491 | (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE); |
489 | } | 492 | } |
490 | 493 | ||
494 | static int ieee80211_set_probe_resp(struct ieee80211_sub_if_data *sdata, | ||
495 | u8 *resp, size_t resp_len) | ||
496 | { | ||
497 | struct sk_buff *new, *old; | ||
498 | |||
499 | if (!resp || !resp_len) | ||
500 | return -EINVAL; | ||
501 | |||
502 | old = sdata->u.ap.probe_resp; | ||
503 | |||
504 | new = dev_alloc_skb(resp_len); | ||
505 | if (!new) | ||
506 | return -ENOMEM; | ||
507 | |||
508 | memcpy(skb_put(new, resp_len), resp, resp_len); | ||
509 | |||
510 | rcu_assign_pointer(sdata->u.ap.probe_resp, new); | ||
511 | synchronize_rcu(); | ||
512 | |||
513 | if (old) | ||
514 | dev_kfree_skb(old); | ||
515 | |||
516 | return 0; | ||
517 | } | ||
518 | |||
491 | /* | 519 | /* |
492 | * This handles both adding a beacon and setting new beacon info | 520 | * This handles both adding a beacon and setting new beacon info |
493 | */ | 521 | */ |
@@ -498,6 +526,7 @@ static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata, | |||
498 | int new_head_len, new_tail_len; | 526 | int new_head_len, new_tail_len; |
499 | int size; | 527 | int size; |
500 | int err = -EINVAL; | 528 | int err = -EINVAL; |
529 | u32 changed = 0; | ||
501 | 530 | ||
502 | old = rtnl_dereference(sdata->u.ap.beacon); | 531 | old = rtnl_dereference(sdata->u.ap.beacon); |
503 | 532 | ||
@@ -581,11 +610,17 @@ static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata, | |||
581 | 610 | ||
582 | kfree(old); | 611 | kfree(old); |
583 | 612 | ||
613 | err = ieee80211_set_probe_resp(sdata, params->probe_resp, | ||
614 | params->probe_resp_len); | ||
615 | if (!err) | ||
616 | changed |= BSS_CHANGED_AP_PROBE_RESP; | ||
617 | |||
584 | ieee80211_config_ap_ssid(sdata, params); | 618 | ieee80211_config_ap_ssid(sdata, params); |
619 | changed |= BSS_CHANGED_BEACON_ENABLED | | ||
620 | BSS_CHANGED_BEACON | | ||
621 | BSS_CHANGED_SSID; | ||
585 | 622 | ||
586 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED | | 623 | ieee80211_bss_info_change_notify(sdata, changed); |
587 | BSS_CHANGED_BEACON | | ||
588 | BSS_CHANGED_SSID); | ||
589 | return 0; | 624 | return 0; |
590 | } | 625 | } |
591 | 626 | ||
@@ -594,6 +629,8 @@ static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev, | |||
594 | { | 629 | { |
595 | struct ieee80211_sub_if_data *sdata; | 630 | struct ieee80211_sub_if_data *sdata; |
596 | struct beacon_data *old; | 631 | struct beacon_data *old; |
632 | struct ieee80211_sub_if_data *vlan; | ||
633 | int ret; | ||
597 | 634 | ||
598 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 635 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
599 | 636 | ||
@@ -601,7 +638,24 @@ static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev, | |||
601 | if (old) | 638 | if (old) |
602 | return -EALREADY; | 639 | return -EALREADY; |
603 | 640 | ||
604 | return ieee80211_config_beacon(sdata, params); | 641 | ret = ieee80211_config_beacon(sdata, params); |
642 | if (ret) | ||
643 | return ret; | ||
644 | |||
645 | /* | ||
646 | * Apply control port protocol, this allows us to | ||
647 | * not encrypt dynamic WEP control frames. | ||
648 | */ | ||
649 | sdata->control_port_protocol = params->crypto.control_port_ethertype; | ||
650 | sdata->control_port_no_encrypt = params->crypto.control_port_no_encrypt; | ||
651 | list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) { | ||
652 | vlan->control_port_protocol = | ||
653 | params->crypto.control_port_ethertype; | ||
654 | vlan->control_port_no_encrypt = | ||
655 | params->crypto.control_port_no_encrypt; | ||
656 | } | ||
657 | |||
658 | return 0; | ||
605 | } | 659 | } |
606 | 660 | ||
607 | static int ieee80211_set_beacon(struct wiphy *wiphy, struct net_device *dev, | 661 | static int ieee80211_set_beacon(struct wiphy *wiphy, struct net_device *dev, |
@@ -847,7 +901,12 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev, | |||
847 | 901 | ||
848 | sta_apply_parameters(local, sta, params); | 902 | sta_apply_parameters(local, sta, params); |
849 | 903 | ||
850 | rate_control_rate_init(sta); | 904 | /* |
905 | * for TDLS, rate control should be initialized only when supported | ||
906 | * rates are known. | ||
907 | */ | ||
908 | if (!test_sta_flag(sta, WLAN_STA_TDLS_PEER)) | ||
909 | rate_control_rate_init(sta); | ||
851 | 910 | ||
852 | layer2_update = sdata->vif.type == NL80211_IFTYPE_AP_VLAN || | 911 | layer2_update = sdata->vif.type == NL80211_IFTYPE_AP_VLAN || |
853 | sdata->vif.type == NL80211_IFTYPE_AP; | 912 | sdata->vif.type == NL80211_IFTYPE_AP; |
@@ -931,6 +990,9 @@ static int ieee80211_change_station(struct wiphy *wiphy, | |||
931 | 990 | ||
932 | sta_apply_parameters(local, sta, params); | 991 | sta_apply_parameters(local, sta, params); |
933 | 992 | ||
993 | if (test_sta_flag(sta, WLAN_STA_TDLS_PEER) && params->supported_rates) | ||
994 | rate_control_rate_init(sta); | ||
995 | |||
934 | rcu_read_unlock(); | 996 | rcu_read_unlock(); |
935 | 997 | ||
936 | if (sdata->vif.type == NL80211_IFTYPE_STATION && | 998 | if (sdata->vif.type == NL80211_IFTYPE_STATION && |
@@ -1394,7 +1456,7 @@ static int ieee80211_set_channel(struct wiphy *wiphy, | |||
1394 | (old_oper_type != local->_oper_channel_type)) | 1456 | (old_oper_type != local->_oper_channel_type)) |
1395 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); | 1457 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); |
1396 | 1458 | ||
1397 | if ((sdata && sdata->vif.type != NL80211_IFTYPE_MONITOR) && | 1459 | if (sdata && sdata->vif.type != NL80211_IFTYPE_MONITOR && |
1398 | old_vif_oper_type != sdata->vif.bss_conf.channel_type) | 1460 | old_vif_oper_type != sdata->vif.bss_conf.channel_type) |
1399 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_HT); | 1461 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_HT); |
1400 | 1462 | ||
@@ -1917,7 +1979,7 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, | |||
1917 | enum nl80211_channel_type channel_type, | 1979 | enum nl80211_channel_type channel_type, |
1918 | bool channel_type_valid, unsigned int wait, | 1980 | bool channel_type_valid, unsigned int wait, |
1919 | const u8 *buf, size_t len, bool no_cck, | 1981 | const u8 *buf, size_t len, bool no_cck, |
1920 | u64 *cookie) | 1982 | bool dont_wait_for_ack, u64 *cookie) |
1921 | { | 1983 | { |
1922 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 1984 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
1923 | struct ieee80211_local *local = sdata->local; | 1985 | struct ieee80211_local *local = sdata->local; |
@@ -1925,10 +1987,15 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, | |||
1925 | struct sta_info *sta; | 1987 | struct sta_info *sta; |
1926 | struct ieee80211_work *wk; | 1988 | struct ieee80211_work *wk; |
1927 | const struct ieee80211_mgmt *mgmt = (void *)buf; | 1989 | const struct ieee80211_mgmt *mgmt = (void *)buf; |
1928 | u32 flags = IEEE80211_TX_INTFL_NL80211_FRAME_TX | | 1990 | u32 flags; |
1929 | IEEE80211_TX_CTL_REQ_TX_STATUS; | ||
1930 | bool is_offchan = false; | 1991 | bool is_offchan = false; |
1931 | 1992 | ||
1993 | if (dont_wait_for_ack) | ||
1994 | flags = IEEE80211_TX_CTL_NO_ACK; | ||
1995 | else | ||
1996 | flags = IEEE80211_TX_INTFL_NL80211_FRAME_TX | | ||
1997 | IEEE80211_TX_CTL_REQ_TX_STATUS; | ||
1998 | |||
1932 | /* Check that we are on the requested channel for transmission */ | 1999 | /* Check that we are on the requested channel for transmission */ |
1933 | if (chan != local->tmp_channel && | 2000 | if (chan != local->tmp_channel && |
1934 | chan != local->oper_channel) | 2001 | chan != local->oper_channel) |
@@ -2488,6 +2555,82 @@ static int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev, | |||
2488 | return 0; | 2555 | return 0; |
2489 | } | 2556 | } |
2490 | 2557 | ||
2558 | static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev, | ||
2559 | const u8 *peer, u64 *cookie) | ||
2560 | { | ||
2561 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
2562 | struct ieee80211_local *local = sdata->local; | ||
2563 | struct ieee80211_qos_hdr *nullfunc; | ||
2564 | struct sk_buff *skb; | ||
2565 | int size = sizeof(*nullfunc); | ||
2566 | __le16 fc; | ||
2567 | bool qos; | ||
2568 | struct ieee80211_tx_info *info; | ||
2569 | struct sta_info *sta; | ||
2570 | |||
2571 | rcu_read_lock(); | ||
2572 | sta = sta_info_get(sdata, peer); | ||
2573 | if (sta) { | ||
2574 | qos = test_sta_flag(sta, WLAN_STA_WME); | ||
2575 | rcu_read_unlock(); | ||
2576 | } else { | ||
2577 | rcu_read_unlock(); | ||
2578 | return -ENOLINK; | ||
2579 | } | ||
2580 | |||
2581 | if (qos) { | ||
2582 | fc = cpu_to_le16(IEEE80211_FTYPE_DATA | | ||
2583 | IEEE80211_STYPE_QOS_NULLFUNC | | ||
2584 | IEEE80211_FCTL_FROMDS); | ||
2585 | } else { | ||
2586 | size -= 2; | ||
2587 | fc = cpu_to_le16(IEEE80211_FTYPE_DATA | | ||
2588 | IEEE80211_STYPE_NULLFUNC | | ||
2589 | IEEE80211_FCTL_FROMDS); | ||
2590 | } | ||
2591 | |||
2592 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + size); | ||
2593 | if (!skb) | ||
2594 | return -ENOMEM; | ||
2595 | |||
2596 | skb->dev = dev; | ||
2597 | |||
2598 | skb_reserve(skb, local->hw.extra_tx_headroom); | ||
2599 | |||
2600 | nullfunc = (void *) skb_put(skb, size); | ||
2601 | nullfunc->frame_control = fc; | ||
2602 | nullfunc->duration_id = 0; | ||
2603 | memcpy(nullfunc->addr1, sta->sta.addr, ETH_ALEN); | ||
2604 | memcpy(nullfunc->addr2, sdata->vif.addr, ETH_ALEN); | ||
2605 | memcpy(nullfunc->addr3, sdata->vif.addr, ETH_ALEN); | ||
2606 | nullfunc->seq_ctrl = 0; | ||
2607 | |||
2608 | info = IEEE80211_SKB_CB(skb); | ||
2609 | |||
2610 | info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS | | ||
2611 | IEEE80211_TX_INTFL_NL80211_FRAME_TX; | ||
2612 | |||
2613 | skb_set_queue_mapping(skb, IEEE80211_AC_VO); | ||
2614 | skb->priority = 7; | ||
2615 | if (qos) | ||
2616 | nullfunc->qos_ctrl = cpu_to_le16(7); | ||
2617 | |||
2618 | local_bh_disable(); | ||
2619 | ieee80211_xmit(sdata, skb); | ||
2620 | local_bh_enable(); | ||
2621 | |||
2622 | *cookie = (unsigned long) skb; | ||
2623 | return 0; | ||
2624 | } | ||
2625 | |||
2626 | static struct ieee80211_channel * | ||
2627 | ieee80211_wiphy_get_channel(struct wiphy *wiphy) | ||
2628 | { | ||
2629 | struct ieee80211_local *local = wiphy_priv(wiphy); | ||
2630 | |||
2631 | return local->oper_channel; | ||
2632 | } | ||
2633 | |||
2491 | struct cfg80211_ops mac80211_config_ops = { | 2634 | struct cfg80211_ops mac80211_config_ops = { |
2492 | .add_virtual_intf = ieee80211_add_iface, | 2635 | .add_virtual_intf = ieee80211_add_iface, |
2493 | .del_virtual_intf = ieee80211_del_iface, | 2636 | .del_virtual_intf = ieee80211_del_iface, |
@@ -2553,4 +2696,6 @@ struct cfg80211_ops mac80211_config_ops = { | |||
2553 | .set_rekey_data = ieee80211_set_rekey_data, | 2696 | .set_rekey_data = ieee80211_set_rekey_data, |
2554 | .tdls_oper = ieee80211_tdls_oper, | 2697 | .tdls_oper = ieee80211_tdls_oper, |
2555 | .tdls_mgmt = ieee80211_tdls_mgmt, | 2698 | .tdls_mgmt = ieee80211_tdls_mgmt, |
2699 | .probe_client = ieee80211_probe_client, | ||
2700 | .get_channel = ieee80211_wiphy_get_channel, | ||
2556 | }; | 2701 | }; |
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c index 883996b2f99f..00cefcb493eb 100644 --- a/net/mac80211/debugfs.c +++ b/net/mac80211/debugfs.c | |||
@@ -190,7 +190,7 @@ static ssize_t uapsd_max_sp_len_write(struct file *file, | |||
190 | return -EFAULT; | 190 | return -EFAULT; |
191 | buf[len] = '\0'; | 191 | buf[len] = '\0'; |
192 | 192 | ||
193 | ret = strict_strtoul(buf, 0, &val); | 193 | ret = kstrtoul(buf, 0, &val); |
194 | 194 | ||
195 | if (ret) | 195 | if (ret) |
196 | return -EINVAL; | 196 | return -EINVAL; |
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 5f165d7eb2db..b12ed52732c8 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h | |||
@@ -5,6 +5,11 @@ | |||
5 | #include "ieee80211_i.h" | 5 | #include "ieee80211_i.h" |
6 | #include "driver-trace.h" | 6 | #include "driver-trace.h" |
7 | 7 | ||
8 | static inline void check_sdata_in_driver(struct ieee80211_sub_if_data *sdata) | ||
9 | { | ||
10 | WARN_ON(!(sdata->flags & IEEE80211_SDATA_IN_DRIVER)); | ||
11 | } | ||
12 | |||
8 | static inline void drv_tx(struct ieee80211_local *local, struct sk_buff *skb) | 13 | static inline void drv_tx(struct ieee80211_local *local, struct sk_buff *skb) |
9 | { | 14 | { |
10 | local->ops->tx(&local->hw, skb); | 15 | local->ops->tx(&local->hw, skb); |
@@ -69,15 +74,23 @@ static inline int drv_resume(struct ieee80211_local *local) | |||
69 | #endif | 74 | #endif |
70 | 75 | ||
71 | static inline int drv_add_interface(struct ieee80211_local *local, | 76 | static inline int drv_add_interface(struct ieee80211_local *local, |
72 | struct ieee80211_vif *vif) | 77 | struct ieee80211_sub_if_data *sdata) |
73 | { | 78 | { |
74 | int ret; | 79 | int ret; |
75 | 80 | ||
76 | might_sleep(); | 81 | might_sleep(); |
77 | 82 | ||
78 | trace_drv_add_interface(local, vif_to_sdata(vif)); | 83 | if (WARN_ON(sdata->vif.type == NL80211_IFTYPE_AP_VLAN || |
79 | ret = local->ops->add_interface(&local->hw, vif); | 84 | sdata->vif.type == NL80211_IFTYPE_MONITOR)) |
85 | return -EINVAL; | ||
86 | |||
87 | trace_drv_add_interface(local, sdata); | ||
88 | ret = local->ops->add_interface(&local->hw, &sdata->vif); | ||
80 | trace_drv_return_int(local, ret); | 89 | trace_drv_return_int(local, ret); |
90 | |||
91 | if (ret == 0) | ||
92 | sdata->flags |= IEEE80211_SDATA_IN_DRIVER; | ||
93 | |||
81 | return ret; | 94 | return ret; |
82 | } | 95 | } |
83 | 96 | ||
@@ -89,6 +102,8 @@ static inline int drv_change_interface(struct ieee80211_local *local, | |||
89 | 102 | ||
90 | might_sleep(); | 103 | might_sleep(); |
91 | 104 | ||
105 | check_sdata_in_driver(sdata); | ||
106 | |||
92 | trace_drv_change_interface(local, sdata, type, p2p); | 107 | trace_drv_change_interface(local, sdata, type, p2p); |
93 | ret = local->ops->change_interface(&local->hw, &sdata->vif, type, p2p); | 108 | ret = local->ops->change_interface(&local->hw, &sdata->vif, type, p2p); |
94 | trace_drv_return_int(local, ret); | 109 | trace_drv_return_int(local, ret); |
@@ -96,12 +111,15 @@ static inline int drv_change_interface(struct ieee80211_local *local, | |||
96 | } | 111 | } |
97 | 112 | ||
98 | static inline void drv_remove_interface(struct ieee80211_local *local, | 113 | static inline void drv_remove_interface(struct ieee80211_local *local, |
99 | struct ieee80211_vif *vif) | 114 | struct ieee80211_sub_if_data *sdata) |
100 | { | 115 | { |
101 | might_sleep(); | 116 | might_sleep(); |
102 | 117 | ||
103 | trace_drv_remove_interface(local, vif_to_sdata(vif)); | 118 | check_sdata_in_driver(sdata); |
104 | local->ops->remove_interface(&local->hw, vif); | 119 | |
120 | trace_drv_remove_interface(local, sdata); | ||
121 | local->ops->remove_interface(&local->hw, &sdata->vif); | ||
122 | sdata->flags &= ~IEEE80211_SDATA_IN_DRIVER; | ||
105 | trace_drv_return_void(local); | 123 | trace_drv_return_void(local); |
106 | } | 124 | } |
107 | 125 | ||
@@ -124,6 +142,8 @@ static inline void drv_bss_info_changed(struct ieee80211_local *local, | |||
124 | { | 142 | { |
125 | might_sleep(); | 143 | might_sleep(); |
126 | 144 | ||
145 | check_sdata_in_driver(sdata); | ||
146 | |||
127 | trace_drv_bss_info_changed(local, sdata, info, changed); | 147 | trace_drv_bss_info_changed(local, sdata, info, changed); |
128 | if (local->ops->bss_info_changed) | 148 | if (local->ops->bss_info_changed) |
129 | local->ops->bss_info_changed(&local->hw, &sdata->vif, info, changed); | 149 | local->ops->bss_info_changed(&local->hw, &sdata->vif, info, changed); |
@@ -139,6 +159,8 @@ static inline int drv_tx_sync(struct ieee80211_local *local, | |||
139 | 159 | ||
140 | might_sleep(); | 160 | might_sleep(); |
141 | 161 | ||
162 | check_sdata_in_driver(sdata); | ||
163 | |||
142 | trace_drv_tx_sync(local, sdata, bssid, type); | 164 | trace_drv_tx_sync(local, sdata, bssid, type); |
143 | if (local->ops->tx_sync) | 165 | if (local->ops->tx_sync) |
144 | ret = local->ops->tx_sync(&local->hw, &sdata->vif, | 166 | ret = local->ops->tx_sync(&local->hw, &sdata->vif, |
@@ -154,6 +176,8 @@ static inline void drv_finish_tx_sync(struct ieee80211_local *local, | |||
154 | { | 176 | { |
155 | might_sleep(); | 177 | might_sleep(); |
156 | 178 | ||
179 | check_sdata_in_driver(sdata); | ||
180 | |||
157 | trace_drv_finish_tx_sync(local, sdata, bssid, type); | 181 | trace_drv_finish_tx_sync(local, sdata, bssid, type); |
158 | if (local->ops->finish_tx_sync) | 182 | if (local->ops->finish_tx_sync) |
159 | local->ops->finish_tx_sync(&local->hw, &sdata->vif, | 183 | local->ops->finish_tx_sync(&local->hw, &sdata->vif, |
@@ -211,6 +235,8 @@ static inline int drv_set_key(struct ieee80211_local *local, | |||
211 | 235 | ||
212 | might_sleep(); | 236 | might_sleep(); |
213 | 237 | ||
238 | check_sdata_in_driver(sdata); | ||
239 | |||
214 | trace_drv_set_key(local, cmd, sdata, sta, key); | 240 | trace_drv_set_key(local, cmd, sdata, sta, key); |
215 | ret = local->ops->set_key(&local->hw, cmd, &sdata->vif, sta, key); | 241 | ret = local->ops->set_key(&local->hw, cmd, &sdata->vif, sta, key); |
216 | trace_drv_return_int(local, ret); | 242 | trace_drv_return_int(local, ret); |
@@ -228,6 +254,8 @@ static inline void drv_update_tkip_key(struct ieee80211_local *local, | |||
228 | if (sta) | 254 | if (sta) |
229 | ista = &sta->sta; | 255 | ista = &sta->sta; |
230 | 256 | ||
257 | check_sdata_in_driver(sdata); | ||
258 | |||
231 | trace_drv_update_tkip_key(local, sdata, conf, ista, iv32); | 259 | trace_drv_update_tkip_key(local, sdata, conf, ista, iv32); |
232 | if (local->ops->update_tkip_key) | 260 | if (local->ops->update_tkip_key) |
233 | local->ops->update_tkip_key(&local->hw, &sdata->vif, conf, | 261 | local->ops->update_tkip_key(&local->hw, &sdata->vif, conf, |
@@ -243,6 +271,8 @@ static inline int drv_hw_scan(struct ieee80211_local *local, | |||
243 | 271 | ||
244 | might_sleep(); | 272 | might_sleep(); |
245 | 273 | ||
274 | check_sdata_in_driver(sdata); | ||
275 | |||
246 | trace_drv_hw_scan(local, sdata); | 276 | trace_drv_hw_scan(local, sdata); |
247 | ret = local->ops->hw_scan(&local->hw, &sdata->vif, req); | 277 | ret = local->ops->hw_scan(&local->hw, &sdata->vif, req); |
248 | trace_drv_return_int(local, ret); | 278 | trace_drv_return_int(local, ret); |
@@ -254,6 +284,8 @@ static inline void drv_cancel_hw_scan(struct ieee80211_local *local, | |||
254 | { | 284 | { |
255 | might_sleep(); | 285 | might_sleep(); |
256 | 286 | ||
287 | check_sdata_in_driver(sdata); | ||
288 | |||
257 | trace_drv_cancel_hw_scan(local, sdata); | 289 | trace_drv_cancel_hw_scan(local, sdata); |
258 | local->ops->cancel_hw_scan(&local->hw, &sdata->vif); | 290 | local->ops->cancel_hw_scan(&local->hw, &sdata->vif); |
259 | trace_drv_return_void(local); | 291 | trace_drv_return_void(local); |
@@ -269,6 +301,8 @@ drv_sched_scan_start(struct ieee80211_local *local, | |||
269 | 301 | ||
270 | might_sleep(); | 302 | might_sleep(); |
271 | 303 | ||
304 | check_sdata_in_driver(sdata); | ||
305 | |||
272 | trace_drv_sched_scan_start(local, sdata); | 306 | trace_drv_sched_scan_start(local, sdata); |
273 | ret = local->ops->sched_scan_start(&local->hw, &sdata->vif, | 307 | ret = local->ops->sched_scan_start(&local->hw, &sdata->vif, |
274 | req, ies); | 308 | req, ies); |
@@ -281,6 +315,8 @@ static inline void drv_sched_scan_stop(struct ieee80211_local *local, | |||
281 | { | 315 | { |
282 | might_sleep(); | 316 | might_sleep(); |
283 | 317 | ||
318 | check_sdata_in_driver(sdata); | ||
319 | |||
284 | trace_drv_sched_scan_stop(local, sdata); | 320 | trace_drv_sched_scan_stop(local, sdata); |
285 | local->ops->sched_scan_stop(&local->hw, &sdata->vif); | 321 | local->ops->sched_scan_stop(&local->hw, &sdata->vif); |
286 | trace_drv_return_void(local); | 322 | trace_drv_return_void(local); |
@@ -377,6 +413,8 @@ static inline void drv_sta_notify(struct ieee80211_local *local, | |||
377 | enum sta_notify_cmd cmd, | 413 | enum sta_notify_cmd cmd, |
378 | struct ieee80211_sta *sta) | 414 | struct ieee80211_sta *sta) |
379 | { | 415 | { |
416 | check_sdata_in_driver(sdata); | ||
417 | |||
380 | trace_drv_sta_notify(local, sdata, cmd, sta); | 418 | trace_drv_sta_notify(local, sdata, cmd, sta); |
381 | if (local->ops->sta_notify) | 419 | if (local->ops->sta_notify) |
382 | local->ops->sta_notify(&local->hw, &sdata->vif, cmd, sta); | 420 | local->ops->sta_notify(&local->hw, &sdata->vif, cmd, sta); |
@@ -391,6 +429,8 @@ static inline int drv_sta_add(struct ieee80211_local *local, | |||
391 | 429 | ||
392 | might_sleep(); | 430 | might_sleep(); |
393 | 431 | ||
432 | check_sdata_in_driver(sdata); | ||
433 | |||
394 | trace_drv_sta_add(local, sdata, sta); | 434 | trace_drv_sta_add(local, sdata, sta); |
395 | if (local->ops->sta_add) | 435 | if (local->ops->sta_add) |
396 | ret = local->ops->sta_add(&local->hw, &sdata->vif, sta); | 436 | ret = local->ops->sta_add(&local->hw, &sdata->vif, sta); |
@@ -406,6 +446,8 @@ static inline void drv_sta_remove(struct ieee80211_local *local, | |||
406 | { | 446 | { |
407 | might_sleep(); | 447 | might_sleep(); |
408 | 448 | ||
449 | check_sdata_in_driver(sdata); | ||
450 | |||
409 | trace_drv_sta_remove(local, sdata, sta); | 451 | trace_drv_sta_remove(local, sdata, sta); |
410 | if (local->ops->sta_remove) | 452 | if (local->ops->sta_remove) |
411 | local->ops->sta_remove(&local->hw, &sdata->vif, sta); | 453 | local->ops->sta_remove(&local->hw, &sdata->vif, sta); |
@@ -421,6 +463,8 @@ static inline int drv_conf_tx(struct ieee80211_local *local, | |||
421 | 463 | ||
422 | might_sleep(); | 464 | might_sleep(); |
423 | 465 | ||
466 | check_sdata_in_driver(sdata); | ||
467 | |||
424 | trace_drv_conf_tx(local, sdata, queue, params); | 468 | trace_drv_conf_tx(local, sdata, queue, params); |
425 | if (local->ops->conf_tx) | 469 | if (local->ops->conf_tx) |
426 | ret = local->ops->conf_tx(&local->hw, &sdata->vif, | 470 | ret = local->ops->conf_tx(&local->hw, &sdata->vif, |
@@ -436,6 +480,8 @@ static inline u64 drv_get_tsf(struct ieee80211_local *local, | |||
436 | 480 | ||
437 | might_sleep(); | 481 | might_sleep(); |
438 | 482 | ||
483 | check_sdata_in_driver(sdata); | ||
484 | |||
439 | trace_drv_get_tsf(local, sdata); | 485 | trace_drv_get_tsf(local, sdata); |
440 | if (local->ops->get_tsf) | 486 | if (local->ops->get_tsf) |
441 | ret = local->ops->get_tsf(&local->hw, &sdata->vif); | 487 | ret = local->ops->get_tsf(&local->hw, &sdata->vif); |
@@ -449,6 +495,8 @@ static inline void drv_set_tsf(struct ieee80211_local *local, | |||
449 | { | 495 | { |
450 | might_sleep(); | 496 | might_sleep(); |
451 | 497 | ||
498 | check_sdata_in_driver(sdata); | ||
499 | |||
452 | trace_drv_set_tsf(local, sdata, tsf); | 500 | trace_drv_set_tsf(local, sdata, tsf); |
453 | if (local->ops->set_tsf) | 501 | if (local->ops->set_tsf) |
454 | local->ops->set_tsf(&local->hw, &sdata->vif, tsf); | 502 | local->ops->set_tsf(&local->hw, &sdata->vif, tsf); |
@@ -460,6 +508,8 @@ static inline void drv_reset_tsf(struct ieee80211_local *local, | |||
460 | { | 508 | { |
461 | might_sleep(); | 509 | might_sleep(); |
462 | 510 | ||
511 | check_sdata_in_driver(sdata); | ||
512 | |||
463 | trace_drv_reset_tsf(local, sdata); | 513 | trace_drv_reset_tsf(local, sdata); |
464 | if (local->ops->reset_tsf) | 514 | if (local->ops->reset_tsf) |
465 | local->ops->reset_tsf(&local->hw, &sdata->vif); | 515 | local->ops->reset_tsf(&local->hw, &sdata->vif); |
@@ -489,6 +539,8 @@ static inline int drv_ampdu_action(struct ieee80211_local *local, | |||
489 | 539 | ||
490 | might_sleep(); | 540 | might_sleep(); |
491 | 541 | ||
542 | check_sdata_in_driver(sdata); | ||
543 | |||
492 | trace_drv_ampdu_action(local, sdata, action, sta, tid, ssn, buf_size); | 544 | trace_drv_ampdu_action(local, sdata, action, sta, tid, ssn, buf_size); |
493 | 545 | ||
494 | if (local->ops->ampdu_action) | 546 | if (local->ops->ampdu_action) |
@@ -644,6 +696,8 @@ static inline int drv_set_bitrate_mask(struct ieee80211_local *local, | |||
644 | 696 | ||
645 | might_sleep(); | 697 | might_sleep(); |
646 | 698 | ||
699 | check_sdata_in_driver(sdata); | ||
700 | |||
647 | trace_drv_set_bitrate_mask(local, sdata, mask); | 701 | trace_drv_set_bitrate_mask(local, sdata, mask); |
648 | if (local->ops->set_bitrate_mask) | 702 | if (local->ops->set_bitrate_mask) |
649 | ret = local->ops->set_bitrate_mask(&local->hw, | 703 | ret = local->ops->set_bitrate_mask(&local->hw, |
@@ -657,6 +711,8 @@ static inline void drv_set_rekey_data(struct ieee80211_local *local, | |||
657 | struct ieee80211_sub_if_data *sdata, | 711 | struct ieee80211_sub_if_data *sdata, |
658 | struct cfg80211_gtk_rekey_data *data) | 712 | struct cfg80211_gtk_rekey_data *data) |
659 | { | 713 | { |
714 | check_sdata_in_driver(sdata); | ||
715 | |||
660 | trace_drv_set_rekey_data(local, sdata, data); | 716 | trace_drv_set_rekey_data(local, sdata, data); |
661 | if (local->ops->set_rekey_data) | 717 | if (local->ops->set_rekey_data) |
662 | local->ops->set_rekey_data(&local->hw, &sdata->vif, data); | 718 | local->ops->set_rekey_data(&local->hw, &sdata->vif, data); |
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c index f0fb737efa86..d06975098aad 100644 --- a/net/mac80211/ht.c +++ b/net/mac80211/ht.c | |||
@@ -196,7 +196,8 @@ void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata, | |||
196 | memcpy(mgmt->da, da, ETH_ALEN); | 196 | memcpy(mgmt->da, da, ETH_ALEN); |
197 | memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); | 197 | memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); |
198 | if (sdata->vif.type == NL80211_IFTYPE_AP || | 198 | if (sdata->vif.type == NL80211_IFTYPE_AP || |
199 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN) | 199 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN || |
200 | sdata->vif.type == NL80211_IFTYPE_MESH_POINT) | ||
200 | memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN); | 201 | memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN); |
201 | else if (sdata->vif.type == NL80211_IFTYPE_STATION) | 202 | else if (sdata->vif.type == NL80211_IFTYPE_STATION) |
202 | memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN); | 203 | memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN); |
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index ede9a8b341ac..7d84af70132f 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
@@ -97,6 +97,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
97 | /* if merging, indicate to driver that we leave the old IBSS */ | 97 | /* if merging, indicate to driver that we leave the old IBSS */ |
98 | if (sdata->vif.bss_conf.ibss_joined) { | 98 | if (sdata->vif.bss_conf.ibss_joined) { |
99 | sdata->vif.bss_conf.ibss_joined = false; | 99 | sdata->vif.bss_conf.ibss_joined = false; |
100 | netif_carrier_off(sdata->dev); | ||
100 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IBSS); | 101 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IBSS); |
101 | } | 102 | } |
102 | 103 | ||
@@ -207,6 +208,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
207 | bss = cfg80211_inform_bss_frame(local->hw.wiphy, local->hw.conf.channel, | 208 | bss = cfg80211_inform_bss_frame(local->hw.wiphy, local->hw.conf.channel, |
208 | mgmt, skb->len, 0, GFP_KERNEL); | 209 | mgmt, skb->len, 0, GFP_KERNEL); |
209 | cfg80211_put_bss(bss); | 210 | cfg80211_put_bss(bss); |
211 | netif_carrier_on(sdata->dev); | ||
210 | cfg80211_ibss_joined(sdata->dev, ifibss->bssid, GFP_KERNEL); | 212 | cfg80211_ibss_joined(sdata->dev, ifibss->bssid, GFP_KERNEL); |
211 | } | 213 | } |
212 | 214 | ||
@@ -990,6 +992,7 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata) | |||
990 | } | 992 | } |
991 | 993 | ||
992 | sta_info_flush(sdata->local, sdata); | 994 | sta_info_flush(sdata->local, sdata); |
995 | netif_carrier_off(sdata->dev); | ||
993 | 996 | ||
994 | /* remove beacon */ | 997 | /* remove beacon */ |
995 | kfree(sdata->u.ibss.ie); | 998 | kfree(sdata->u.ibss.ie); |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index ea10a51babda..068cc92d16aa 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/spinlock.h> | 24 | #include <linux/spinlock.h> |
25 | #include <linux/etherdevice.h> | 25 | #include <linux/etherdevice.h> |
26 | #include <linux/leds.h> | 26 | #include <linux/leds.h> |
27 | #include <linux/idr.h> | ||
27 | #include <net/ieee80211_radiotap.h> | 28 | #include <net/ieee80211_radiotap.h> |
28 | #include <net/cfg80211.h> | 29 | #include <net/cfg80211.h> |
29 | #include <net/mac80211.h> | 30 | #include <net/mac80211.h> |
@@ -184,12 +185,15 @@ enum ieee80211_packet_rx_flags { | |||
184 | * enum ieee80211_rx_flags - RX data flags | 185 | * enum ieee80211_rx_flags - RX data flags |
185 | * | 186 | * |
186 | * @IEEE80211_RX_CMNTR: received on cooked monitor already | 187 | * @IEEE80211_RX_CMNTR: received on cooked monitor already |
188 | * @IEEE80211_RX_BEACON_REPORTED: This frame was already reported | ||
189 | * to cfg80211_report_obss_beacon(). | ||
187 | * | 190 | * |
188 | * These flags are used across handling multiple interfaces | 191 | * These flags are used across handling multiple interfaces |
189 | * for a single frame. | 192 | * for a single frame. |
190 | */ | 193 | */ |
191 | enum ieee80211_rx_flags { | 194 | enum ieee80211_rx_flags { |
192 | IEEE80211_RX_CMNTR = BIT(0), | 195 | IEEE80211_RX_CMNTR = BIT(0), |
196 | IEEE80211_RX_BEACON_REPORTED = BIT(1), | ||
193 | }; | 197 | }; |
194 | 198 | ||
195 | struct ieee80211_rx_data { | 199 | struct ieee80211_rx_data { |
@@ -228,6 +232,7 @@ struct beacon_data { | |||
228 | 232 | ||
229 | struct ieee80211_if_ap { | 233 | struct ieee80211_if_ap { |
230 | struct beacon_data __rcu *beacon; | 234 | struct beacon_data __rcu *beacon; |
235 | struct sk_buff __rcu *probe_resp; | ||
231 | 236 | ||
232 | struct list_head vlans; | 237 | struct list_head vlans; |
233 | 238 | ||
@@ -543,6 +548,7 @@ struct ieee80211_if_mesh { | |||
543 | * associated stations and deliver multicast frames both | 548 | * associated stations and deliver multicast frames both |
544 | * back to wireless media and to the local net stack. | 549 | * back to wireless media and to the local net stack. |
545 | * @IEEE80211_SDATA_DISCONNECT_RESUME: Disconnect after resume. | 550 | * @IEEE80211_SDATA_DISCONNECT_RESUME: Disconnect after resume. |
551 | * @IEEE80211_SDATA_IN_DRIVER: indicates interface was added to driver | ||
546 | */ | 552 | */ |
547 | enum ieee80211_sub_if_data_flags { | 553 | enum ieee80211_sub_if_data_flags { |
548 | IEEE80211_SDATA_ALLMULTI = BIT(0), | 554 | IEEE80211_SDATA_ALLMULTI = BIT(0), |
@@ -550,6 +556,7 @@ enum ieee80211_sub_if_data_flags { | |||
550 | IEEE80211_SDATA_OPERATING_GMODE = BIT(2), | 556 | IEEE80211_SDATA_OPERATING_GMODE = BIT(2), |
551 | IEEE80211_SDATA_DONT_BRIDGE_PACKETS = BIT(3), | 557 | IEEE80211_SDATA_DONT_BRIDGE_PACKETS = BIT(3), |
552 | IEEE80211_SDATA_DISCONNECT_RESUME = BIT(4), | 558 | IEEE80211_SDATA_DISCONNECT_RESUME = BIT(4), |
559 | IEEE80211_SDATA_IN_DRIVER = BIT(5), | ||
553 | }; | 560 | }; |
554 | 561 | ||
555 | /** | 562 | /** |
@@ -722,17 +729,16 @@ enum { | |||
722 | * operating channel | 729 | * operating channel |
723 | * @SCAN_SET_CHANNEL: Set the next channel to be scanned | 730 | * @SCAN_SET_CHANNEL: Set the next channel to be scanned |
724 | * @SCAN_SEND_PROBE: Send probe requests and wait for probe responses | 731 | * @SCAN_SEND_PROBE: Send probe requests and wait for probe responses |
725 | * @SCAN_LEAVE_OPER_CHANNEL: Leave the operating channel, notify the AP | 732 | * @SCAN_SUSPEND: Suspend the scan and go back to operating channel to |
726 | * about us leaving the channel and stop all associated STA interfaces | 733 | * send out data |
727 | * @SCAN_ENTER_OPER_CHANNEL: Enter the operating channel again, notify the | 734 | * @SCAN_RESUME: Resume the scan and scan the next channel |
728 | * AP about us being back and restart all associated STA interfaces | ||
729 | */ | 735 | */ |
730 | enum mac80211_scan_state { | 736 | enum mac80211_scan_state { |
731 | SCAN_DECISION, | 737 | SCAN_DECISION, |
732 | SCAN_SET_CHANNEL, | 738 | SCAN_SET_CHANNEL, |
733 | SCAN_SEND_PROBE, | 739 | SCAN_SEND_PROBE, |
734 | SCAN_LEAVE_OPER_CHANNEL, | 740 | SCAN_SUSPEND, |
735 | SCAN_ENTER_OPER_CHANNEL, | 741 | SCAN_RESUME, |
736 | }; | 742 | }; |
737 | 743 | ||
738 | struct ieee80211_local { | 744 | struct ieee80211_local { |
@@ -1012,6 +1018,9 @@ struct ieee80211_local { | |||
1012 | u32 hw_roc_cookie; | 1018 | u32 hw_roc_cookie; |
1013 | bool hw_roc_for_tx; | 1019 | bool hw_roc_for_tx; |
1014 | 1020 | ||
1021 | struct idr ack_status_frames; | ||
1022 | spinlock_t ack_status_lock; | ||
1023 | |||
1015 | /* dummy netdev for use w/ NAPI */ | 1024 | /* dummy netdev for use w/ NAPI */ |
1016 | struct net_device napi_dev; | 1025 | struct net_device napi_dev; |
1017 | 1026 | ||
@@ -1334,6 +1343,12 @@ void ieee80211_recalc_smps(struct ieee80211_local *local); | |||
1334 | size_t ieee80211_ie_split(const u8 *ies, size_t ielen, | 1343 | size_t ieee80211_ie_split(const u8 *ies, size_t ielen, |
1335 | const u8 *ids, int n_ids, size_t offset); | 1344 | const u8 *ids, int n_ids, size_t offset); |
1336 | size_t ieee80211_ie_split_vendor(const u8 *ies, size_t ielen, size_t offset); | 1345 | size_t ieee80211_ie_split_vendor(const u8 *ies, size_t ielen, size_t offset); |
1346 | u8 *ieee80211_ie_build_ht_cap(u8 *pos, struct ieee80211_supported_band *sband, | ||
1347 | u16 cap); | ||
1348 | u8 *ieee80211_ie_build_ht_info(u8 *pos, | ||
1349 | struct ieee80211_sta_ht_cap *ht_cap, | ||
1350 | struct ieee80211_channel *channel, | ||
1351 | enum nl80211_channel_type channel_type); | ||
1337 | 1352 | ||
1338 | /* internal work items */ | 1353 | /* internal work items */ |
1339 | void ieee80211_work_init(struct ieee80211_local *local); | 1354 | void ieee80211_work_init(struct ieee80211_local *local); |
@@ -1362,6 +1377,8 @@ ieee80211_get_channel_mode(struct ieee80211_local *local, | |||
1362 | bool ieee80211_set_channel_type(struct ieee80211_local *local, | 1377 | bool ieee80211_set_channel_type(struct ieee80211_local *local, |
1363 | struct ieee80211_sub_if_data *sdata, | 1378 | struct ieee80211_sub_if_data *sdata, |
1364 | enum nl80211_channel_type chantype); | 1379 | enum nl80211_channel_type chantype); |
1380 | enum nl80211_channel_type | ||
1381 | ieee80211_ht_info_to_channel_type(struct ieee80211_ht_info *ht_info); | ||
1365 | 1382 | ||
1366 | #ifdef CONFIG_MAC80211_NOINLINE | 1383 | #ifdef CONFIG_MAC80211_NOINLINE |
1367 | #define debug_noinline noinline | 1384 | #define debug_noinline noinline |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 30d73552e9ab..12a6d4bb5d37 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -188,11 +188,22 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up) | |||
188 | if (!is_valid_ether_addr(sdata->u.wds.remote_addr)) | 188 | if (!is_valid_ether_addr(sdata->u.wds.remote_addr)) |
189 | return -ENOLINK; | 189 | return -ENOLINK; |
190 | break; | 190 | break; |
191 | case NL80211_IFTYPE_AP_VLAN: | 191 | case NL80211_IFTYPE_AP_VLAN: { |
192 | struct ieee80211_sub_if_data *master; | ||
193 | |||
192 | if (!sdata->bss) | 194 | if (!sdata->bss) |
193 | return -ENOLINK; | 195 | return -ENOLINK; |
196 | |||
194 | list_add(&sdata->u.vlan.list, &sdata->bss->vlans); | 197 | list_add(&sdata->u.vlan.list, &sdata->bss->vlans); |
198 | |||
199 | master = container_of(sdata->bss, | ||
200 | struct ieee80211_sub_if_data, u.ap); | ||
201 | sdata->control_port_protocol = | ||
202 | master->control_port_protocol; | ||
203 | sdata->control_port_no_encrypt = | ||
204 | master->control_port_no_encrypt; | ||
195 | break; | 205 | break; |
206 | } | ||
196 | case NL80211_IFTYPE_AP: | 207 | case NL80211_IFTYPE_AP: |
197 | sdata->bss = &sdata->u.ap; | 208 | sdata->bss = &sdata->u.ap; |
198 | break; | 209 | break; |
@@ -265,7 +276,7 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up) | |||
265 | break; | 276 | break; |
266 | default: | 277 | default: |
267 | if (coming_up) { | 278 | if (coming_up) { |
268 | res = drv_add_interface(local, &sdata->vif); | 279 | res = drv_add_interface(local, sdata); |
269 | if (res) | 280 | if (res) |
270 | goto err_stop; | 281 | goto err_stop; |
271 | } | 282 | } |
@@ -282,10 +293,18 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up) | |||
282 | changed |= ieee80211_reset_erp_info(sdata); | 293 | changed |= ieee80211_reset_erp_info(sdata); |
283 | ieee80211_bss_info_change_notify(sdata, changed); | 294 | ieee80211_bss_info_change_notify(sdata, changed); |
284 | 295 | ||
285 | if (sdata->vif.type == NL80211_IFTYPE_STATION) | 296 | if (sdata->vif.type == NL80211_IFTYPE_STATION || |
297 | sdata->vif.type == NL80211_IFTYPE_ADHOC) | ||
286 | netif_carrier_off(dev); | 298 | netif_carrier_off(dev); |
287 | else | 299 | else |
288 | netif_carrier_on(dev); | 300 | netif_carrier_on(dev); |
301 | |||
302 | /* | ||
303 | * set default queue parameters so drivers don't | ||
304 | * need to initialise the hardware if the hardware | ||
305 | * doesn't start up with sane defaults | ||
306 | */ | ||
307 | ieee80211_set_wmm_default(sdata); | ||
289 | } | 308 | } |
290 | 309 | ||
291 | set_bit(SDATA_STATE_RUNNING, &sdata->state); | 310 | set_bit(SDATA_STATE_RUNNING, &sdata->state); |
@@ -329,15 +348,8 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up) | |||
329 | if (coming_up) | 348 | if (coming_up) |
330 | local->open_count++; | 349 | local->open_count++; |
331 | 350 | ||
332 | if (hw_reconf_flags) { | 351 | if (hw_reconf_flags) |
333 | ieee80211_hw_config(local, hw_reconf_flags); | 352 | ieee80211_hw_config(local, hw_reconf_flags); |
334 | /* | ||
335 | * set default queue parameters so drivers don't | ||
336 | * need to initialise the hardware if the hardware | ||
337 | * doesn't start up with sane defaults | ||
338 | */ | ||
339 | ieee80211_set_wmm_default(sdata); | ||
340 | } | ||
341 | 353 | ||
342 | ieee80211_recalc_ps(local, -1); | 354 | ieee80211_recalc_ps(local, -1); |
343 | 355 | ||
@@ -345,7 +357,7 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up) | |||
345 | 357 | ||
346 | return 0; | 358 | return 0; |
347 | err_del_interface: | 359 | err_del_interface: |
348 | drv_remove_interface(local, &sdata->vif); | 360 | drv_remove_interface(local, sdata); |
349 | err_stop: | 361 | err_stop: |
350 | if (!local->open_count) | 362 | if (!local->open_count) |
351 | drv_stop(local); | 363 | drv_stop(local); |
@@ -450,15 +462,19 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, | |||
450 | struct ieee80211_sub_if_data *vlan, *tmpsdata; | 462 | struct ieee80211_sub_if_data *vlan, *tmpsdata; |
451 | struct beacon_data *old_beacon = | 463 | struct beacon_data *old_beacon = |
452 | rtnl_dereference(sdata->u.ap.beacon); | 464 | rtnl_dereference(sdata->u.ap.beacon); |
465 | struct sk_buff *old_probe_resp = | ||
466 | rtnl_dereference(sdata->u.ap.probe_resp); | ||
453 | 467 | ||
454 | /* sdata_running will return false, so this will disable */ | 468 | /* sdata_running will return false, so this will disable */ |
455 | ieee80211_bss_info_change_notify(sdata, | 469 | ieee80211_bss_info_change_notify(sdata, |
456 | BSS_CHANGED_BEACON_ENABLED); | 470 | BSS_CHANGED_BEACON_ENABLED); |
457 | 471 | ||
458 | /* remove beacon */ | 472 | /* remove beacon and probe response */ |
459 | RCU_INIT_POINTER(sdata->u.ap.beacon, NULL); | 473 | RCU_INIT_POINTER(sdata->u.ap.beacon, NULL); |
474 | RCU_INIT_POINTER(sdata->u.ap.probe_resp, NULL); | ||
460 | synchronize_rcu(); | 475 | synchronize_rcu(); |
461 | kfree(old_beacon); | 476 | kfree(old_beacon); |
477 | kfree(old_probe_resp); | ||
462 | 478 | ||
463 | /* down all dependent devices, that is VLANs */ | 479 | /* down all dependent devices, that is VLANs */ |
464 | list_for_each_entry_safe(vlan, tmpsdata, &sdata->u.ap.vlans, | 480 | list_for_each_entry_safe(vlan, tmpsdata, &sdata->u.ap.vlans, |
@@ -520,7 +536,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, | |||
520 | ieee80211_free_keys(sdata); | 536 | ieee80211_free_keys(sdata); |
521 | 537 | ||
522 | if (going_down) | 538 | if (going_down) |
523 | drv_remove_interface(local, &sdata->vif); | 539 | drv_remove_interface(local, sdata); |
524 | } | 540 | } |
525 | 541 | ||
526 | sdata->bss = NULL; | 542 | sdata->bss = NULL; |
diff --git a/net/mac80211/key.c b/net/mac80211/key.c index fb02ea52d2c2..87a89741432d 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c | |||
@@ -134,9 +134,13 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key) | |||
134 | key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE; | 134 | key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE; |
135 | 135 | ||
136 | if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) || | 136 | if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) || |
137 | (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV))) | 137 | (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) || |
138 | (key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE))) | ||
138 | sdata->crypto_tx_tailroom_needed_cnt--; | 139 | sdata->crypto_tx_tailroom_needed_cnt--; |
139 | 140 | ||
141 | WARN_ON((key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE) && | ||
142 | (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)); | ||
143 | |||
140 | return 0; | 144 | return 0; |
141 | } | 145 | } |
142 | 146 | ||
@@ -179,7 +183,8 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key) | |||
179 | sdata = key->sdata; | 183 | sdata = key->sdata; |
180 | 184 | ||
181 | if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) || | 185 | if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) || |
182 | (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV))) | 186 | (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) || |
187 | (key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE))) | ||
183 | increment_tailroom_need_count(sdata); | 188 | increment_tailroom_need_count(sdata); |
184 | 189 | ||
185 | if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) | 190 | if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index d999bf3b84e1..e323d4e6647b 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -100,7 +100,7 @@ static void ieee80211_reconfig_filter(struct work_struct *work) | |||
100 | */ | 100 | */ |
101 | bool ieee80211_cfg_on_oper_channel(struct ieee80211_local *local) | 101 | bool ieee80211_cfg_on_oper_channel(struct ieee80211_local *local) |
102 | { | 102 | { |
103 | struct ieee80211_channel *chan, *scan_chan; | 103 | struct ieee80211_channel *chan; |
104 | enum nl80211_channel_type channel_type; | 104 | enum nl80211_channel_type channel_type; |
105 | 105 | ||
106 | /* This logic needs to match logic in ieee80211_hw_config */ | 106 | /* This logic needs to match logic in ieee80211_hw_config */ |
@@ -114,7 +114,7 @@ bool ieee80211_cfg_on_oper_channel(struct ieee80211_local *local) | |||
114 | else | 114 | else |
115 | channel_type = NL80211_CHAN_NO_HT; | 115 | channel_type = NL80211_CHAN_NO_HT; |
116 | } else if (local->tmp_channel) { | 116 | } else if (local->tmp_channel) { |
117 | chan = scan_chan = local->tmp_channel; | 117 | chan = local->tmp_channel; |
118 | channel_type = local->tmp_channel_type; | 118 | channel_type = local->tmp_channel_type; |
119 | } else { | 119 | } else { |
120 | chan = local->oper_channel; | 120 | chan = local->oper_channel; |
@@ -126,8 +126,8 @@ bool ieee80211_cfg_on_oper_channel(struct ieee80211_local *local) | |||
126 | return false; | 126 | return false; |
127 | 127 | ||
128 | /* Check current hardware-config against oper_channel. */ | 128 | /* Check current hardware-config against oper_channel. */ |
129 | if ((local->oper_channel != local->hw.conf.channel) || | 129 | if (local->oper_channel != local->hw.conf.channel || |
130 | (local->_oper_channel_type != local->hw.conf.channel_type)) | 130 | local->_oper_channel_type != local->hw.conf.channel_type) |
131 | return false; | 131 | return false; |
132 | 132 | ||
133 | return true; | 133 | return true; |
@@ -135,7 +135,7 @@ bool ieee80211_cfg_on_oper_channel(struct ieee80211_local *local) | |||
135 | 135 | ||
136 | int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) | 136 | int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) |
137 | { | 137 | { |
138 | struct ieee80211_channel *chan, *scan_chan; | 138 | struct ieee80211_channel *chan; |
139 | int ret = 0; | 139 | int ret = 0; |
140 | int power; | 140 | int power; |
141 | enum nl80211_channel_type channel_type; | 141 | enum nl80211_channel_type channel_type; |
@@ -143,14 +143,12 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) | |||
143 | 143 | ||
144 | might_sleep(); | 144 | might_sleep(); |
145 | 145 | ||
146 | scan_chan = local->scan_channel; | ||
147 | |||
148 | /* If this off-channel logic ever changes, ieee80211_on_oper_channel | 146 | /* If this off-channel logic ever changes, ieee80211_on_oper_channel |
149 | * may need to change as well. | 147 | * may need to change as well. |
150 | */ | 148 | */ |
151 | offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL; | 149 | offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL; |
152 | if (scan_chan) { | 150 | if (local->scan_channel) { |
153 | chan = scan_chan; | 151 | chan = local->scan_channel; |
154 | /* If scanning on oper channel, use whatever channel-type | 152 | /* If scanning on oper channel, use whatever channel-type |
155 | * is currently in use. | 153 | * is currently in use. |
156 | */ | 154 | */ |
@@ -159,7 +157,7 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) | |||
159 | else | 157 | else |
160 | channel_type = NL80211_CHAN_NO_HT; | 158 | channel_type = NL80211_CHAN_NO_HT; |
161 | } else if (local->tmp_channel) { | 159 | } else if (local->tmp_channel) { |
162 | chan = scan_chan = local->tmp_channel; | 160 | chan = local->tmp_channel; |
163 | channel_type = local->tmp_channel_type; | 161 | channel_type = local->tmp_channel_type; |
164 | } else { | 162 | } else { |
165 | chan = local->oper_channel; | 163 | chan = local->oper_channel; |
@@ -595,7 +593,10 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
595 | 593 | ||
596 | wiphy->flags |= WIPHY_FLAG_NETNS_OK | | 594 | wiphy->flags |= WIPHY_FLAG_NETNS_OK | |
597 | WIPHY_FLAG_4ADDR_AP | | 595 | WIPHY_FLAG_4ADDR_AP | |
598 | WIPHY_FLAG_4ADDR_STATION; | 596 | WIPHY_FLAG_4ADDR_STATION | |
597 | WIPHY_FLAG_REPORTS_OBSS; | ||
598 | |||
599 | wiphy->features = NL80211_FEATURE_SK_TX_STATUS; | ||
599 | 600 | ||
600 | if (!ops->set_key) | 601 | if (!ops->set_key) |
601 | wiphy->flags |= WIPHY_FLAG_IBSS_RSN; | 602 | wiphy->flags |= WIPHY_FLAG_IBSS_RSN; |
@@ -670,6 +671,11 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
670 | INIT_WORK(&local->sched_scan_stopped_work, | 671 | INIT_WORK(&local->sched_scan_stopped_work, |
671 | ieee80211_sched_scan_stopped_work); | 672 | ieee80211_sched_scan_stopped_work); |
672 | 673 | ||
674 | spin_lock_init(&local->ack_status_lock); | ||
675 | idr_init(&local->ack_status_frames); | ||
676 | /* preallocate at least one entry */ | ||
677 | idr_pre_get(&local->ack_status_frames, GFP_KERNEL); | ||
678 | |||
673 | sta_info_init(local); | 679 | sta_info_init(local); |
674 | 680 | ||
675 | for (i = 0; i < IEEE80211_MAX_QUEUES; i++) { | 681 | for (i = 0; i < IEEE80211_MAX_QUEUES; i++) { |
@@ -1045,6 +1051,13 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) | |||
1045 | } | 1051 | } |
1046 | EXPORT_SYMBOL(ieee80211_unregister_hw); | 1052 | EXPORT_SYMBOL(ieee80211_unregister_hw); |
1047 | 1053 | ||
1054 | static int ieee80211_free_ack_frame(int id, void *p, void *data) | ||
1055 | { | ||
1056 | WARN_ONCE(1, "Have pending ack frames!\n"); | ||
1057 | kfree_skb(p); | ||
1058 | return 0; | ||
1059 | } | ||
1060 | |||
1048 | void ieee80211_free_hw(struct ieee80211_hw *hw) | 1061 | void ieee80211_free_hw(struct ieee80211_hw *hw) |
1049 | { | 1062 | { |
1050 | struct ieee80211_local *local = hw_to_local(hw); | 1063 | struct ieee80211_local *local = hw_to_local(hw); |
@@ -1055,6 +1068,10 @@ void ieee80211_free_hw(struct ieee80211_hw *hw) | |||
1055 | if (local->wiphy_ciphers_allocated) | 1068 | if (local->wiphy_ciphers_allocated) |
1056 | kfree(local->hw.wiphy->cipher_suites); | 1069 | kfree(local->hw.wiphy->cipher_suites); |
1057 | 1070 | ||
1071 | idr_for_each(&local->ack_status_frames, | ||
1072 | ieee80211_free_ack_frame, NULL); | ||
1073 | idr_destroy(&local->ack_status_frames); | ||
1074 | |||
1058 | wiphy_free(local->hw.wiphy); | 1075 | wiphy_free(local->hw.wiphy); |
1059 | } | 1076 | } |
1060 | EXPORT_SYMBOL(ieee80211_free_hw); | 1077 | EXPORT_SYMBOL(ieee80211_free_hw); |
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index a7078fdba8ca..b3a125f60347 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c | |||
@@ -76,6 +76,7 @@ static void ieee80211_mesh_housekeeping_timer(unsigned long data) | |||
76 | bool mesh_matches_local(struct ieee802_11_elems *ie, struct ieee80211_sub_if_data *sdata) | 76 | bool mesh_matches_local(struct ieee802_11_elems *ie, struct ieee80211_sub_if_data *sdata) |
77 | { | 77 | { |
78 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; | 78 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; |
79 | struct ieee80211_local *local = sdata->local; | ||
79 | 80 | ||
80 | /* | 81 | /* |
81 | * As support for each feature is added, check for matching | 82 | * As support for each feature is added, check for matching |
@@ -87,15 +88,23 @@ bool mesh_matches_local(struct ieee802_11_elems *ie, struct ieee80211_sub_if_dat | |||
87 | * - MDA enabled | 88 | * - MDA enabled |
88 | * - Power management control on fc | 89 | * - Power management control on fc |
89 | */ | 90 | */ |
90 | if (ifmsh->mesh_id_len == ie->mesh_id_len && | 91 | if (!(ifmsh->mesh_id_len == ie->mesh_id_len && |
91 | memcmp(ifmsh->mesh_id, ie->mesh_id, ie->mesh_id_len) == 0 && | 92 | memcmp(ifmsh->mesh_id, ie->mesh_id, ie->mesh_id_len) == 0 && |
92 | (ifmsh->mesh_pp_id == ie->mesh_config->meshconf_psel) && | 93 | (ifmsh->mesh_pp_id == ie->mesh_config->meshconf_psel) && |
93 | (ifmsh->mesh_pm_id == ie->mesh_config->meshconf_pmetric) && | 94 | (ifmsh->mesh_pm_id == ie->mesh_config->meshconf_pmetric) && |
94 | (ifmsh->mesh_cc_id == ie->mesh_config->meshconf_congest) && | 95 | (ifmsh->mesh_cc_id == ie->mesh_config->meshconf_congest) && |
95 | (ifmsh->mesh_sp_id == ie->mesh_config->meshconf_synch) && | 96 | (ifmsh->mesh_sp_id == ie->mesh_config->meshconf_synch) && |
96 | (ifmsh->mesh_auth_id == ie->mesh_config->meshconf_auth)) | 97 | (ifmsh->mesh_auth_id == ie->mesh_config->meshconf_auth))) |
97 | return true; | 98 | goto mismatch; |
98 | 99 | ||
100 | /* disallow peering with mismatched channel types for now */ | ||
101 | if (ie->ht_info_elem && | ||
102 | (local->_oper_channel_type != | ||
103 | ieee80211_ht_info_to_channel_type(ie->ht_info_elem))) | ||
104 | goto mismatch; | ||
105 | |||
106 | return true; | ||
107 | mismatch: | ||
99 | return false; | 108 | return false; |
100 | } | 109 | } |
101 | 110 | ||
@@ -341,6 +350,49 @@ int mesh_add_ds_params_ie(struct sk_buff *skb, | |||
341 | return 0; | 350 | return 0; |
342 | } | 351 | } |
343 | 352 | ||
353 | int mesh_add_ht_cap_ie(struct sk_buff *skb, | ||
354 | struct ieee80211_sub_if_data *sdata) | ||
355 | { | ||
356 | struct ieee80211_local *local = sdata->local; | ||
357 | struct ieee80211_supported_band *sband; | ||
358 | u8 *pos; | ||
359 | |||
360 | sband = local->hw.wiphy->bands[local->oper_channel->band]; | ||
361 | if (!sband->ht_cap.ht_supported || | ||
362 | local->_oper_channel_type == NL80211_CHAN_NO_HT) | ||
363 | return 0; | ||
364 | |||
365 | if (skb_tailroom(skb) < 2 + sizeof(struct ieee80211_ht_cap)) | ||
366 | return -ENOMEM; | ||
367 | |||
368 | pos = skb_put(skb, 2 + sizeof(struct ieee80211_ht_cap)); | ||
369 | ieee80211_ie_build_ht_cap(pos, sband, sband->ht_cap.cap); | ||
370 | |||
371 | return 0; | ||
372 | } | ||
373 | |||
374 | int mesh_add_ht_info_ie(struct sk_buff *skb, | ||
375 | struct ieee80211_sub_if_data *sdata) | ||
376 | { | ||
377 | struct ieee80211_local *local = sdata->local; | ||
378 | struct ieee80211_channel *channel = local->oper_channel; | ||
379 | enum nl80211_channel_type channel_type = local->_oper_channel_type; | ||
380 | struct ieee80211_supported_band *sband = | ||
381 | local->hw.wiphy->bands[channel->band]; | ||
382 | struct ieee80211_sta_ht_cap *ht_cap = &sband->ht_cap; | ||
383 | u8 *pos; | ||
384 | |||
385 | if (!ht_cap->ht_supported || channel_type == NL80211_CHAN_NO_HT) | ||
386 | return 0; | ||
387 | |||
388 | if (skb_tailroom(skb) < 2 + sizeof(struct ieee80211_ht_info)) | ||
389 | return -ENOMEM; | ||
390 | |||
391 | pos = skb_put(skb, 2 + sizeof(struct ieee80211_ht_info)); | ||
392 | ieee80211_ie_build_ht_info(pos, ht_cap, channel, channel_type); | ||
393 | |||
394 | return 0; | ||
395 | } | ||
344 | static void ieee80211_mesh_path_timer(unsigned long data) | 396 | static void ieee80211_mesh_path_timer(unsigned long data) |
345 | { | 397 | { |
346 | struct ieee80211_sub_if_data *sdata = | 398 | struct ieee80211_sub_if_data *sdata = |
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h index 8c00e2d1d636..622cc96eb4de 100644 --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h | |||
@@ -31,6 +31,8 @@ | |||
31 | * @MESH_PATH_FIXED: the mesh path has been manually set and should not be | 31 | * @MESH_PATH_FIXED: the mesh path has been manually set and should not be |
32 | * modified | 32 | * modified |
33 | * @MESH_PATH_RESOLVED: the mesh path can has been resolved | 33 | * @MESH_PATH_RESOLVED: the mesh path can has been resolved |
34 | * @MESH_PATH_REQ_QUEUED: there is an unsent path request for this destination | ||
35 | * already queued up, waiting for the discovery process to start. | ||
34 | * | 36 | * |
35 | * MESH_PATH_RESOLVED is used by the mesh path timer to | 37 | * MESH_PATH_RESOLVED is used by the mesh path timer to |
36 | * decide when to stop or cancel the mesh path discovery. | 38 | * decide when to stop or cancel the mesh path discovery. |
@@ -41,6 +43,7 @@ enum mesh_path_flags { | |||
41 | MESH_PATH_SN_VALID = BIT(2), | 43 | MESH_PATH_SN_VALID = BIT(2), |
42 | MESH_PATH_FIXED = BIT(3), | 44 | MESH_PATH_FIXED = BIT(3), |
43 | MESH_PATH_RESOLVED = BIT(4), | 45 | MESH_PATH_RESOLVED = BIT(4), |
46 | MESH_PATH_REQ_QUEUED = BIT(5), | ||
44 | }; | 47 | }; |
45 | 48 | ||
46 | /** | 49 | /** |
@@ -212,6 +215,10 @@ int mesh_add_vendor_ies(struct sk_buff *skb, | |||
212 | struct ieee80211_sub_if_data *sdata); | 215 | struct ieee80211_sub_if_data *sdata); |
213 | int mesh_add_ds_params_ie(struct sk_buff *skb, | 216 | int mesh_add_ds_params_ie(struct sk_buff *skb, |
214 | struct ieee80211_sub_if_data *sdata); | 217 | struct ieee80211_sub_if_data *sdata); |
218 | int mesh_add_ht_cap_ie(struct sk_buff *skb, | ||
219 | struct ieee80211_sub_if_data *sdata); | ||
220 | int mesh_add_ht_info_ie(struct sk_buff *skb, | ||
221 | struct ieee80211_sub_if_data *sdata); | ||
215 | void mesh_rmc_free(struct ieee80211_sub_if_data *sdata); | 222 | void mesh_rmc_free(struct ieee80211_sub_if_data *sdata); |
216 | int mesh_rmc_init(struct ieee80211_sub_if_data *sdata); | 223 | int mesh_rmc_init(struct ieee80211_sub_if_data *sdata); |
217 | void ieee80211s_init(void); | 224 | void ieee80211s_init(void); |
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index 174040a42887..a7afb2d32def 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c | |||
@@ -113,20 +113,20 @@ static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags, | |||
113 | struct ieee80211_sub_if_data *sdata) | 113 | struct ieee80211_sub_if_data *sdata) |
114 | { | 114 | { |
115 | struct ieee80211_local *local = sdata->local; | 115 | struct ieee80211_local *local = sdata->local; |
116 | struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400); | 116 | struct sk_buff *skb; |
117 | struct ieee80211_mgmt *mgmt; | 117 | struct ieee80211_mgmt *mgmt; |
118 | u8 *pos; | 118 | u8 *pos, ie_len; |
119 | int ie_len; | 119 | int hdr_len = offsetof(struct ieee80211_mgmt, u.action.u.mesh_action) + |
120 | sizeof(mgmt->u.action.u.mesh_action); | ||
120 | 121 | ||
122 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + | ||
123 | hdr_len + | ||
124 | 2 + 37); /* max HWMP IE */ | ||
121 | if (!skb) | 125 | if (!skb) |
122 | return -1; | 126 | return -1; |
123 | skb_reserve(skb, local->hw.extra_tx_headroom); | 127 | skb_reserve(skb, local->hw.extra_tx_headroom); |
124 | /* 25 is the size of the common mgmt part (24) plus the size of the | 128 | mgmt = (struct ieee80211_mgmt *) skb_put(skb, hdr_len); |
125 | * common action part (1) | 129 | memset(mgmt, 0, hdr_len); |
126 | */ | ||
127 | mgmt = (struct ieee80211_mgmt *) | ||
128 | skb_put(skb, 25 + sizeof(mgmt->u.action.u.mesh_action)); | ||
129 | memset(mgmt, 0, 25 + sizeof(mgmt->u.action.u.mesh_action)); | ||
130 | mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | | 130 | mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | |
131 | IEEE80211_STYPE_ACTION); | 131 | IEEE80211_STYPE_ACTION); |
132 | 132 | ||
@@ -240,20 +240,20 @@ int mesh_path_error_tx(u8 ttl, u8 *target, __le32 target_sn, | |||
240 | struct ieee80211_sub_if_data *sdata) | 240 | struct ieee80211_sub_if_data *sdata) |
241 | { | 241 | { |
242 | struct ieee80211_local *local = sdata->local; | 242 | struct ieee80211_local *local = sdata->local; |
243 | struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400); | 243 | struct sk_buff *skb; |
244 | struct ieee80211_mgmt *mgmt; | 244 | struct ieee80211_mgmt *mgmt; |
245 | u8 *pos; | 245 | u8 *pos, ie_len; |
246 | int ie_len; | 246 | int hdr_len = offsetof(struct ieee80211_mgmt, u.action.u.mesh_action) + |
247 | sizeof(mgmt->u.action.u.mesh_action); | ||
247 | 248 | ||
249 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + | ||
250 | hdr_len + | ||
251 | 2 + 15 /* PERR IE */); | ||
248 | if (!skb) | 252 | if (!skb) |
249 | return -1; | 253 | return -1; |
250 | skb_reserve(skb, local->tx_headroom + local->hw.extra_tx_headroom); | 254 | skb_reserve(skb, local->tx_headroom + local->hw.extra_tx_headroom); |
251 | /* 25 is the size of the common mgmt part (24) plus the size of the | 255 | mgmt = (struct ieee80211_mgmt *) skb_put(skb, hdr_len); |
252 | * common action part (1) | 256 | memset(mgmt, 0, hdr_len); |
253 | */ | ||
254 | mgmt = (struct ieee80211_mgmt *) | ||
255 | skb_put(skb, 25 + sizeof(mgmt->u.action.u.mesh_action)); | ||
256 | memset(mgmt, 0, 25 + sizeof(mgmt->u.action.u.mesh_action)); | ||
257 | mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | | 257 | mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | |
258 | IEEE80211_STYPE_ACTION); | 258 | IEEE80211_STYPE_ACTION); |
259 | 259 | ||
@@ -867,9 +867,19 @@ static void mesh_queue_preq(struct mesh_path *mpath, u8 flags) | |||
867 | return; | 867 | return; |
868 | } | 868 | } |
869 | 869 | ||
870 | spin_lock_bh(&mpath->state_lock); | ||
871 | if (mpath->flags & MESH_PATH_REQ_QUEUED) { | ||
872 | spin_unlock_bh(&mpath->state_lock); | ||
873 | spin_unlock_bh(&ifmsh->mesh_preq_queue_lock); | ||
874 | return; | ||
875 | } | ||
876 | |||
870 | memcpy(preq_node->dst, mpath->dst, ETH_ALEN); | 877 | memcpy(preq_node->dst, mpath->dst, ETH_ALEN); |
871 | preq_node->flags = flags; | 878 | preq_node->flags = flags; |
872 | 879 | ||
880 | mpath->flags |= MESH_PATH_REQ_QUEUED; | ||
881 | spin_unlock_bh(&mpath->state_lock); | ||
882 | |||
873 | list_add_tail(&preq_node->list, &ifmsh->preq_queue.list); | 883 | list_add_tail(&preq_node->list, &ifmsh->preq_queue.list); |
874 | ++ifmsh->preq_queue_len; | 884 | ++ifmsh->preq_queue_len; |
875 | spin_unlock_bh(&ifmsh->mesh_preq_queue_lock); | 885 | spin_unlock_bh(&ifmsh->mesh_preq_queue_lock); |
@@ -921,6 +931,7 @@ void mesh_path_start_discovery(struct ieee80211_sub_if_data *sdata) | |||
921 | goto enddiscovery; | 931 | goto enddiscovery; |
922 | 932 | ||
923 | spin_lock_bh(&mpath->state_lock); | 933 | spin_lock_bh(&mpath->state_lock); |
934 | mpath->flags &= ~MESH_PATH_REQ_QUEUED; | ||
924 | if (preq_node->flags & PREQ_Q_F_START) { | 935 | if (preq_node->flags & PREQ_Q_F_START) { |
925 | if (mpath->flags & MESH_PATH_RESOLVING) { | 936 | if (mpath->flags & MESH_PATH_RESOLVING) { |
926 | spin_unlock_bh(&mpath->state_lock); | 937 | spin_unlock_bh(&mpath->state_lock); |
@@ -1028,11 +1039,11 @@ int mesh_nexthop_lookup(struct sk_buff *skb, | |||
1028 | mesh_queue_preq(mpath, PREQ_Q_F_START); | 1039 | mesh_queue_preq(mpath, PREQ_Q_F_START); |
1029 | } | 1040 | } |
1030 | 1041 | ||
1031 | if (skb_queue_len(&mpath->frame_queue) >= | 1042 | if (skb_queue_len(&mpath->frame_queue) >= MESH_FRAME_QUEUE_LEN) |
1032 | MESH_FRAME_QUEUE_LEN) | ||
1033 | skb_to_free = skb_dequeue(&mpath->frame_queue); | 1043 | skb_to_free = skb_dequeue(&mpath->frame_queue); |
1034 | 1044 | ||
1035 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; | 1045 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; |
1046 | ieee80211_set_qos_hdr(sdata, skb); | ||
1036 | skb_queue_tail(&mpath->frame_queue, skb); | 1047 | skb_queue_tail(&mpath->frame_queue, skb); |
1037 | if (skb_to_free) | 1048 | if (skb_to_free) |
1038 | mesh_path_discard_frame(skb_to_free, sdata); | 1049 | mesh_path_discard_frame(skb_to_free, sdata); |
@@ -1061,6 +1072,7 @@ void mesh_path_timer(unsigned long data) | |||
1061 | } else if (mpath->discovery_retries < max_preq_retries(sdata)) { | 1072 | } else if (mpath->discovery_retries < max_preq_retries(sdata)) { |
1062 | ++mpath->discovery_retries; | 1073 | ++mpath->discovery_retries; |
1063 | mpath->discovery_timeout *= 2; | 1074 | mpath->discovery_timeout *= 2; |
1075 | mpath->flags &= ~MESH_PATH_REQ_QUEUED; | ||
1064 | spin_unlock_bh(&mpath->state_lock); | 1076 | spin_unlock_bh(&mpath->state_lock); |
1065 | mesh_queue_preq(mpath, 0); | 1077 | mesh_queue_preq(mpath, 0); |
1066 | } else { | 1078 | } else { |
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index 7f54c5042235..4fc23d1b9c3a 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c | |||
@@ -213,7 +213,6 @@ void mesh_path_assign_nexthop(struct mesh_path *mpath, struct sta_info *sta) | |||
213 | struct ieee80211_hdr *hdr; | 213 | struct ieee80211_hdr *hdr; |
214 | struct sk_buff_head tmpq; | 214 | struct sk_buff_head tmpq; |
215 | unsigned long flags; | 215 | unsigned long flags; |
216 | struct ieee80211_sub_if_data *sdata = mpath->sdata; | ||
217 | 216 | ||
218 | rcu_assign_pointer(mpath->next_hop, sta); | 217 | rcu_assign_pointer(mpath->next_hop, sta); |
219 | 218 | ||
@@ -224,8 +223,6 @@ void mesh_path_assign_nexthop(struct mesh_path *mpath, struct sta_info *sta) | |||
224 | while ((skb = __skb_dequeue(&mpath->frame_queue)) != NULL) { | 223 | while ((skb = __skb_dequeue(&mpath->frame_queue)) != NULL) { |
225 | hdr = (struct ieee80211_hdr *) skb->data; | 224 | hdr = (struct ieee80211_hdr *) skb->data; |
226 | memcpy(hdr->addr1, sta->sta.addr, ETH_ALEN); | 225 | memcpy(hdr->addr1, sta->sta.addr, ETH_ALEN); |
227 | skb_set_queue_mapping(skb, ieee80211_select_queue(sdata, skb)); | ||
228 | ieee80211_set_qos_hdr(sdata, skb); | ||
229 | __skb_queue_tail(&tmpq, skb); | 226 | __skb_queue_tail(&tmpq, skb); |
230 | } | 227 | } |
231 | 228 | ||
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index 7e57f5d07f66..0140e88a8220 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c | |||
@@ -80,11 +80,15 @@ static inline void mesh_plink_fsm_restart(struct sta_info *sta) | |||
80 | * on it in the lifecycle management section! | 80 | * on it in the lifecycle management section! |
81 | */ | 81 | */ |
82 | static struct sta_info *mesh_plink_alloc(struct ieee80211_sub_if_data *sdata, | 82 | static struct sta_info *mesh_plink_alloc(struct ieee80211_sub_if_data *sdata, |
83 | u8 *hw_addr, u32 rates) | 83 | u8 *hw_addr, u32 rates, |
84 | struct ieee802_11_elems *elems) | ||
84 | { | 85 | { |
85 | struct ieee80211_local *local = sdata->local; | 86 | struct ieee80211_local *local = sdata->local; |
87 | struct ieee80211_supported_band *sband; | ||
86 | struct sta_info *sta; | 88 | struct sta_info *sta; |
87 | 89 | ||
90 | sband = local->hw.wiphy->bands[local->oper_channel->band]; | ||
91 | |||
88 | if (local->num_sta >= MESH_MAX_PLINKS) | 92 | if (local->num_sta >= MESH_MAX_PLINKS) |
89 | return NULL; | 93 | return NULL; |
90 | 94 | ||
@@ -96,6 +100,9 @@ static struct sta_info *mesh_plink_alloc(struct ieee80211_sub_if_data *sdata, | |||
96 | set_sta_flag(sta, WLAN_STA_AUTHORIZED); | 100 | set_sta_flag(sta, WLAN_STA_AUTHORIZED); |
97 | set_sta_flag(sta, WLAN_STA_WME); | 101 | set_sta_flag(sta, WLAN_STA_WME); |
98 | sta->sta.supp_rates[local->hw.conf.channel->band] = rates; | 102 | sta->sta.supp_rates[local->hw.conf.channel->band] = rates; |
103 | if (elems->ht_cap_elem) | ||
104 | ieee80211_ht_cap_ie_to_sta_ht_cap(sband, elems->ht_cap_elem, | ||
105 | &sta->sta.ht_cap); | ||
99 | rate_control_rate_init(sta); | 106 | rate_control_rate_init(sta); |
100 | 107 | ||
101 | return sta; | 108 | return sta; |
@@ -153,23 +160,31 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, | |||
153 | enum ieee80211_self_protected_actioncode action, | 160 | enum ieee80211_self_protected_actioncode action, |
154 | u8 *da, __le16 llid, __le16 plid, __le16 reason) { | 161 | u8 *da, __le16 llid, __le16 plid, __le16 reason) { |
155 | struct ieee80211_local *local = sdata->local; | 162 | struct ieee80211_local *local = sdata->local; |
156 | struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400 + | 163 | struct sk_buff *skb; |
157 | sdata->u.mesh.ie_len); | ||
158 | struct ieee80211_mgmt *mgmt; | 164 | struct ieee80211_mgmt *mgmt; |
159 | bool include_plid = false; | 165 | bool include_plid = false; |
160 | int ie_len = 4; | ||
161 | u16 peering_proto = 0; | 166 | u16 peering_proto = 0; |
162 | u8 *pos; | 167 | u8 *pos, ie_len = 4; |
163 | 168 | int hdr_len = offsetof(struct ieee80211_mgmt, u.action.u.self_prot) + | |
169 | sizeof(mgmt->u.action.u.self_prot); | ||
170 | |||
171 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + | ||
172 | hdr_len + | ||
173 | 2 + /* capability info */ | ||
174 | 2 + /* AID */ | ||
175 | 2 + 8 + /* supported rates */ | ||
176 | 2 + (IEEE80211_MAX_SUPP_RATES - 8) + | ||
177 | 2 + sdata->u.mesh.mesh_id_len + | ||
178 | 2 + sizeof(struct ieee80211_meshconf_ie) + | ||
179 | 2 + sizeof(struct ieee80211_ht_cap) + | ||
180 | 2 + sizeof(struct ieee80211_ht_info) + | ||
181 | 2 + 8 + /* peering IE */ | ||
182 | sdata->u.mesh.ie_len); | ||
164 | if (!skb) | 183 | if (!skb) |
165 | return -1; | 184 | return -1; |
166 | skb_reserve(skb, local->hw.extra_tx_headroom); | 185 | skb_reserve(skb, local->hw.extra_tx_headroom); |
167 | /* 25 is the size of the common mgmt part (24) plus the size of the | 186 | mgmt = (struct ieee80211_mgmt *) skb_put(skb, hdr_len); |
168 | * common action part (1) | 187 | memset(mgmt, 0, hdr_len); |
169 | */ | ||
170 | mgmt = (struct ieee80211_mgmt *) | ||
171 | skb_put(skb, 25 + sizeof(mgmt->u.action.u.self_prot)); | ||
172 | memset(mgmt, 0, 25 + sizeof(mgmt->u.action.u.self_prot)); | ||
173 | mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | | 188 | mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | |
174 | IEEE80211_STYPE_ACTION); | 189 | IEEE80211_STYPE_ACTION); |
175 | memcpy(mgmt->da, da, ETH_ALEN); | 190 | memcpy(mgmt->da, da, ETH_ALEN); |
@@ -235,6 +250,13 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, | |||
235 | memcpy(pos, &reason, 2); | 250 | memcpy(pos, &reason, 2); |
236 | pos += 2; | 251 | pos += 2; |
237 | } | 252 | } |
253 | |||
254 | if (action != WLAN_SP_MESH_PEERING_CLOSE) { | ||
255 | if (mesh_add_ht_cap_ie(skb, sdata) || | ||
256 | mesh_add_ht_info_ie(skb, sdata)) | ||
257 | return -1; | ||
258 | } | ||
259 | |||
238 | if (mesh_add_vendor_ies(skb, sdata)) | 260 | if (mesh_add_vendor_ies(skb, sdata)) |
239 | return -1; | 261 | return -1; |
240 | 262 | ||
@@ -261,7 +283,7 @@ void mesh_neighbour_update(u8 *hw_addr, u32 rates, | |||
261 | elems->ie_start, elems->total_len, | 283 | elems->ie_start, elems->total_len, |
262 | GFP_KERNEL); | 284 | GFP_KERNEL); |
263 | else | 285 | else |
264 | sta = mesh_plink_alloc(sdata, hw_addr, rates); | 286 | sta = mesh_plink_alloc(sdata, hw_addr, rates, elems); |
265 | if (!sta) | 287 | if (!sta) |
266 | return; | 288 | return; |
267 | if (sta_info_insert_rcu(sta)) { | 289 | if (sta_info_insert_rcu(sta)) { |
@@ -552,7 +574,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m | |||
552 | } | 574 | } |
553 | 575 | ||
554 | rates = ieee80211_sta_get_rates(local, &elems, rx_status->band); | 576 | rates = ieee80211_sta_get_rates(local, &elems, rx_status->band); |
555 | sta = mesh_plink_alloc(sdata, mgmt->sa, rates); | 577 | sta = mesh_plink_alloc(sdata, mgmt->sa, rates, &elems); |
556 | if (!sta) { | 578 | if (!sta) { |
557 | mpl_dbg("Mesh plink error: plink table full\n"); | 579 | mpl_dbg("Mesh plink error: plink table full\n"); |
558 | return; | 580 | return; |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 72c8bea81a6c..341e18344679 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -1468,6 +1468,47 @@ ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata, | |||
1468 | return RX_MGMT_CFG80211_DISASSOC; | 1468 | return RX_MGMT_CFG80211_DISASSOC; |
1469 | } | 1469 | } |
1470 | 1470 | ||
1471 | static void ieee80211_get_rates(struct ieee80211_supported_band *sband, | ||
1472 | u8 *supp_rates, unsigned int supp_rates_len, | ||
1473 | u32 *rates, u32 *basic_rates, | ||
1474 | bool *have_higher_than_11mbit, | ||
1475 | int *min_rate, int *min_rate_index) | ||
1476 | { | ||
1477 | int i, j; | ||
1478 | |||
1479 | for (i = 0; i < supp_rates_len; i++) { | ||
1480 | int rate = (supp_rates[i] & 0x7f) * 5; | ||
1481 | bool is_basic = !!(supp_rates[i] & 0x80); | ||
1482 | |||
1483 | if (rate > 110) | ||
1484 | *have_higher_than_11mbit = true; | ||
1485 | |||
1486 | /* | ||
1487 | * BSS_MEMBERSHIP_SELECTOR_HT_PHY is defined in 802.11n-2009 | ||
1488 | * 7.3.2.2 as a magic value instead of a rate. Hence, skip it. | ||
1489 | * | ||
1490 | * Note: Even through the membership selector and the basic | ||
1491 | * rate flag share the same bit, they are not exactly | ||
1492 | * the same. | ||
1493 | */ | ||
1494 | if (!!(supp_rates[i] & 0x80) && | ||
1495 | (supp_rates[i] & 0x7f) == BSS_MEMBERSHIP_SELECTOR_HT_PHY) | ||
1496 | continue; | ||
1497 | |||
1498 | for (j = 0; j < sband->n_bitrates; j++) { | ||
1499 | if (sband->bitrates[j].bitrate == rate) { | ||
1500 | *rates |= BIT(j); | ||
1501 | if (is_basic) | ||
1502 | *basic_rates |= BIT(j); | ||
1503 | if (rate < *min_rate) { | ||
1504 | *min_rate = rate; | ||
1505 | *min_rate_index = j; | ||
1506 | } | ||
1507 | break; | ||
1508 | } | ||
1509 | } | ||
1510 | } | ||
1511 | } | ||
1471 | 1512 | ||
1472 | static bool ieee80211_assoc_success(struct ieee80211_work *wk, | 1513 | static bool ieee80211_assoc_success(struct ieee80211_work *wk, |
1473 | struct ieee80211_mgmt *mgmt, size_t len) | 1514 | struct ieee80211_mgmt *mgmt, size_t len) |
@@ -1484,9 +1525,10 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk, | |||
1484 | struct ieee802_11_elems elems; | 1525 | struct ieee802_11_elems elems; |
1485 | struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf; | 1526 | struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf; |
1486 | u32 changed = 0; | 1527 | u32 changed = 0; |
1487 | int i, j, err; | 1528 | int err; |
1488 | bool have_higher_than_11mbit = false; | 1529 | bool have_higher_than_11mbit = false; |
1489 | u16 ap_ht_cap_flags; | 1530 | u16 ap_ht_cap_flags; |
1531 | int min_rate = INT_MAX, min_rate_index = -1; | ||
1490 | 1532 | ||
1491 | /* AssocResp and ReassocResp have identical structure */ | 1533 | /* AssocResp and ReassocResp have identical structure */ |
1492 | 1534 | ||
@@ -1541,38 +1583,23 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk, | |||
1541 | basic_rates = 0; | 1583 | basic_rates = 0; |
1542 | sband = local->hw.wiphy->bands[wk->chan->band]; | 1584 | sband = local->hw.wiphy->bands[wk->chan->band]; |
1543 | 1585 | ||
1544 | for (i = 0; i < elems.supp_rates_len; i++) { | 1586 | ieee80211_get_rates(sband, elems.supp_rates, elems.supp_rates_len, |
1545 | int rate = (elems.supp_rates[i] & 0x7f) * 5; | 1587 | &rates, &basic_rates, &have_higher_than_11mbit, |
1546 | bool is_basic = !!(elems.supp_rates[i] & 0x80); | 1588 | &min_rate, &min_rate_index); |
1547 | |||
1548 | if (rate > 110) | ||
1549 | have_higher_than_11mbit = true; | ||
1550 | |||
1551 | for (j = 0; j < sband->n_bitrates; j++) { | ||
1552 | if (sband->bitrates[j].bitrate == rate) { | ||
1553 | rates |= BIT(j); | ||
1554 | if (is_basic) | ||
1555 | basic_rates |= BIT(j); | ||
1556 | break; | ||
1557 | } | ||
1558 | } | ||
1559 | } | ||
1560 | 1589 | ||
1561 | for (i = 0; i < elems.ext_supp_rates_len; i++) { | 1590 | ieee80211_get_rates(sband, elems.ext_supp_rates, |
1562 | int rate = (elems.ext_supp_rates[i] & 0x7f) * 5; | 1591 | elems.ext_supp_rates_len, &rates, &basic_rates, |
1563 | bool is_basic = !!(elems.ext_supp_rates[i] & 0x80); | 1592 | &have_higher_than_11mbit, |
1593 | &min_rate, &min_rate_index); | ||
1564 | 1594 | ||
1565 | if (rate > 110) | 1595 | /* |
1566 | have_higher_than_11mbit = true; | 1596 | * some buggy APs don't advertise basic_rates. use the lowest |
1567 | 1597 | * supported rate instead. | |
1568 | for (j = 0; j < sband->n_bitrates; j++) { | 1598 | */ |
1569 | if (sband->bitrates[j].bitrate == rate) { | 1599 | if (unlikely(!basic_rates) && min_rate_index >= 0) { |
1570 | rates |= BIT(j); | 1600 | printk(KERN_DEBUG "%s: No basic rates in AssocResp. " |
1571 | if (is_basic) | 1601 | "Using min supported rate instead.\n", sdata->name); |
1572 | basic_rates |= BIT(j); | 1602 | basic_rates = BIT(min_rate_index); |
1573 | break; | ||
1574 | } | ||
1575 | } | ||
1576 | } | 1603 | } |
1577 | 1604 | ||
1578 | sta->sta.supp_rates[wk->chan->band] = rates; | 1605 | sta->sta.supp_rates[wk->chan->band] = rates; |
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c index 9ee7164b207c..596efaf50e09 100644 --- a/net/mac80211/pm.c +++ b/net/mac80211/pm.c | |||
@@ -125,7 +125,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) | |||
125 | ieee80211_bss_info_change_notify(sdata, | 125 | ieee80211_bss_info_change_notify(sdata, |
126 | BSS_CHANGED_BEACON_ENABLED); | 126 | BSS_CHANGED_BEACON_ENABLED); |
127 | 127 | ||
128 | drv_remove_interface(local, &sdata->vif); | 128 | drv_remove_interface(local, sdata); |
129 | } | 129 | } |
130 | 130 | ||
131 | /* stop hardware - this must stop RX */ | 131 | /* stop hardware - this must stop RX */ |
diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c index 58a89554b788..b39dda523f39 100644 --- a/net/mac80211/rc80211_minstrel.c +++ b/net/mac80211/rc80211_minstrel.c | |||
@@ -334,8 +334,8 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta, | |||
334 | 334 | ||
335 | 335 | ||
336 | static void | 336 | static void |
337 | calc_rate_durations(struct minstrel_sta_info *mi, struct ieee80211_local *local, | 337 | calc_rate_durations(struct ieee80211_local *local, struct minstrel_rate *d, |
338 | struct minstrel_rate *d, struct ieee80211_rate *rate) | 338 | struct ieee80211_rate *rate) |
339 | { | 339 | { |
340 | int erp = !!(rate->flags & IEEE80211_RATE_ERP_G); | 340 | int erp = !!(rate->flags & IEEE80211_RATE_ERP_G); |
341 | 341 | ||
@@ -402,8 +402,7 @@ minstrel_rate_init(void *priv, struct ieee80211_supported_band *sband, | |||
402 | 402 | ||
403 | mr->rix = i; | 403 | mr->rix = i; |
404 | mr->bitrate = sband->bitrates[i].bitrate / 5; | 404 | mr->bitrate = sband->bitrates[i].bitrate / 5; |
405 | calc_rate_durations(mi, local, mr, | 405 | calc_rate_durations(local, mr, &sband->bitrates[i]); |
406 | &sband->bitrates[i]); | ||
407 | 406 | ||
408 | /* calculate maximum number of retransmissions before | 407 | /* calculate maximum number of retransmissions before |
409 | * fallback (based on maximum segment size) */ | 408 | * fallback (based on maximum segment size) */ |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index bb53726cb04a..4eafbfd891d5 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -745,10 +745,11 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx) | |||
745 | struct ieee80211_local *local = rx->local; | 745 | struct ieee80211_local *local = rx->local; |
746 | struct ieee80211_hw *hw = &local->hw; | 746 | struct ieee80211_hw *hw = &local->hw; |
747 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 747 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
748 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | ||
748 | struct sta_info *sta = rx->sta; | 749 | struct sta_info *sta = rx->sta; |
749 | struct tid_ampdu_rx *tid_agg_rx; | 750 | struct tid_ampdu_rx *tid_agg_rx; |
750 | u16 sc; | 751 | u16 sc; |
751 | int tid; | 752 | u8 tid, ack_policy; |
752 | 753 | ||
753 | if (!ieee80211_is_data_qos(hdr->frame_control)) | 754 | if (!ieee80211_is_data_qos(hdr->frame_control)) |
754 | goto dont_reorder; | 755 | goto dont_reorder; |
@@ -761,6 +762,8 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx) | |||
761 | if (!sta) | 762 | if (!sta) |
762 | goto dont_reorder; | 763 | goto dont_reorder; |
763 | 764 | ||
765 | ack_policy = *ieee80211_get_qos_ctl(hdr) & | ||
766 | IEEE80211_QOS_CTL_ACK_POLICY_MASK; | ||
764 | tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK; | 767 | tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK; |
765 | 768 | ||
766 | tid_agg_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[tid]); | 769 | tid_agg_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[tid]); |
@@ -771,6 +774,15 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx) | |||
771 | if (unlikely(hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_NULLFUNC))) | 774 | if (unlikely(hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_NULLFUNC))) |
772 | goto dont_reorder; | 775 | goto dont_reorder; |
773 | 776 | ||
777 | /* not part of a BA session */ | ||
778 | if (ack_policy != IEEE80211_QOS_CTL_ACK_POLICY_BLOCKACK && | ||
779 | ack_policy != IEEE80211_QOS_CTL_ACK_POLICY_NORMAL) | ||
780 | goto dont_reorder; | ||
781 | |||
782 | /* not actually part of this BA session */ | ||
783 | if (!(status->rx_flags & IEEE80211_RX_RA_MATCH)) | ||
784 | goto dont_reorder; | ||
785 | |||
774 | /* new, potentially un-ordered, ampdu frame - process it */ | 786 | /* new, potentially un-ordered, ampdu frame - process it */ |
775 | 787 | ||
776 | /* reset session timer */ | 788 | /* reset session timer */ |
@@ -855,6 +867,13 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx) | |||
855 | rx->sdata->control_port_protocol) | 867 | rx->sdata->control_port_protocol) |
856 | return RX_CONTINUE; | 868 | return RX_CONTINUE; |
857 | } | 869 | } |
870 | |||
871 | if (rx->sdata->vif.type == NL80211_IFTYPE_AP && | ||
872 | cfg80211_rx_spurious_frame(rx->sdata->dev, | ||
873 | hdr->addr2, | ||
874 | GFP_ATOMIC)) | ||
875 | return RX_DROP_UNUSABLE; | ||
876 | |||
858 | return RX_DROP_MONITOR; | 877 | return RX_DROP_MONITOR; |
859 | } | 878 | } |
860 | 879 | ||
@@ -1324,15 +1343,20 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) | |||
1324 | 1343 | ||
1325 | /* | 1344 | /* |
1326 | * If we receive a 4-addr nullfunc frame from a STA | 1345 | * If we receive a 4-addr nullfunc frame from a STA |
1327 | * that was not moved to a 4-addr STA vlan yet, drop | 1346 | * that was not moved to a 4-addr STA vlan yet send |
1328 | * the frame to the monitor interface, to make sure | 1347 | * the event to userspace and for older hostapd drop |
1329 | * that hostapd sees it | 1348 | * the frame to the monitor interface. |
1330 | */ | 1349 | */ |
1331 | if (ieee80211_has_a4(hdr->frame_control) && | 1350 | if (ieee80211_has_a4(hdr->frame_control) && |
1332 | (rx->sdata->vif.type == NL80211_IFTYPE_AP || | 1351 | (rx->sdata->vif.type == NL80211_IFTYPE_AP || |
1333 | (rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN && | 1352 | (rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN && |
1334 | !rx->sdata->u.vlan.sta))) | 1353 | !rx->sdata->u.vlan.sta))) { |
1354 | if (!test_and_set_sta_flag(sta, WLAN_STA_4ADDR_EVENT)) | ||
1355 | cfg80211_rx_unexpected_4addr_frame( | ||
1356 | rx->sdata->dev, sta->sta.addr, | ||
1357 | GFP_ATOMIC); | ||
1335 | return RX_DROP_MONITOR; | 1358 | return RX_DROP_MONITOR; |
1359 | } | ||
1336 | /* | 1360 | /* |
1337 | * Update counter and free packet here to avoid | 1361 | * Update counter and free packet here to avoid |
1338 | * counting this as a dropped packed. | 1362 | * counting this as a dropped packed. |
@@ -1930,6 +1954,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) | |||
1930 | compare_ether_addr(sdata->vif.addr, hdr->addr3) == 0) | 1954 | compare_ether_addr(sdata->vif.addr, hdr->addr3) == 0) |
1931 | return RX_CONTINUE; | 1955 | return RX_CONTINUE; |
1932 | 1956 | ||
1957 | skb_set_queue_mapping(skb, ieee80211_select_queue(sdata, skb)); | ||
1933 | mesh_hdr->ttl--; | 1958 | mesh_hdr->ttl--; |
1934 | 1959 | ||
1935 | if (status->rx_flags & IEEE80211_RX_RA_MATCH) { | 1960 | if (status->rx_flags & IEEE80211_RX_RA_MATCH) { |
@@ -1954,12 +1979,10 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) | |||
1954 | memset(info, 0, sizeof(*info)); | 1979 | memset(info, 0, sizeof(*info)); |
1955 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; | 1980 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; |
1956 | info->control.vif = &rx->sdata->vif; | 1981 | info->control.vif = &rx->sdata->vif; |
1982 | info->control.jiffies = jiffies; | ||
1957 | if (is_multicast_ether_addr(fwd_hdr->addr1)) { | 1983 | if (is_multicast_ether_addr(fwd_hdr->addr1)) { |
1958 | IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh, | 1984 | IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh, |
1959 | fwded_mcast); | 1985 | fwded_mcast); |
1960 | skb_set_queue_mapping(fwd_skb, | ||
1961 | ieee80211_select_queue(sdata, fwd_skb)); | ||
1962 | ieee80211_set_qos_hdr(sdata, fwd_skb); | ||
1963 | } else { | 1986 | } else { |
1964 | int err; | 1987 | int err; |
1965 | /* | 1988 | /* |
@@ -2011,12 +2034,17 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx) | |||
2011 | return RX_DROP_MONITOR; | 2034 | return RX_DROP_MONITOR; |
2012 | 2035 | ||
2013 | /* | 2036 | /* |
2014 | * Allow the cooked monitor interface of an AP to see 4-addr frames so | 2037 | * Send unexpected-4addr-frame event to hostapd. For older versions, |
2015 | * that a 4-addr station can be detected and moved into a separate VLAN | 2038 | * also drop the frame to cooked monitor interfaces. |
2016 | */ | 2039 | */ |
2017 | if (ieee80211_has_a4(hdr->frame_control) && | 2040 | if (ieee80211_has_a4(hdr->frame_control) && |
2018 | sdata->vif.type == NL80211_IFTYPE_AP) | 2041 | sdata->vif.type == NL80211_IFTYPE_AP) { |
2042 | if (rx->sta && | ||
2043 | !test_and_set_sta_flag(rx->sta, WLAN_STA_4ADDR_EVENT)) | ||
2044 | cfg80211_rx_unexpected_4addr_frame( | ||
2045 | rx->sdata->dev, rx->sta->sta.addr, GFP_ATOMIC); | ||
2019 | return RX_DROP_MONITOR; | 2046 | return RX_DROP_MONITOR; |
2047 | } | ||
2020 | 2048 | ||
2021 | err = __ieee80211_data_to_8023(rx, &port_control); | 2049 | err = __ieee80211_data_to_8023(rx, &port_control); |
2022 | if (unlikely(err)) | 2050 | if (unlikely(err)) |
@@ -2171,6 +2199,18 @@ ieee80211_rx_h_mgmt_check(struct ieee80211_rx_data *rx) | |||
2171 | if (!ieee80211_is_mgmt(mgmt->frame_control)) | 2199 | if (!ieee80211_is_mgmt(mgmt->frame_control)) |
2172 | return RX_DROP_MONITOR; | 2200 | return RX_DROP_MONITOR; |
2173 | 2201 | ||
2202 | if (rx->sdata->vif.type == NL80211_IFTYPE_AP && | ||
2203 | ieee80211_is_beacon(mgmt->frame_control) && | ||
2204 | !(rx->flags & IEEE80211_RX_BEACON_REPORTED)) { | ||
2205 | struct ieee80211_rx_status *status; | ||
2206 | |||
2207 | status = IEEE80211_SKB_RXCB(rx->skb); | ||
2208 | cfg80211_report_obss_beacon(rx->local->hw.wiphy, | ||
2209 | rx->skb->data, rx->skb->len, | ||
2210 | status->freq, GFP_ATOMIC); | ||
2211 | rx->flags |= IEEE80211_RX_BEACON_REPORTED; | ||
2212 | } | ||
2213 | |||
2174 | if (!(status->rx_flags & IEEE80211_RX_RA_MATCH)) | 2214 | if (!(status->rx_flags & IEEE80211_RX_RA_MATCH)) |
2175 | return RX_DROP_MONITOR; | 2215 | return RX_DROP_MONITOR; |
2176 | 2216 | ||
@@ -2204,13 +2244,8 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) | |||
2204 | 2244 | ||
2205 | switch (mgmt->u.action.category) { | 2245 | switch (mgmt->u.action.category) { |
2206 | case WLAN_CATEGORY_BACK: | 2246 | case WLAN_CATEGORY_BACK: |
2207 | /* | ||
2208 | * The aggregation code is not prepared to handle | ||
2209 | * anything but STA/AP due to the BSSID handling; | ||
2210 | * IBSS could work in the code but isn't supported | ||
2211 | * by drivers or the standard. | ||
2212 | */ | ||
2213 | if (sdata->vif.type != NL80211_IFTYPE_STATION && | 2247 | if (sdata->vif.type != NL80211_IFTYPE_STATION && |
2248 | sdata->vif.type != NL80211_IFTYPE_MESH_POINT && | ||
2214 | sdata->vif.type != NL80211_IFTYPE_AP_VLAN && | 2249 | sdata->vif.type != NL80211_IFTYPE_AP_VLAN && |
2215 | sdata->vif.type != NL80211_IFTYPE_AP) | 2250 | sdata->vif.type != NL80211_IFTYPE_AP) |
2216 | break; | 2251 | break; |
@@ -2490,6 +2525,10 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx, | |||
2490 | goto out_free_skb; | 2525 | goto out_free_skb; |
2491 | rx->flags |= IEEE80211_RX_CMNTR; | 2526 | rx->flags |= IEEE80211_RX_CMNTR; |
2492 | 2527 | ||
2528 | /* If there are no cooked monitor interfaces, just free the SKB */ | ||
2529 | if (!local->cooked_mntrs) | ||
2530 | goto out_free_skb; | ||
2531 | |||
2493 | if (skb_headroom(skb) < sizeof(*rthdr) && | 2532 | if (skb_headroom(skb) < sizeof(*rthdr) && |
2494 | pskb_expand_head(skb, sizeof(*rthdr), 0, GFP_ATOMIC)) | 2533 | pskb_expand_head(skb, sizeof(*rthdr), 0, GFP_ATOMIC)) |
2495 | goto out_free_skb; | 2534 | goto out_free_skb; |
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 105436dbb90d..81863031e0a3 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
@@ -213,12 +213,7 @@ ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb) | |||
213 | if (bss) | 213 | if (bss) |
214 | ieee80211_rx_bss_put(sdata->local, bss); | 214 | ieee80211_rx_bss_put(sdata->local, bss); |
215 | 215 | ||
216 | /* If we are on-operating-channel, and this packet is for the | 216 | if (channel == sdata->local->oper_channel) |
217 | * current channel, pass the pkt on up the stack so that | ||
218 | * the rest of the stack can make use of it. | ||
219 | */ | ||
220 | if (ieee80211_cfg_on_oper_channel(sdata->local) | ||
221 | && (channel == sdata->local->oper_channel)) | ||
222 | return RX_CONTINUE; | 217 | return RX_CONTINUE; |
223 | 218 | ||
224 | dev_kfree_skb(skb); | 219 | dev_kfree_skb(skb); |
@@ -264,8 +259,6 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted, | |||
264 | bool was_hw_scan) | 259 | bool was_hw_scan) |
265 | { | 260 | { |
266 | struct ieee80211_local *local = hw_to_local(hw); | 261 | struct ieee80211_local *local = hw_to_local(hw); |
267 | bool on_oper_chan; | ||
268 | bool enable_beacons = false; | ||
269 | 262 | ||
270 | lockdep_assert_held(&local->mtx); | 263 | lockdep_assert_held(&local->mtx); |
271 | 264 | ||
@@ -298,25 +291,13 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted, | |||
298 | local->scanning = 0; | 291 | local->scanning = 0; |
299 | local->scan_channel = NULL; | 292 | local->scan_channel = NULL; |
300 | 293 | ||
301 | on_oper_chan = ieee80211_cfg_on_oper_channel(local); | 294 | /* Set power back to normal operating levels. */ |
302 | 295 | ieee80211_hw_config(local, 0); | |
303 | if (was_hw_scan || !on_oper_chan) | ||
304 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); | ||
305 | else | ||
306 | /* Set power back to normal operating levels. */ | ||
307 | ieee80211_hw_config(local, 0); | ||
308 | 296 | ||
309 | if (!was_hw_scan) { | 297 | if (!was_hw_scan) { |
310 | bool on_oper_chan2; | ||
311 | ieee80211_configure_filter(local); | 298 | ieee80211_configure_filter(local); |
312 | drv_sw_scan_complete(local); | 299 | drv_sw_scan_complete(local); |
313 | on_oper_chan2 = ieee80211_cfg_on_oper_channel(local); | 300 | ieee80211_offchannel_return(local, true, true); |
314 | /* We should always be on-channel at this point. */ | ||
315 | WARN_ON(!on_oper_chan2); | ||
316 | if (on_oper_chan2 && (on_oper_chan != on_oper_chan2)) | ||
317 | enable_beacons = true; | ||
318 | |||
319 | ieee80211_offchannel_return(local, enable_beacons, true); | ||
320 | } | 301 | } |
321 | 302 | ||
322 | ieee80211_recalc_idle(local); | 303 | ieee80211_recalc_idle(local); |
@@ -361,11 +342,7 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local) | |||
361 | local->next_scan_state = SCAN_DECISION; | 342 | local->next_scan_state = SCAN_DECISION; |
362 | local->scan_channel_idx = 0; | 343 | local->scan_channel_idx = 0; |
363 | 344 | ||
364 | /* We always want to use off-channel PS, even if we | 345 | ieee80211_offchannel_stop_vifs(local, true); |
365 | * are not really leaving oper-channel. Don't | ||
366 | * tell the AP though, as long as we are on-channel. | ||
367 | */ | ||
368 | ieee80211_offchannel_enable_all_ps(local, false); | ||
369 | 346 | ||
370 | ieee80211_configure_filter(local); | 347 | ieee80211_configure_filter(local); |
371 | 348 | ||
@@ -373,8 +350,7 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local) | |||
373 | ieee80211_hw_config(local, 0); | 350 | ieee80211_hw_config(local, 0); |
374 | 351 | ||
375 | ieee80211_queue_delayed_work(&local->hw, | 352 | ieee80211_queue_delayed_work(&local->hw, |
376 | &local->scan_work, | 353 | &local->scan_work, 0); |
377 | IEEE80211_CHANNEL_TIME); | ||
378 | 354 | ||
379 | return 0; | 355 | return 0; |
380 | } | 356 | } |
@@ -510,96 +486,39 @@ static void ieee80211_scan_state_decision(struct ieee80211_local *local, | |||
510 | 486 | ||
511 | next_chan = local->scan_req->channels[local->scan_channel_idx]; | 487 | next_chan = local->scan_req->channels[local->scan_channel_idx]; |
512 | 488 | ||
513 | if (ieee80211_cfg_on_oper_channel(local)) { | ||
514 | /* We're currently on operating channel. */ | ||
515 | if (next_chan == local->oper_channel) | ||
516 | /* We don't need to move off of operating channel. */ | ||
517 | local->next_scan_state = SCAN_SET_CHANNEL; | ||
518 | else | ||
519 | /* | ||
520 | * We do need to leave operating channel, as next | ||
521 | * scan is somewhere else. | ||
522 | */ | ||
523 | local->next_scan_state = SCAN_LEAVE_OPER_CHANNEL; | ||
524 | } else { | ||
525 | /* | ||
526 | * we're currently scanning a different channel, let's | ||
527 | * see if we can scan another channel without interfering | ||
528 | * with the current traffic situation. | ||
529 | * | ||
530 | * Since we don't know if the AP has pending frames for us | ||
531 | * we can only check for our tx queues and use the current | ||
532 | * pm_qos requirements for rx. Hence, if no tx traffic occurs | ||
533 | * at all we will scan as many channels in a row as the pm_qos | ||
534 | * latency allows us to. Additionally we also check for the | ||
535 | * currently negotiated listen interval to prevent losing | ||
536 | * frames unnecessarily. | ||
537 | * | ||
538 | * Otherwise switch back to the operating channel. | ||
539 | */ | ||
540 | |||
541 | bad_latency = time_after(jiffies + | ||
542 | ieee80211_scan_get_channel_time(next_chan), | ||
543 | local->leave_oper_channel_time + | ||
544 | usecs_to_jiffies(pm_qos_request(PM_QOS_NETWORK_LATENCY))); | ||
545 | |||
546 | listen_int_exceeded = time_after(jiffies + | ||
547 | ieee80211_scan_get_channel_time(next_chan), | ||
548 | local->leave_oper_channel_time + | ||
549 | usecs_to_jiffies(min_beacon_int * 1024) * | ||
550 | local->hw.conf.listen_interval); | ||
551 | |||
552 | if (associated && ( !tx_empty || bad_latency || | ||
553 | listen_int_exceeded)) | ||
554 | local->next_scan_state = SCAN_ENTER_OPER_CHANNEL; | ||
555 | else | ||
556 | local->next_scan_state = SCAN_SET_CHANNEL; | ||
557 | } | ||
558 | |||
559 | *next_delay = 0; | ||
560 | } | ||
561 | |||
562 | static void ieee80211_scan_state_leave_oper_channel(struct ieee80211_local *local, | ||
563 | unsigned long *next_delay) | ||
564 | { | ||
565 | /* PS will already be in off-channel mode, | ||
566 | * we do that once at the beginning of scanning. | ||
567 | */ | ||
568 | ieee80211_offchannel_stop_vifs(local, false); | ||
569 | |||
570 | /* | 489 | /* |
571 | * What if the nullfunc frames didn't arrive? | 490 | * we're currently scanning a different channel, let's |
491 | * see if we can scan another channel without interfering | ||
492 | * with the current traffic situation. | ||
493 | * | ||
494 | * Since we don't know if the AP has pending frames for us | ||
495 | * we can only check for our tx queues and use the current | ||
496 | * pm_qos requirements for rx. Hence, if no tx traffic occurs | ||
497 | * at all we will scan as many channels in a row as the pm_qos | ||
498 | * latency allows us to. Additionally we also check for the | ||
499 | * currently negotiated listen interval to prevent losing | ||
500 | * frames unnecessarily. | ||
501 | * | ||
502 | * Otherwise switch back to the operating channel. | ||
572 | */ | 503 | */ |
573 | drv_flush(local, false); | ||
574 | if (local->ops->flush) | ||
575 | *next_delay = 0; | ||
576 | else | ||
577 | *next_delay = HZ / 10; | ||
578 | 504 | ||
579 | /* remember when we left the operating channel */ | 505 | bad_latency = time_after(jiffies + |
580 | local->leave_oper_channel_time = jiffies; | 506 | ieee80211_scan_get_channel_time(next_chan), |
507 | local->leave_oper_channel_time + | ||
508 | usecs_to_jiffies(pm_qos_request(PM_QOS_NETWORK_LATENCY))); | ||
581 | 509 | ||
582 | /* advance to the next channel to be scanned */ | 510 | listen_int_exceeded = time_after(jiffies + |
583 | local->next_scan_state = SCAN_SET_CHANNEL; | 511 | ieee80211_scan_get_channel_time(next_chan), |
584 | } | 512 | local->leave_oper_channel_time + |
585 | 513 | usecs_to_jiffies(min_beacon_int * 1024) * | |
586 | static void ieee80211_scan_state_enter_oper_channel(struct ieee80211_local *local, | 514 | local->hw.conf.listen_interval); |
587 | unsigned long *next_delay) | ||
588 | { | ||
589 | /* switch back to the operating channel */ | ||
590 | local->scan_channel = NULL; | ||
591 | if (!ieee80211_cfg_on_oper_channel(local)) | ||
592 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); | ||
593 | 515 | ||
594 | /* | 516 | if (associated && (!tx_empty || bad_latency || listen_int_exceeded)) |
595 | * Re-enable vifs and beaconing. Leave PS | 517 | local->next_scan_state = SCAN_SUSPEND; |
596 | * in off-channel state..will put that back | 518 | else |
597 | * on-channel at the end of scanning. | 519 | local->next_scan_state = SCAN_SET_CHANNEL; |
598 | */ | ||
599 | ieee80211_offchannel_return(local, true, false); | ||
600 | 520 | ||
601 | *next_delay = HZ / 5; | 521 | *next_delay = 0; |
602 | local->next_scan_state = SCAN_DECISION; | ||
603 | } | 522 | } |
604 | 523 | ||
605 | static void ieee80211_scan_state_set_channel(struct ieee80211_local *local, | 524 | static void ieee80211_scan_state_set_channel(struct ieee80211_local *local, |
@@ -613,10 +532,8 @@ static void ieee80211_scan_state_set_channel(struct ieee80211_local *local, | |||
613 | 532 | ||
614 | local->scan_channel = chan; | 533 | local->scan_channel = chan; |
615 | 534 | ||
616 | /* Only call hw-config if we really need to change channels. */ | 535 | if (ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL)) |
617 | if (chan != local->hw.conf.channel) | 536 | skip = 1; |
618 | if (ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL)) | ||
619 | skip = 1; | ||
620 | 537 | ||
621 | /* advance state machine to next channel/band */ | 538 | /* advance state machine to next channel/band */ |
622 | local->scan_channel_idx++; | 539 | local->scan_channel_idx++; |
@@ -673,6 +590,44 @@ static void ieee80211_scan_state_send_probe(struct ieee80211_local *local, | |||
673 | local->next_scan_state = SCAN_DECISION; | 590 | local->next_scan_state = SCAN_DECISION; |
674 | } | 591 | } |
675 | 592 | ||
593 | static void ieee80211_scan_state_suspend(struct ieee80211_local *local, | ||
594 | unsigned long *next_delay) | ||
595 | { | ||
596 | /* switch back to the operating channel */ | ||
597 | local->scan_channel = NULL; | ||
598 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); | ||
599 | |||
600 | /* | ||
601 | * Re-enable vifs and beaconing. Leave PS | ||
602 | * in off-channel state..will put that back | ||
603 | * on-channel at the end of scanning. | ||
604 | */ | ||
605 | ieee80211_offchannel_return(local, true, false); | ||
606 | |||
607 | *next_delay = HZ / 5; | ||
608 | /* afterwards, resume scan & go to next channel */ | ||
609 | local->next_scan_state = SCAN_RESUME; | ||
610 | } | ||
611 | |||
612 | static void ieee80211_scan_state_resume(struct ieee80211_local *local, | ||
613 | unsigned long *next_delay) | ||
614 | { | ||
615 | /* PS already is in off-channel mode */ | ||
616 | ieee80211_offchannel_stop_vifs(local, false); | ||
617 | |||
618 | if (local->ops->flush) { | ||
619 | drv_flush(local, false); | ||
620 | *next_delay = 0; | ||
621 | } else | ||
622 | *next_delay = HZ / 10; | ||
623 | |||
624 | /* remember when we left the operating channel */ | ||
625 | local->leave_oper_channel_time = jiffies; | ||
626 | |||
627 | /* advance to the next channel to be scanned */ | ||
628 | local->next_scan_state = SCAN_DECISION; | ||
629 | } | ||
630 | |||
676 | void ieee80211_scan_work(struct work_struct *work) | 631 | void ieee80211_scan_work(struct work_struct *work) |
677 | { | 632 | { |
678 | struct ieee80211_local *local = | 633 | struct ieee80211_local *local = |
@@ -743,11 +698,11 @@ void ieee80211_scan_work(struct work_struct *work) | |||
743 | case SCAN_SEND_PROBE: | 698 | case SCAN_SEND_PROBE: |
744 | ieee80211_scan_state_send_probe(local, &next_delay); | 699 | ieee80211_scan_state_send_probe(local, &next_delay); |
745 | break; | 700 | break; |
746 | case SCAN_LEAVE_OPER_CHANNEL: | 701 | case SCAN_SUSPEND: |
747 | ieee80211_scan_state_leave_oper_channel(local, &next_delay); | 702 | ieee80211_scan_state_suspend(local, &next_delay); |
748 | break; | 703 | break; |
749 | case SCAN_ENTER_OPER_CHANNEL: | 704 | case SCAN_RESUME: |
750 | ieee80211_scan_state_enter_oper_channel(local, &next_delay); | 705 | ieee80211_scan_state_resume(local, &next_delay); |
751 | break; | 706 | break; |
752 | } | 707 | } |
753 | } while (next_delay == 0); | 708 | } while (next_delay == 0); |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index ce962d2c8782..8eaa746ec7a2 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -1354,12 +1354,12 @@ ieee80211_sta_ps_deliver_response(struct sta_info *sta, | |||
1354 | * Use MoreData flag to indicate whether there are | 1354 | * Use MoreData flag to indicate whether there are |
1355 | * more buffered frames for this STA | 1355 | * more buffered frames for this STA |
1356 | */ | 1356 | */ |
1357 | if (!more_data) | 1357 | if (more_data || !skb_queue_empty(&frames)) |
1358 | hdr->frame_control &= | ||
1359 | cpu_to_le16(~IEEE80211_FCTL_MOREDATA); | ||
1360 | else | ||
1361 | hdr->frame_control |= | 1358 | hdr->frame_control |= |
1362 | cpu_to_le16(IEEE80211_FCTL_MOREDATA); | 1359 | cpu_to_le16(IEEE80211_FCTL_MOREDATA); |
1360 | else | ||
1361 | hdr->frame_control &= | ||
1362 | cpu_to_le16(~IEEE80211_FCTL_MOREDATA); | ||
1363 | 1363 | ||
1364 | if (ieee80211_is_data_qos(hdr->frame_control) || | 1364 | if (ieee80211_is_data_qos(hdr->frame_control) || |
1365 | ieee80211_is_qos_nullfunc(hdr->frame_control)) | 1365 | ieee80211_is_qos_nullfunc(hdr->frame_control)) |
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 8c8ce05ad26f..c5923ab8a070 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h | |||
@@ -52,6 +52,7 @@ | |||
52 | * unblocks the station. | 52 | * unblocks the station. |
53 | * @WLAN_STA_SP: Station is in a service period, so don't try to | 53 | * @WLAN_STA_SP: Station is in a service period, so don't try to |
54 | * reply to other uAPSD trigger frames or PS-Poll. | 54 | * reply to other uAPSD trigger frames or PS-Poll. |
55 | * @WLAN_STA_4ADDR_EVENT: 4-addr event was already sent for this frame. | ||
55 | */ | 56 | */ |
56 | enum ieee80211_sta_info_flags { | 57 | enum ieee80211_sta_info_flags { |
57 | WLAN_STA_AUTH, | 58 | WLAN_STA_AUTH, |
@@ -71,6 +72,7 @@ enum ieee80211_sta_info_flags { | |||
71 | WLAN_STA_TDLS_PEER_AUTH, | 72 | WLAN_STA_TDLS_PEER_AUTH, |
72 | WLAN_STA_UAPSD, | 73 | WLAN_STA_UAPSD, |
73 | WLAN_STA_SP, | 74 | WLAN_STA_SP, |
75 | WLAN_STA_4ADDR_EVENT, | ||
74 | }; | 76 | }; |
75 | 77 | ||
76 | #define STA_TID_NUM 16 | 78 | #define STA_TID_NUM 16 |
@@ -390,6 +392,12 @@ static inline int test_and_clear_sta_flag(struct sta_info *sta, | |||
390 | return test_and_clear_bit(flag, &sta->_flags); | 392 | return test_and_clear_bit(flag, &sta->_flags); |
391 | } | 393 | } |
392 | 394 | ||
395 | static inline int test_and_set_sta_flag(struct sta_info *sta, | ||
396 | enum ieee80211_sta_info_flags flag) | ||
397 | { | ||
398 | return test_and_set_bit(flag, &sta->_flags); | ||
399 | } | ||
400 | |||
393 | void ieee80211_assign_tid_tx(struct sta_info *sta, int tid, | 401 | void ieee80211_assign_tid_tx(struct sta_info *sta, int tid, |
394 | struct tid_ampdu_tx *tid_tx); | 402 | struct tid_ampdu_tx *tid_tx); |
395 | 403 | ||
diff --git a/net/mac80211/status.c b/net/mac80211/status.c index 80de436eae20..a9da6ee69803 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c | |||
@@ -517,27 +517,54 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
517 | } | 517 | } |
518 | 518 | ||
519 | if (info->flags & IEEE80211_TX_INTFL_NL80211_FRAME_TX) { | 519 | if (info->flags & IEEE80211_TX_INTFL_NL80211_FRAME_TX) { |
520 | struct ieee80211_work *wk; | ||
521 | u64 cookie = (unsigned long)skb; | 520 | u64 cookie = (unsigned long)skb; |
522 | 521 | ||
523 | rcu_read_lock(); | 522 | if (ieee80211_is_nullfunc(hdr->frame_control) || |
524 | list_for_each_entry_rcu(wk, &local->work_list, list) { | 523 | ieee80211_is_qos_nullfunc(hdr->frame_control)) { |
525 | if (wk->type != IEEE80211_WORK_OFFCHANNEL_TX) | 524 | bool acked = info->flags & IEEE80211_TX_STAT_ACK; |
526 | continue; | 525 | cfg80211_probe_status(skb->dev, hdr->addr1, |
527 | if (wk->offchan_tx.frame != skb) | 526 | cookie, acked, GFP_ATOMIC); |
528 | continue; | 527 | } else { |
529 | wk->offchan_tx.status = true; | 528 | struct ieee80211_work *wk; |
530 | break; | 529 | |
531 | } | 530 | rcu_read_lock(); |
532 | rcu_read_unlock(); | 531 | list_for_each_entry_rcu(wk, &local->work_list, list) { |
533 | if (local->hw_roc_skb_for_status == skb) { | 532 | if (wk->type != IEEE80211_WORK_OFFCHANNEL_TX) |
534 | cookie = local->hw_roc_cookie ^ 2; | 533 | continue; |
535 | local->hw_roc_skb_for_status = NULL; | 534 | if (wk->offchan_tx.frame != skb) |
535 | continue; | ||
536 | wk->offchan_tx.status = true; | ||
537 | break; | ||
538 | } | ||
539 | rcu_read_unlock(); | ||
540 | if (local->hw_roc_skb_for_status == skb) { | ||
541 | cookie = local->hw_roc_cookie ^ 2; | ||
542 | local->hw_roc_skb_for_status = NULL; | ||
543 | } | ||
544 | |||
545 | cfg80211_mgmt_tx_status( | ||
546 | skb->dev, cookie, skb->data, skb->len, | ||
547 | !!(info->flags & IEEE80211_TX_STAT_ACK), | ||
548 | GFP_ATOMIC); | ||
536 | } | 549 | } |
550 | } | ||
537 | 551 | ||
538 | cfg80211_mgmt_tx_status( | 552 | if (unlikely(info->ack_frame_id)) { |
539 | skb->dev, cookie, skb->data, skb->len, | 553 | struct sk_buff *ack_skb; |
540 | !!(info->flags & IEEE80211_TX_STAT_ACK), GFP_ATOMIC); | 554 | unsigned long flags; |
555 | |||
556 | spin_lock_irqsave(&local->ack_status_lock, flags); | ||
557 | ack_skb = idr_find(&local->ack_status_frames, | ||
558 | info->ack_frame_id); | ||
559 | if (ack_skb) | ||
560 | idr_remove(&local->ack_status_frames, | ||
561 | info->ack_frame_id); | ||
562 | spin_unlock_irqrestore(&local->ack_status_lock, flags); | ||
563 | |||
564 | /* consumes ack_skb */ | ||
565 | if (ack_skb) | ||
566 | skb_complete_wifi_ack(ack_skb, | ||
567 | info->flags & IEEE80211_TX_STAT_ACK); | ||
541 | } | 568 | } |
542 | 569 | ||
543 | /* this was a transmitted frame, but now we want to reuse it */ | 570 | /* this was a transmitted frame, but now we want to reuse it */ |
@@ -610,3 +637,29 @@ void ieee80211_report_low_ack(struct ieee80211_sta *pubsta, u32 num_packets) | |||
610 | num_packets, GFP_ATOMIC); | 637 | num_packets, GFP_ATOMIC); |
611 | } | 638 | } |
612 | EXPORT_SYMBOL(ieee80211_report_low_ack); | 639 | EXPORT_SYMBOL(ieee80211_report_low_ack); |
640 | |||
641 | void ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb) | ||
642 | { | ||
643 | struct ieee80211_local *local = hw_to_local(hw); | ||
644 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
645 | |||
646 | if (unlikely(info->ack_frame_id)) { | ||
647 | struct sk_buff *ack_skb; | ||
648 | unsigned long flags; | ||
649 | |||
650 | spin_lock_irqsave(&local->ack_status_lock, flags); | ||
651 | ack_skb = idr_find(&local->ack_status_frames, | ||
652 | info->ack_frame_id); | ||
653 | if (ack_skb) | ||
654 | idr_remove(&local->ack_status_frames, | ||
655 | info->ack_frame_id); | ||
656 | spin_unlock_irqrestore(&local->ack_status_lock, flags); | ||
657 | |||
658 | /* consumes ack_skb */ | ||
659 | if (ack_skb) | ||
660 | dev_kfree_skb_any(ack_skb); | ||
661 | } | ||
662 | |||
663 | dev_kfree_skb_any(skb); | ||
664 | } | ||
665 | EXPORT_SYMBOL(ieee80211_free_txskb); | ||
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 1f8b120146d1..f044963feb9a 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -1685,8 +1685,10 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1685 | int nh_pos, h_pos; | 1685 | int nh_pos, h_pos; |
1686 | struct sta_info *sta = NULL; | 1686 | struct sta_info *sta = NULL; |
1687 | bool wme_sta = false, authorized = false, tdls_auth = false; | 1687 | bool wme_sta = false, authorized = false, tdls_auth = false; |
1688 | struct sk_buff *tmp_skb; | ||
1689 | bool tdls_direct = false; | 1688 | bool tdls_direct = false; |
1689 | bool multicast; | ||
1690 | u32 info_flags = 0; | ||
1691 | u16 info_id = 0; | ||
1690 | 1692 | ||
1691 | if (unlikely(skb->len < ETH_HLEN)) { | 1693 | if (unlikely(skb->len < ETH_HLEN)) { |
1692 | ret = NETDEV_TX_OK; | 1694 | ret = NETDEV_TX_OK; |
@@ -1873,7 +1875,8 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1873 | * if it is a multicast address (which can only happen | 1875 | * if it is a multicast address (which can only happen |
1874 | * in AP mode) | 1876 | * in AP mode) |
1875 | */ | 1877 | */ |
1876 | if (!is_multicast_ether_addr(hdr.addr1)) { | 1878 | multicast = is_multicast_ether_addr(hdr.addr1); |
1879 | if (!multicast) { | ||
1877 | rcu_read_lock(); | 1880 | rcu_read_lock(); |
1878 | sta = sta_info_get(sdata, hdr.addr1); | 1881 | sta = sta_info_get(sdata, hdr.addr1); |
1879 | if (sta) { | 1882 | if (sta) { |
@@ -1914,11 +1917,54 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1914 | goto fail; | 1917 | goto fail; |
1915 | } | 1918 | } |
1916 | 1919 | ||
1920 | if (unlikely(!multicast && skb->sk && | ||
1921 | skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS)) { | ||
1922 | struct sk_buff *orig_skb = skb; | ||
1923 | |||
1924 | skb = skb_clone(skb, GFP_ATOMIC); | ||
1925 | if (skb) { | ||
1926 | unsigned long flags; | ||
1927 | int id, r; | ||
1928 | |||
1929 | spin_lock_irqsave(&local->ack_status_lock, flags); | ||
1930 | r = idr_get_new_above(&local->ack_status_frames, | ||
1931 | orig_skb, 1, &id); | ||
1932 | if (r == -EAGAIN) { | ||
1933 | idr_pre_get(&local->ack_status_frames, | ||
1934 | GFP_ATOMIC); | ||
1935 | r = idr_get_new_above(&local->ack_status_frames, | ||
1936 | orig_skb, 1, &id); | ||
1937 | } | ||
1938 | if (WARN_ON(!id) || id > 0xffff) { | ||
1939 | idr_remove(&local->ack_status_frames, id); | ||
1940 | r = -ERANGE; | ||
1941 | } | ||
1942 | spin_unlock_irqrestore(&local->ack_status_lock, flags); | ||
1943 | |||
1944 | if (!r) { | ||
1945 | info_id = id; | ||
1946 | info_flags |= IEEE80211_TX_CTL_REQ_TX_STATUS; | ||
1947 | } else if (skb_shared(skb)) { | ||
1948 | kfree_skb(orig_skb); | ||
1949 | } else { | ||
1950 | kfree_skb(skb); | ||
1951 | skb = orig_skb; | ||
1952 | } | ||
1953 | } else { | ||
1954 | /* couldn't clone -- lose tx status ... */ | ||
1955 | skb = orig_skb; | ||
1956 | } | ||
1957 | } | ||
1958 | |||
1917 | /* | 1959 | /* |
1918 | * If the skb is shared we need to obtain our own copy. | 1960 | * If the skb is shared we need to obtain our own copy. |
1919 | */ | 1961 | */ |
1920 | if (skb_shared(skb)) { | 1962 | if (skb_shared(skb)) { |
1921 | tmp_skb = skb; | 1963 | struct sk_buff *tmp_skb = skb; |
1964 | |||
1965 | /* can't happen -- skb is a clone if info_id != 0 */ | ||
1966 | WARN_ON(info_id); | ||
1967 | |||
1922 | skb = skb_clone(skb, GFP_ATOMIC); | 1968 | skb = skb_clone(skb, GFP_ATOMIC); |
1923 | kfree_skb(tmp_skb); | 1969 | kfree_skb(tmp_skb); |
1924 | 1970 | ||
@@ -2019,6 +2065,10 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
2019 | memset(info, 0, sizeof(*info)); | 2065 | memset(info, 0, sizeof(*info)); |
2020 | 2066 | ||
2021 | dev->trans_start = jiffies; | 2067 | dev->trans_start = jiffies; |
2068 | |||
2069 | info->flags = info_flags; | ||
2070 | info->ack_frame_id = info_id; | ||
2071 | |||
2022 | ieee80211_xmit(sdata, skb); | 2072 | ieee80211_xmit(sdata, skb); |
2023 | 2073 | ||
2024 | return NETDEV_TX_OK; | 2074 | return NETDEV_TX_OK; |
@@ -2279,22 +2329,31 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, | |||
2279 | } else if (ieee80211_vif_is_mesh(&sdata->vif)) { | 2329 | } else if (ieee80211_vif_is_mesh(&sdata->vif)) { |
2280 | struct ieee80211_mgmt *mgmt; | 2330 | struct ieee80211_mgmt *mgmt; |
2281 | u8 *pos; | 2331 | u8 *pos; |
2332 | int hdr_len = offsetof(struct ieee80211_mgmt, u.beacon) + | ||
2333 | sizeof(mgmt->u.beacon); | ||
2282 | 2334 | ||
2283 | #ifdef CONFIG_MAC80211_MESH | 2335 | #ifdef CONFIG_MAC80211_MESH |
2284 | if (!sdata->u.mesh.mesh_id_len) | 2336 | if (!sdata->u.mesh.mesh_id_len) |
2285 | goto out; | 2337 | goto out; |
2286 | #endif | 2338 | #endif |
2287 | 2339 | ||
2288 | /* headroom, head length, tail length and maximum TIM length */ | 2340 | skb = dev_alloc_skb(local->tx_headroom + |
2289 | skb = dev_alloc_skb(local->tx_headroom + 400 + | 2341 | hdr_len + |
2290 | sdata->u.mesh.ie_len); | 2342 | 2 + /* NULL SSID */ |
2343 | 2 + 8 + /* supported rates */ | ||
2344 | 2 + 3 + /* DS params */ | ||
2345 | 2 + (IEEE80211_MAX_SUPP_RATES - 8) + | ||
2346 | 2 + sizeof(struct ieee80211_ht_cap) + | ||
2347 | 2 + sizeof(struct ieee80211_ht_info) + | ||
2348 | 2 + sdata->u.mesh.mesh_id_len + | ||
2349 | 2 + sizeof(struct ieee80211_meshconf_ie) + | ||
2350 | sdata->u.mesh.ie_len); | ||
2291 | if (!skb) | 2351 | if (!skb) |
2292 | goto out; | 2352 | goto out; |
2293 | 2353 | ||
2294 | skb_reserve(skb, local->hw.extra_tx_headroom); | 2354 | skb_reserve(skb, local->hw.extra_tx_headroom); |
2295 | mgmt = (struct ieee80211_mgmt *) | 2355 | mgmt = (struct ieee80211_mgmt *) skb_put(skb, hdr_len); |
2296 | skb_put(skb, 24 + sizeof(mgmt->u.beacon)); | 2356 | memset(mgmt, 0, hdr_len); |
2297 | memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon)); | ||
2298 | mgmt->frame_control = | 2357 | mgmt->frame_control = |
2299 | cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON); | 2358 | cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON); |
2300 | memset(mgmt->da, 0xff, ETH_ALEN); | 2359 | memset(mgmt->da, 0xff, ETH_ALEN); |
@@ -2313,6 +2372,8 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, | |||
2313 | mesh_add_ds_params_ie(skb, sdata) || | 2372 | mesh_add_ds_params_ie(skb, sdata) || |
2314 | ieee80211_add_ext_srates_ie(&sdata->vif, skb) || | 2373 | ieee80211_add_ext_srates_ie(&sdata->vif, skb) || |
2315 | mesh_add_rsn_ie(skb, sdata) || | 2374 | mesh_add_rsn_ie(skb, sdata) || |
2375 | mesh_add_ht_cap_ie(skb, sdata) || | ||
2376 | mesh_add_ht_info_ie(skb, sdata) || | ||
2316 | mesh_add_meshid_ie(skb, sdata) || | 2377 | mesh_add_meshid_ie(skb, sdata) || |
2317 | mesh_add_meshconf_ie(skb, sdata) || | 2378 | mesh_add_meshconf_ie(skb, sdata) || |
2318 | mesh_add_vendor_ies(skb, sdata)) { | 2379 | mesh_add_vendor_ies(skb, sdata)) { |
@@ -2355,6 +2416,37 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, | |||
2355 | } | 2416 | } |
2356 | EXPORT_SYMBOL(ieee80211_beacon_get_tim); | 2417 | EXPORT_SYMBOL(ieee80211_beacon_get_tim); |
2357 | 2418 | ||
2419 | struct sk_buff *ieee80211_proberesp_get(struct ieee80211_hw *hw, | ||
2420 | struct ieee80211_vif *vif) | ||
2421 | { | ||
2422 | struct ieee80211_if_ap *ap = NULL; | ||
2423 | struct sk_buff *presp = NULL, *skb = NULL; | ||
2424 | struct ieee80211_hdr *hdr; | ||
2425 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); | ||
2426 | |||
2427 | if (sdata->vif.type != NL80211_IFTYPE_AP) | ||
2428 | return NULL; | ||
2429 | |||
2430 | rcu_read_lock(); | ||
2431 | |||
2432 | ap = &sdata->u.ap; | ||
2433 | presp = rcu_dereference(ap->probe_resp); | ||
2434 | if (!presp) | ||
2435 | goto out; | ||
2436 | |||
2437 | skb = skb_copy(presp, GFP_ATOMIC); | ||
2438 | if (!skb) | ||
2439 | goto out; | ||
2440 | |||
2441 | hdr = (struct ieee80211_hdr *) skb->data; | ||
2442 | memset(hdr->addr1, 0, sizeof(hdr->addr1)); | ||
2443 | |||
2444 | out: | ||
2445 | rcu_read_unlock(); | ||
2446 | return skb; | ||
2447 | } | ||
2448 | EXPORT_SYMBOL(ieee80211_proberesp_get); | ||
2449 | |||
2358 | struct sk_buff *ieee80211_pspoll_get(struct ieee80211_hw *hw, | 2450 | struct sk_buff *ieee80211_pspoll_get(struct ieee80211_hw *hw, |
2359 | struct ieee80211_vif *vif) | 2451 | struct ieee80211_vif *vif) |
2360 | { | 2452 | { |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 51e256c5fb78..7683cb83fe46 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -812,23 +812,8 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, | |||
812 | offset = noffset; | 812 | offset = noffset; |
813 | } | 813 | } |
814 | 814 | ||
815 | if (sband->ht_cap.ht_supported) { | 815 | if (sband->ht_cap.ht_supported) |
816 | u16 cap = sband->ht_cap.cap; | 816 | pos = ieee80211_ie_build_ht_cap(pos, sband, sband->ht_cap.cap); |
817 | __le16 tmp; | ||
818 | |||
819 | *pos++ = WLAN_EID_HT_CAPABILITY; | ||
820 | *pos++ = sizeof(struct ieee80211_ht_cap); | ||
821 | memset(pos, 0, sizeof(struct ieee80211_ht_cap)); | ||
822 | tmp = cpu_to_le16(cap); | ||
823 | memcpy(pos, &tmp, sizeof(u16)); | ||
824 | pos += sizeof(u16); | ||
825 | *pos++ = sband->ht_cap.ampdu_factor | | ||
826 | (sband->ht_cap.ampdu_density << | ||
827 | IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT); | ||
828 | memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs)); | ||
829 | pos += sizeof(sband->ht_cap.mcs); | ||
830 | pos += 2 + 4 + 1; /* ext info, BF cap, antsel */ | ||
831 | } | ||
832 | 817 | ||
833 | /* | 818 | /* |
834 | * If adding more here, adjust code in main.c | 819 | * If adding more here, adjust code in main.c |
@@ -1022,7 +1007,7 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1022 | if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN && | 1007 | if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN && |
1023 | sdata->vif.type != NL80211_IFTYPE_MONITOR && | 1008 | sdata->vif.type != NL80211_IFTYPE_MONITOR && |
1024 | ieee80211_sdata_running(sdata)) | 1009 | ieee80211_sdata_running(sdata)) |
1025 | res = drv_add_interface(local, &sdata->vif); | 1010 | res = drv_add_interface(local, sdata); |
1026 | } | 1011 | } |
1027 | 1012 | ||
1028 | /* add STAs back */ | 1013 | /* add STAs back */ |
@@ -1073,7 +1058,8 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1073 | BSS_CHANGED_BEACON_INT | | 1058 | BSS_CHANGED_BEACON_INT | |
1074 | BSS_CHANGED_BSSID | | 1059 | BSS_CHANGED_BSSID | |
1075 | BSS_CHANGED_CQM | | 1060 | BSS_CHANGED_CQM | |
1076 | BSS_CHANGED_QOS; | 1061 | BSS_CHANGED_QOS | |
1062 | BSS_CHANGED_IDLE; | ||
1077 | 1063 | ||
1078 | switch (sdata->vif.type) { | 1064 | switch (sdata->vif.type) { |
1079 | case NL80211_IFTYPE_STATION: | 1065 | case NL80211_IFTYPE_STATION: |
@@ -1086,7 +1072,8 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1086 | changed |= BSS_CHANGED_IBSS; | 1072 | changed |= BSS_CHANGED_IBSS; |
1087 | /* fall through */ | 1073 | /* fall through */ |
1088 | case NL80211_IFTYPE_AP: | 1074 | case NL80211_IFTYPE_AP: |
1089 | changed |= BSS_CHANGED_SSID; | 1075 | changed |= BSS_CHANGED_SSID | |
1076 | BSS_CHANGED_AP_PROBE_RESP; | ||
1090 | /* fall through */ | 1077 | /* fall through */ |
1091 | case NL80211_IFTYPE_MESH_POINT: | 1078 | case NL80211_IFTYPE_MESH_POINT: |
1092 | changed |= BSS_CHANGED_BEACON | | 1079 | changed |= BSS_CHANGED_BEACON | |
@@ -1108,6 +1095,8 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1108 | } | 1095 | } |
1109 | } | 1096 | } |
1110 | 1097 | ||
1098 | ieee80211_recalc_ps(local, -1); | ||
1099 | |||
1111 | /* | 1100 | /* |
1112 | * Clear the WLAN_STA_BLOCK_BA flag so new aggregation | 1101 | * Clear the WLAN_STA_BLOCK_BA flag so new aggregation |
1113 | * sessions can be established after a resume. | 1102 | * sessions can be established after a resume. |
@@ -1363,6 +1352,103 @@ void ieee80211_disable_rssi_reports(struct ieee80211_vif *vif) | |||
1363 | } | 1352 | } |
1364 | EXPORT_SYMBOL(ieee80211_disable_rssi_reports); | 1353 | EXPORT_SYMBOL(ieee80211_disable_rssi_reports); |
1365 | 1354 | ||
1355 | u8 *ieee80211_ie_build_ht_cap(u8 *pos, struct ieee80211_supported_band *sband, | ||
1356 | u16 cap) | ||
1357 | { | ||
1358 | __le16 tmp; | ||
1359 | |||
1360 | *pos++ = WLAN_EID_HT_CAPABILITY; | ||
1361 | *pos++ = sizeof(struct ieee80211_ht_cap); | ||
1362 | memset(pos, 0, sizeof(struct ieee80211_ht_cap)); | ||
1363 | |||
1364 | /* capability flags */ | ||
1365 | tmp = cpu_to_le16(cap); | ||
1366 | memcpy(pos, &tmp, sizeof(u16)); | ||
1367 | pos += sizeof(u16); | ||
1368 | |||
1369 | /* AMPDU parameters */ | ||
1370 | *pos++ = sband->ht_cap.ampdu_factor | | ||
1371 | (sband->ht_cap.ampdu_density << | ||
1372 | IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT); | ||
1373 | |||
1374 | /* MCS set */ | ||
1375 | memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs)); | ||
1376 | pos += sizeof(sband->ht_cap.mcs); | ||
1377 | |||
1378 | /* extended capabilities */ | ||
1379 | pos += sizeof(__le16); | ||
1380 | |||
1381 | /* BF capabilities */ | ||
1382 | pos += sizeof(__le32); | ||
1383 | |||
1384 | /* antenna selection */ | ||
1385 | pos += sizeof(u8); | ||
1386 | |||
1387 | return pos; | ||
1388 | } | ||
1389 | |||
1390 | u8 *ieee80211_ie_build_ht_info(u8 *pos, | ||
1391 | struct ieee80211_sta_ht_cap *ht_cap, | ||
1392 | struct ieee80211_channel *channel, | ||
1393 | enum nl80211_channel_type channel_type) | ||
1394 | { | ||
1395 | struct ieee80211_ht_info *ht_info; | ||
1396 | /* Build HT Information */ | ||
1397 | *pos++ = WLAN_EID_HT_INFORMATION; | ||
1398 | *pos++ = sizeof(struct ieee80211_ht_info); | ||
1399 | ht_info = (struct ieee80211_ht_info *)pos; | ||
1400 | ht_info->control_chan = | ||
1401 | ieee80211_frequency_to_channel(channel->center_freq); | ||
1402 | switch (channel_type) { | ||
1403 | case NL80211_CHAN_HT40MINUS: | ||
1404 | ht_info->ht_param = IEEE80211_HT_PARAM_CHA_SEC_BELOW; | ||
1405 | break; | ||
1406 | case NL80211_CHAN_HT40PLUS: | ||
1407 | ht_info->ht_param = IEEE80211_HT_PARAM_CHA_SEC_ABOVE; | ||
1408 | break; | ||
1409 | case NL80211_CHAN_HT20: | ||
1410 | default: | ||
1411 | ht_info->ht_param = IEEE80211_HT_PARAM_CHA_SEC_NONE; | ||
1412 | break; | ||
1413 | } | ||
1414 | if (ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) | ||
1415 | ht_info->ht_param |= IEEE80211_HT_PARAM_CHAN_WIDTH_ANY; | ||
1416 | ht_info->operation_mode = 0x0000; | ||
1417 | ht_info->stbc_param = 0x0000; | ||
1418 | |||
1419 | /* It seems that Basic MCS set and Supported MCS set | ||
1420 | are identical for the first 10 bytes */ | ||
1421 | memset(&ht_info->basic_set, 0, 16); | ||
1422 | memcpy(&ht_info->basic_set, &ht_cap->mcs, 10); | ||
1423 | |||
1424 | return pos + sizeof(struct ieee80211_ht_info); | ||
1425 | } | ||
1426 | |||
1427 | enum nl80211_channel_type | ||
1428 | ieee80211_ht_info_to_channel_type(struct ieee80211_ht_info *ht_info) | ||
1429 | { | ||
1430 | enum nl80211_channel_type channel_type; | ||
1431 | |||
1432 | if (!ht_info) | ||
1433 | return NL80211_CHAN_NO_HT; | ||
1434 | |||
1435 | switch (ht_info->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { | ||
1436 | case IEEE80211_HT_PARAM_CHA_SEC_NONE: | ||
1437 | channel_type = NL80211_CHAN_HT20; | ||
1438 | break; | ||
1439 | case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: | ||
1440 | channel_type = NL80211_CHAN_HT40PLUS; | ||
1441 | break; | ||
1442 | case IEEE80211_HT_PARAM_CHA_SEC_BELOW: | ||
1443 | channel_type = NL80211_CHAN_HT40MINUS; | ||
1444 | break; | ||
1445 | default: | ||
1446 | channel_type = NL80211_CHAN_NO_HT; | ||
1447 | } | ||
1448 | |||
1449 | return channel_type; | ||
1450 | } | ||
1451 | |||
1366 | int ieee80211_add_srates_ie(struct ieee80211_vif *vif, struct sk_buff *skb) | 1452 | int ieee80211_add_srates_ie(struct ieee80211_vif *vif, struct sk_buff *skb) |
1367 | { | 1453 | { |
1368 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); | 1454 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); |
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c index fd52e695c071..43327115b490 100644 --- a/net/mac80211/wme.c +++ b/net/mac80211/wme.c | |||
@@ -83,7 +83,7 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, | |||
83 | break; | 83 | break; |
84 | #ifdef CONFIG_MAC80211_MESH | 84 | #ifdef CONFIG_MAC80211_MESH |
85 | case NL80211_IFTYPE_MESH_POINT: | 85 | case NL80211_IFTYPE_MESH_POINT: |
86 | ra = skb->data; | 86 | qos = true; |
87 | break; | 87 | break; |
88 | #endif | 88 | #endif |
89 | case NL80211_IFTYPE_STATION: | 89 | case NL80211_IFTYPE_STATION: |
@@ -143,11 +143,15 @@ void ieee80211_set_qos_hdr(struct ieee80211_sub_if_data *sdata, | |||
143 | /* Fill in the QoS header if there is one. */ | 143 | /* Fill in the QoS header if there is one. */ |
144 | if (ieee80211_is_data_qos(hdr->frame_control)) { | 144 | if (ieee80211_is_data_qos(hdr->frame_control)) { |
145 | u8 *p = ieee80211_get_qos_ctl(hdr); | 145 | u8 *p = ieee80211_get_qos_ctl(hdr); |
146 | u8 ack_policy = 0, tid; | 146 | u8 ack_policy, tid; |
147 | 147 | ||
148 | tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; | 148 | tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; |
149 | 149 | ||
150 | if (unlikely(sdata->local->wifi_wme_noack_test)) | 150 | /* preserve EOSP bit */ |
151 | ack_policy = *p & IEEE80211_QOS_CTL_EOSP; | ||
152 | |||
153 | if (unlikely(sdata->local->wifi_wme_noack_test) || | ||
154 | is_multicast_ether_addr(hdr->addr1)) | ||
151 | ack_policy |= IEEE80211_QOS_CTL_ACK_POLICY_NOACK; | 155 | ack_policy |= IEEE80211_QOS_CTL_ACK_POLICY_NOACK; |
152 | /* qos header is 2 bytes */ | 156 | /* qos header is 2 bytes */ |
153 | *p++ = ack_policy | tid; | 157 | *p++ = ack_policy | tid; |
diff --git a/net/mac80211/work.c b/net/mac80211/work.c index 6c53b6d1002b..3dd5a89e99a7 100644 --- a/net/mac80211/work.c +++ b/net/mac80211/work.c | |||
@@ -103,7 +103,6 @@ static void ieee80211_add_ht_ie(struct sk_buff *skb, const u8 *ht_info_ie, | |||
103 | u8 *pos; | 103 | u8 *pos; |
104 | u32 flags = channel->flags; | 104 | u32 flags = channel->flags; |
105 | u16 cap = sband->ht_cap.cap; | 105 | u16 cap = sband->ht_cap.cap; |
106 | __le16 tmp; | ||
107 | 106 | ||
108 | if (!sband->ht_cap.ht_supported) | 107 | if (!sband->ht_cap.ht_supported) |
109 | return; | 108 | return; |
@@ -154,34 +153,8 @@ static void ieee80211_add_ht_ie(struct sk_buff *skb, const u8 *ht_info_ie, | |||
154 | } | 153 | } |
155 | 154 | ||
156 | /* reserve and fill IE */ | 155 | /* reserve and fill IE */ |
157 | |||
158 | pos = skb_put(skb, sizeof(struct ieee80211_ht_cap) + 2); | 156 | pos = skb_put(skb, sizeof(struct ieee80211_ht_cap) + 2); |
159 | *pos++ = WLAN_EID_HT_CAPABILITY; | 157 | ieee80211_ie_build_ht_cap(pos, sband, cap); |
160 | *pos++ = sizeof(struct ieee80211_ht_cap); | ||
161 | memset(pos, 0, sizeof(struct ieee80211_ht_cap)); | ||
162 | |||
163 | /* capability flags */ | ||
164 | tmp = cpu_to_le16(cap); | ||
165 | memcpy(pos, &tmp, sizeof(u16)); | ||
166 | pos += sizeof(u16); | ||
167 | |||
168 | /* AMPDU parameters */ | ||
169 | *pos++ = sband->ht_cap.ampdu_factor | | ||
170 | (sband->ht_cap.ampdu_density << | ||
171 | IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT); | ||
172 | |||
173 | /* MCS set */ | ||
174 | memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs)); | ||
175 | pos += sizeof(sband->ht_cap.mcs); | ||
176 | |||
177 | /* extended capabilities */ | ||
178 | pos += sizeof(__le16); | ||
179 | |||
180 | /* BF capabilities */ | ||
181 | pos += sizeof(__le32); | ||
182 | |||
183 | /* antenna selection */ | ||
184 | pos += sizeof(u8); | ||
185 | } | 158 | } |
186 | 159 | ||
187 | static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata, | 160 | static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata, |
@@ -969,10 +942,9 @@ static void ieee80211_work_work(struct work_struct *work) | |||
969 | } | 942 | } |
970 | 943 | ||
971 | if (!started && !local->tmp_channel) { | 944 | if (!started && !local->tmp_channel) { |
972 | bool on_oper_chan; | 945 | bool on_oper_chan, on_oper_chan2; |
973 | bool tmp_chan_changed = false; | ||
974 | bool on_oper_chan2; | ||
975 | enum nl80211_channel_type wk_ct; | 946 | enum nl80211_channel_type wk_ct; |
947 | |||
976 | on_oper_chan = ieee80211_cfg_on_oper_channel(local); | 948 | on_oper_chan = ieee80211_cfg_on_oper_channel(local); |
977 | 949 | ||
978 | /* Work with existing channel type if possible. */ | 950 | /* Work with existing channel type if possible. */ |
@@ -981,11 +953,6 @@ static void ieee80211_work_work(struct work_struct *work) | |||
981 | wk_ct = ieee80211_calc_ct(wk->chan_type, | 953 | wk_ct = ieee80211_calc_ct(wk->chan_type, |
982 | local->hw.conf.channel_type); | 954 | local->hw.conf.channel_type); |
983 | 955 | ||
984 | if (local->tmp_channel) | ||
985 | if ((local->tmp_channel != wk->chan) || | ||
986 | (local->tmp_channel_type != wk_ct)) | ||
987 | tmp_chan_changed = true; | ||
988 | |||
989 | local->tmp_channel = wk->chan; | 956 | local->tmp_channel = wk->chan; |
990 | local->tmp_channel_type = wk_ct; | 957 | local->tmp_channel_type = wk_ct; |
991 | /* | 958 | /* |
@@ -1008,12 +975,7 @@ static void ieee80211_work_work(struct work_struct *work) | |||
1008 | true, | 975 | true, |
1009 | false); | 976 | false); |
1010 | } | 977 | } |
1011 | } else if (tmp_chan_changed) | 978 | } |
1012 | /* Still off-channel, but on some other | ||
1013 | * channel, so update hardware. | ||
1014 | * PS should already be off-channel. | ||
1015 | */ | ||
1016 | ieee80211_hw_config(local, 0); | ||
1017 | 979 | ||
1018 | started = true; | 980 | started = true; |
1019 | wk->timeout = jiffies; | 981 | wk->timeout = jiffies; |
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index f614ce7bb6e3..106e15a4649f 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c | |||
@@ -390,7 +390,8 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) | |||
390 | u8 scratch[6 * AES_BLOCK_SIZE]; | 390 | u8 scratch[6 * AES_BLOCK_SIZE]; |
391 | 391 | ||
392 | if (info->control.hw_key && | 392 | if (info->control.hw_key && |
393 | !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV)) { | 393 | !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV) && |
394 | !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)) { | ||
394 | /* | 395 | /* |
395 | * hwaccel has no need for preallocated room for CCMP | 396 | * hwaccel has no need for preallocated room for CCMP |
396 | * header or MIC fields | 397 | * header or MIC fields |
@@ -412,6 +413,12 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) | |||
412 | 413 | ||
413 | pos = skb_push(skb, CCMP_HDR_LEN); | 414 | pos = skb_push(skb, CCMP_HDR_LEN); |
414 | memmove(pos, pos + CCMP_HDR_LEN, hdrlen); | 415 | memmove(pos, pos + CCMP_HDR_LEN, hdrlen); |
416 | |||
417 | /* the HW only needs room for the IV, but not the actual IV */ | ||
418 | if (info->control.hw_key && | ||
419 | (info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)) | ||
420 | return 0; | ||
421 | |||
415 | hdr = (struct ieee80211_hdr *) pos; | 422 | hdr = (struct ieee80211_hdr *) pos; |
416 | pos += hdrlen; | 423 | pos += hdrlen; |
417 | 424 | ||
diff --git a/net/nfc/nci/core.c b/net/nfc/nci/core.c index 3925c6578767..fe5ca89abfce 100644 --- a/net/nfc/nci/core.c +++ b/net/nfc/nci/core.c | |||
@@ -126,7 +126,10 @@ static inline int nci_request(struct nci_dev *ndev, | |||
126 | 126 | ||
127 | static void nci_reset_req(struct nci_dev *ndev, unsigned long opt) | 127 | static void nci_reset_req(struct nci_dev *ndev, unsigned long opt) |
128 | { | 128 | { |
129 | nci_send_cmd(ndev, NCI_OP_CORE_RESET_CMD, 0, NULL); | 129 | struct nci_core_reset_cmd cmd; |
130 | |||
131 | cmd.reset_type = NCI_RESET_TYPE_RESET_CONFIG; | ||
132 | nci_send_cmd(ndev, NCI_OP_CORE_RESET_CMD, 1, &cmd); | ||
130 | } | 133 | } |
131 | 134 | ||
132 | static void nci_init_req(struct nci_dev *ndev, unsigned long opt) | 135 | static void nci_init_req(struct nci_dev *ndev, unsigned long opt) |
@@ -136,17 +139,11 @@ static void nci_init_req(struct nci_dev *ndev, unsigned long opt) | |||
136 | 139 | ||
137 | static void nci_init_complete_req(struct nci_dev *ndev, unsigned long opt) | 140 | static void nci_init_complete_req(struct nci_dev *ndev, unsigned long opt) |
138 | { | 141 | { |
139 | struct nci_core_conn_create_cmd conn_cmd; | ||
140 | struct nci_rf_disc_map_cmd cmd; | 142 | struct nci_rf_disc_map_cmd cmd; |
141 | struct disc_map_config *cfg = cmd.mapping_configs; | 143 | struct disc_map_config *cfg = cmd.mapping_configs; |
142 | __u8 *num = &cmd.num_mapping_configs; | 144 | __u8 *num = &cmd.num_mapping_configs; |
143 | int i; | 145 | int i; |
144 | 146 | ||
145 | /* create static rf connection */ | ||
146 | conn_cmd.target_handle = 0; | ||
147 | conn_cmd.num_target_specific_params = 0; | ||
148 | nci_send_cmd(ndev, NCI_OP_CORE_CONN_CREATE_CMD, 2, &conn_cmd); | ||
149 | |||
150 | /* set rf mapping configurations */ | 147 | /* set rf mapping configurations */ |
151 | *num = 0; | 148 | *num = 0; |
152 | 149 | ||
@@ -470,7 +467,7 @@ static int nci_data_exchange(struct nfc_dev *nfc_dev, __u32 target_idx, | |||
470 | ndev->data_exchange_cb = cb; | 467 | ndev->data_exchange_cb = cb; |
471 | ndev->data_exchange_cb_context = cb_context; | 468 | ndev->data_exchange_cb_context = cb_context; |
472 | 469 | ||
473 | rc = nci_send_data(ndev, ndev->conn_id, skb); | 470 | rc = nci_send_data(ndev, NCI_STATIC_RF_CONN_ID, skb); |
474 | if (rc) | 471 | if (rc) |
475 | clear_bit(NCI_DATA_EXCHANGE, &ndev->flags); | 472 | clear_bit(NCI_DATA_EXCHANGE, &ndev->flags); |
476 | 473 | ||
@@ -726,7 +723,10 @@ static void nci_tx_work(struct work_struct *work) | |||
726 | if (!skb) | 723 | if (!skb) |
727 | return; | 724 | return; |
728 | 725 | ||
729 | atomic_dec(&ndev->credits_cnt); | 726 | /* Check if data flow control is used */ |
727 | if (atomic_read(&ndev->credits_cnt) != | ||
728 | NCI_DATA_FLOW_CONTROL_NOT_USED) | ||
729 | atomic_dec(&ndev->credits_cnt); | ||
730 | 730 | ||
731 | nfc_dbg("NCI TX: MT=data, PBF=%d, conn_id=%d, plen=%d", | 731 | nfc_dbg("NCI TX: MT=data, PBF=%d, conn_id=%d, plen=%d", |
732 | nci_pbf(skb->data), | 732 | nci_pbf(skb->data), |
diff --git a/net/nfc/nci/data.c b/net/nfc/nci/data.c index e5ed90fc1a9c..511fb96e21bc 100644 --- a/net/nfc/nci/data.c +++ b/net/nfc/nci/data.c | |||
@@ -95,7 +95,8 @@ static int nci_queue_tx_data_frags(struct nci_dev *ndev, | |||
95 | __skb_queue_head_init(&frags_q); | 95 | __skb_queue_head_init(&frags_q); |
96 | 96 | ||
97 | while (total_len) { | 97 | while (total_len) { |
98 | frag_len = min_t(int, total_len, ndev->max_pkt_payload_size); | 98 | frag_len = |
99 | min_t(int, total_len, ndev->max_data_pkt_payload_size); | ||
99 | 100 | ||
100 | skb_frag = nci_skb_alloc(ndev, | 101 | skb_frag = nci_skb_alloc(ndev, |
101 | (NCI_DATA_HDR_SIZE + frag_len), | 102 | (NCI_DATA_HDR_SIZE + frag_len), |
@@ -151,7 +152,7 @@ int nci_send_data(struct nci_dev *ndev, __u8 conn_id, struct sk_buff *skb) | |||
151 | nfc_dbg("entry, conn_id 0x%x, plen %d", conn_id, skb->len); | 152 | nfc_dbg("entry, conn_id 0x%x, plen %d", conn_id, skb->len); |
152 | 153 | ||
153 | /* check if the packet need to be fragmented */ | 154 | /* check if the packet need to be fragmented */ |
154 | if (skb->len <= ndev->max_pkt_payload_size) { | 155 | if (skb->len <= ndev->max_data_pkt_payload_size) { |
155 | /* no need to fragment packet */ | 156 | /* no need to fragment packet */ |
156 | nci_push_data_hdr(ndev, conn_id, skb, NCI_PBF_LAST); | 157 | nci_push_data_hdr(ndev, conn_id, skb, NCI_PBF_LAST); |
157 | 158 | ||
diff --git a/net/nfc/nci/lib.c b/net/nfc/nci/lib.c index b19dc2fa90e1..e99adcfb1bcf 100644 --- a/net/nfc/nci/lib.c +++ b/net/nfc/nci/lib.c | |||
@@ -42,12 +42,9 @@ int nci_to_errno(__u8 code) | |||
42 | case NCI_STATUS_REJECTED: | 42 | case NCI_STATUS_REJECTED: |
43 | return -EBUSY; | 43 | return -EBUSY; |
44 | 44 | ||
45 | case NCI_STATUS_MESSAGE_CORRUPTED: | 45 | case NCI_STATUS_RF_FRAME_CORRUPTED: |
46 | return -EBADMSG; | 46 | return -EBADMSG; |
47 | 47 | ||
48 | case NCI_STATUS_BUFFER_FULL: | ||
49 | return -ENOBUFS; | ||
50 | |||
51 | case NCI_STATUS_NOT_INITIALIZED: | 48 | case NCI_STATUS_NOT_INITIALIZED: |
52 | return -EHOSTDOWN; | 49 | return -EHOSTDOWN; |
53 | 50 | ||
@@ -80,9 +77,6 @@ int nci_to_errno(__u8 code) | |||
80 | case NCI_STATUS_NFCEE_TIMEOUT_ERROR: | 77 | case NCI_STATUS_NFCEE_TIMEOUT_ERROR: |
81 | return -ETIMEDOUT; | 78 | return -ETIMEDOUT; |
82 | 79 | ||
83 | case NCI_STATUS_RF_LINK_LOSS_ERROR: | ||
84 | return -ENOLINK; | ||
85 | |||
86 | case NCI_STATUS_MAX_ACTIVE_NFCEE_INTERFACES_REACHED: | 80 | case NCI_STATUS_MAX_ACTIVE_NFCEE_INTERFACES_REACHED: |
87 | return -EDQUOT; | 81 | return -EDQUOT; |
88 | 82 | ||
diff --git a/net/nfc/nci/ntf.c b/net/nfc/nci/ntf.c index 96633f5cda4f..c1bf54172c25 100644 --- a/net/nfc/nci/ntf.c +++ b/net/nfc/nci/ntf.c | |||
@@ -54,7 +54,7 @@ static void nci_core_conn_credits_ntf_packet(struct nci_dev *ndev, | |||
54 | ntf->conn_entries[i].conn_id, | 54 | ntf->conn_entries[i].conn_id, |
55 | ntf->conn_entries[i].credits); | 55 | ntf->conn_entries[i].credits); |
56 | 56 | ||
57 | if (ntf->conn_entries[i].conn_id == ndev->conn_id) { | 57 | if (ntf->conn_entries[i].conn_id == NCI_STATIC_RF_CONN_ID) { |
58 | /* found static rf connection */ | 58 | /* found static rf connection */ |
59 | atomic_add(ntf->conn_entries[i].credits, | 59 | atomic_add(ntf->conn_entries[i].credits, |
60 | &ndev->credits_cnt); | 60 | &ndev->credits_cnt); |
@@ -66,22 +66,12 @@ static void nci_core_conn_credits_ntf_packet(struct nci_dev *ndev, | |||
66 | queue_work(ndev->tx_wq, &ndev->tx_work); | 66 | queue_work(ndev->tx_wq, &ndev->tx_work); |
67 | } | 67 | } |
68 | 68 | ||
69 | static void nci_rf_field_info_ntf_packet(struct nci_dev *ndev, | 69 | static __u8 *nci_extract_rf_params_nfca_passive_poll(struct nci_dev *ndev, |
70 | struct sk_buff *skb) | 70 | struct nci_rf_intf_activated_ntf *ntf, __u8 *data) |
71 | { | ||
72 | struct nci_rf_field_info_ntf *ntf = (void *) skb->data; | ||
73 | |||
74 | nfc_dbg("entry, rf_field_status %d", ntf->rf_field_status); | ||
75 | } | ||
76 | |||
77 | static int nci_rf_activate_nfca_passive_poll(struct nci_dev *ndev, | ||
78 | struct nci_rf_activate_ntf *ntf, __u8 *data) | ||
79 | { | 71 | { |
80 | struct rf_tech_specific_params_nfca_poll *nfca_poll; | 72 | struct rf_tech_specific_params_nfca_poll *nfca_poll; |
81 | struct activation_params_nfca_poll_iso_dep *nfca_poll_iso_dep; | ||
82 | 73 | ||
83 | nfca_poll = &ntf->rf_tech_specific_params.nfca_poll; | 74 | nfca_poll = &ntf->rf_tech_specific_params.nfca_poll; |
84 | nfca_poll_iso_dep = &ntf->activation_params.nfca_poll_iso_dep; | ||
85 | 75 | ||
86 | nfca_poll->sens_res = __le16_to_cpu(*((__u16 *)data)); | 76 | nfca_poll->sens_res = __le16_to_cpu(*((__u16 *)data)); |
87 | data += 2; | 77 | data += 2; |
@@ -100,32 +90,32 @@ static int nci_rf_activate_nfca_passive_poll(struct nci_dev *ndev, | |||
100 | if (nfca_poll->sel_res_len != 0) | 90 | if (nfca_poll->sel_res_len != 0) |
101 | nfca_poll->sel_res = *data++; | 91 | nfca_poll->sel_res = *data++; |
102 | 92 | ||
103 | ntf->rf_interface_type = *data++; | 93 | nfc_dbg("sel_res_len %d, sel_res 0x%x", |
104 | ntf->activation_params_len = *data++; | ||
105 | |||
106 | nfc_dbg("sel_res_len %d, sel_res 0x%x, rf_interface_type %d, activation_params_len %d", | ||
107 | nfca_poll->sel_res_len, | 94 | nfca_poll->sel_res_len, |
108 | nfca_poll->sel_res, | 95 | nfca_poll->sel_res); |
109 | ntf->rf_interface_type, | 96 | |
110 | ntf->activation_params_len); | 97 | return data; |
111 | 98 | } | |
112 | switch (ntf->rf_interface_type) { | 99 | |
113 | case NCI_RF_INTERFACE_ISO_DEP: | 100 | static int nci_extract_activation_params_iso_dep(struct nci_dev *ndev, |
114 | nfca_poll_iso_dep->rats_res_len = *data++; | 101 | struct nci_rf_intf_activated_ntf *ntf, __u8 *data) |
115 | if (nfca_poll_iso_dep->rats_res_len > 0) { | 102 | { |
116 | memcpy(nfca_poll_iso_dep->rats_res, | 103 | struct activation_params_nfca_poll_iso_dep *nfca_poll; |
104 | |||
105 | switch (ntf->activation_rf_tech_and_mode) { | ||
106 | case NCI_NFC_A_PASSIVE_POLL_MODE: | ||
107 | nfca_poll = &ntf->activation_params.nfca_poll_iso_dep; | ||
108 | nfca_poll->rats_res_len = *data++; | ||
109 | if (nfca_poll->rats_res_len > 0) { | ||
110 | memcpy(nfca_poll->rats_res, | ||
117 | data, | 111 | data, |
118 | nfca_poll_iso_dep->rats_res_len); | 112 | nfca_poll->rats_res_len); |
119 | } | 113 | } |
120 | break; | 114 | break; |
121 | 115 | ||
122 | case NCI_RF_INTERFACE_FRAME: | ||
123 | /* no activation params */ | ||
124 | break; | ||
125 | |||
126 | default: | 116 | default: |
127 | nfc_err("unsupported rf_interface_type 0x%x", | 117 | nfc_err("unsupported activation_rf_tech_and_mode 0x%x", |
128 | ntf->rf_interface_type); | 118 | ntf->activation_rf_tech_and_mode); |
129 | return -EPROTO; | 119 | return -EPROTO; |
130 | } | 120 | } |
131 | 121 | ||
@@ -133,7 +123,7 @@ static int nci_rf_activate_nfca_passive_poll(struct nci_dev *ndev, | |||
133 | } | 123 | } |
134 | 124 | ||
135 | static void nci_target_found(struct nci_dev *ndev, | 125 | static void nci_target_found(struct nci_dev *ndev, |
136 | struct nci_rf_activate_ntf *ntf) | 126 | struct nci_rf_intf_activated_ntf *ntf) |
137 | { | 127 | { |
138 | struct nfc_target nfc_tgt; | 128 | struct nfc_target nfc_tgt; |
139 | 129 | ||
@@ -141,6 +131,8 @@ static void nci_target_found(struct nci_dev *ndev, | |||
141 | nfc_tgt.supported_protocols = NFC_PROTO_MIFARE_MASK; | 131 | nfc_tgt.supported_protocols = NFC_PROTO_MIFARE_MASK; |
142 | else if (ntf->rf_protocol == NCI_RF_PROTOCOL_ISO_DEP) /* 4A */ | 132 | else if (ntf->rf_protocol == NCI_RF_PROTOCOL_ISO_DEP) /* 4A */ |
143 | nfc_tgt.supported_protocols = NFC_PROTO_ISO14443_MASK; | 133 | nfc_tgt.supported_protocols = NFC_PROTO_ISO14443_MASK; |
134 | else | ||
135 | nfc_tgt.supported_protocols = 0; | ||
144 | 136 | ||
145 | nfc_tgt.sens_res = ntf->rf_tech_specific_params.nfca_poll.sens_res; | 137 | nfc_tgt.sens_res = ntf->rf_tech_specific_params.nfca_poll.sens_res; |
146 | nfc_tgt.sel_res = ntf->rf_tech_specific_params.nfca_poll.sel_res; | 138 | nfc_tgt.sel_res = ntf->rf_tech_specific_params.nfca_poll.sel_res; |
@@ -158,49 +150,86 @@ static void nci_target_found(struct nci_dev *ndev, | |||
158 | nfc_targets_found(ndev->nfc_dev, &nfc_tgt, 1); | 150 | nfc_targets_found(ndev->nfc_dev, &nfc_tgt, 1); |
159 | } | 151 | } |
160 | 152 | ||
161 | static void nci_rf_activate_ntf_packet(struct nci_dev *ndev, | 153 | static void nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev, |
162 | struct sk_buff *skb) | 154 | struct sk_buff *skb) |
163 | { | 155 | { |
164 | struct nci_rf_activate_ntf ntf; | 156 | struct nci_rf_intf_activated_ntf ntf; |
165 | __u8 *data = skb->data; | 157 | __u8 *data = skb->data; |
166 | int rc = -1; | 158 | int err = 0; |
167 | 159 | ||
168 | clear_bit(NCI_DISCOVERY, &ndev->flags); | 160 | clear_bit(NCI_DISCOVERY, &ndev->flags); |
169 | set_bit(NCI_POLL_ACTIVE, &ndev->flags); | 161 | set_bit(NCI_POLL_ACTIVE, &ndev->flags); |
170 | 162 | ||
171 | ntf.target_handle = *data++; | 163 | ntf.rf_discovery_id = *data++; |
164 | ntf.rf_interface_type = *data++; | ||
172 | ntf.rf_protocol = *data++; | 165 | ntf.rf_protocol = *data++; |
173 | ntf.rf_tech_and_mode = *data++; | 166 | ntf.activation_rf_tech_and_mode = *data++; |
174 | ntf.rf_tech_specific_params_len = *data++; | 167 | ntf.rf_tech_specific_params_len = *data++; |
175 | 168 | ||
176 | nfc_dbg("target_handle %d, rf_protocol 0x%x, rf_tech_and_mode 0x%x, rf_tech_specific_params_len %d", | 169 | nfc_dbg("rf_discovery_id %d", ntf.rf_discovery_id); |
177 | ntf.target_handle, | 170 | nfc_dbg("rf_interface_type 0x%x", ntf.rf_interface_type); |
178 | ntf.rf_protocol, | 171 | nfc_dbg("rf_protocol 0x%x", ntf.rf_protocol); |
179 | ntf.rf_tech_and_mode, | 172 | nfc_dbg("activation_rf_tech_and_mode 0x%x", |
173 | ntf.activation_rf_tech_and_mode); | ||
174 | nfc_dbg("rf_tech_specific_params_len %d", | ||
180 | ntf.rf_tech_specific_params_len); | 175 | ntf.rf_tech_specific_params_len); |
181 | 176 | ||
182 | switch (ntf.rf_tech_and_mode) { | 177 | if (ntf.rf_tech_specific_params_len > 0) { |
183 | case NCI_NFC_A_PASSIVE_POLL_MODE: | 178 | switch (ntf.activation_rf_tech_and_mode) { |
184 | rc = nci_rf_activate_nfca_passive_poll(ndev, &ntf, | 179 | case NCI_NFC_A_PASSIVE_POLL_MODE: |
185 | data); | 180 | data = nci_extract_rf_params_nfca_passive_poll(ndev, |
186 | break; | 181 | &ntf, data); |
182 | break; | ||
183 | |||
184 | default: | ||
185 | nfc_err("unsupported activation_rf_tech_and_mode 0x%x", | ||
186 | ntf.activation_rf_tech_and_mode); | ||
187 | return; | ||
188 | } | ||
189 | } | ||
187 | 190 | ||
188 | default: | 191 | ntf.data_exch_rf_tech_and_mode = *data++; |
189 | nfc_err("unsupported rf_tech_and_mode 0x%x", | 192 | ntf.data_exch_tx_bit_rate = *data++; |
190 | ntf.rf_tech_and_mode); | 193 | ntf.data_exch_rx_bit_rate = *data++; |
191 | return; | 194 | ntf.activation_params_len = *data++; |
195 | |||
196 | nfc_dbg("data_exch_rf_tech_and_mode 0x%x", | ||
197 | ntf.data_exch_rf_tech_and_mode); | ||
198 | nfc_dbg("data_exch_tx_bit_rate 0x%x", | ||
199 | ntf.data_exch_tx_bit_rate); | ||
200 | nfc_dbg("data_exch_rx_bit_rate 0x%x", | ||
201 | ntf.data_exch_rx_bit_rate); | ||
202 | nfc_dbg("activation_params_len %d", | ||
203 | ntf.activation_params_len); | ||
204 | |||
205 | if (ntf.activation_params_len > 0) { | ||
206 | switch (ntf.rf_interface_type) { | ||
207 | case NCI_RF_INTERFACE_ISO_DEP: | ||
208 | err = nci_extract_activation_params_iso_dep(ndev, | ||
209 | &ntf, data); | ||
210 | break; | ||
211 | |||
212 | case NCI_RF_INTERFACE_FRAME: | ||
213 | /* no activation params */ | ||
214 | break; | ||
215 | |||
216 | default: | ||
217 | nfc_err("unsupported rf_interface_type 0x%x", | ||
218 | ntf.rf_interface_type); | ||
219 | return; | ||
220 | } | ||
192 | } | 221 | } |
193 | 222 | ||
194 | if (!rc) | 223 | if (!err) |
195 | nci_target_found(ndev, &ntf); | 224 | nci_target_found(ndev, &ntf); |
196 | } | 225 | } |
197 | 226 | ||
198 | static void nci_rf_deactivate_ntf_packet(struct nci_dev *ndev, | 227 | static void nci_rf_deactivate_ntf_packet(struct nci_dev *ndev, |
199 | struct sk_buff *skb) | 228 | struct sk_buff *skb) |
200 | { | 229 | { |
201 | __u8 type = skb->data[0]; | 230 | struct nci_rf_deactivate_ntf *ntf = (void *) skb->data; |
202 | 231 | ||
203 | nfc_dbg("entry, type 0x%x", type); | 232 | nfc_dbg("entry, type 0x%x, reason 0x%x", ntf->type, ntf->reason); |
204 | 233 | ||
205 | clear_bit(NCI_POLL_ACTIVE, &ndev->flags); | 234 | clear_bit(NCI_POLL_ACTIVE, &ndev->flags); |
206 | ndev->target_active_prot = 0; | 235 | ndev->target_active_prot = 0; |
@@ -214,6 +243,9 @@ static void nci_rf_deactivate_ntf_packet(struct nci_dev *ndev, | |||
214 | ndev->rx_data_reassembly = 0; | 243 | ndev->rx_data_reassembly = 0; |
215 | } | 244 | } |
216 | 245 | ||
246 | /* set the available credits to initial value */ | ||
247 | atomic_set(&ndev->credits_cnt, ndev->initial_num_credits); | ||
248 | |||
217 | /* complete the data exchange transaction, if exists */ | 249 | /* complete the data exchange transaction, if exists */ |
218 | if (test_bit(NCI_DATA_EXCHANGE, &ndev->flags)) | 250 | if (test_bit(NCI_DATA_EXCHANGE, &ndev->flags)) |
219 | nci_data_exchange_complete(ndev, NULL, -EIO); | 251 | nci_data_exchange_complete(ndev, NULL, -EIO); |
@@ -237,12 +269,8 @@ void nci_ntf_packet(struct nci_dev *ndev, struct sk_buff *skb) | |||
237 | nci_core_conn_credits_ntf_packet(ndev, skb); | 269 | nci_core_conn_credits_ntf_packet(ndev, skb); |
238 | break; | 270 | break; |
239 | 271 | ||
240 | case NCI_OP_RF_FIELD_INFO_NTF: | 272 | case NCI_OP_RF_INTF_ACTIVATED_NTF: |
241 | nci_rf_field_info_ntf_packet(ndev, skb); | 273 | nci_rf_intf_activated_ntf_packet(ndev, skb); |
242 | break; | ||
243 | |||
244 | case NCI_OP_RF_ACTIVATE_NTF: | ||
245 | nci_rf_activate_ntf_packet(ndev, skb); | ||
246 | break; | 274 | break; |
247 | 275 | ||
248 | case NCI_OP_RF_DEACTIVATE_NTF: | 276 | case NCI_OP_RF_DEACTIVATE_NTF: |
diff --git a/net/nfc/nci/rsp.c b/net/nfc/nci/rsp.c index 0403d4cd0917..0591f5aff89f 100644 --- a/net/nfc/nci/rsp.c +++ b/net/nfc/nci/rsp.c | |||
@@ -42,10 +42,11 @@ static void nci_core_reset_rsp_packet(struct nci_dev *ndev, struct sk_buff *skb) | |||
42 | 42 | ||
43 | nfc_dbg("entry, status 0x%x", rsp->status); | 43 | nfc_dbg("entry, status 0x%x", rsp->status); |
44 | 44 | ||
45 | if (rsp->status == NCI_STATUS_OK) | 45 | if (rsp->status == NCI_STATUS_OK) { |
46 | ndev->nci_ver = rsp->nci_ver; | 46 | ndev->nci_ver = rsp->nci_ver; |
47 | 47 | nfc_dbg("nci_ver 0x%x, config_status 0x%x", | |
48 | nfc_dbg("nci_ver 0x%x", ndev->nci_ver); | 48 | rsp->nci_ver, rsp->config_status); |
49 | } | ||
49 | 50 | ||
50 | nci_req_complete(ndev, rsp->status); | 51 | nci_req_complete(ndev, rsp->status); |
51 | } | 52 | } |
@@ -58,13 +59,13 @@ static void nci_core_init_rsp_packet(struct nci_dev *ndev, struct sk_buff *skb) | |||
58 | nfc_dbg("entry, status 0x%x", rsp_1->status); | 59 | nfc_dbg("entry, status 0x%x", rsp_1->status); |
59 | 60 | ||
60 | if (rsp_1->status != NCI_STATUS_OK) | 61 | if (rsp_1->status != NCI_STATUS_OK) |
61 | return; | 62 | goto exit; |
62 | 63 | ||
63 | ndev->nfcc_features = __le32_to_cpu(rsp_1->nfcc_features); | 64 | ndev->nfcc_features = __le32_to_cpu(rsp_1->nfcc_features); |
64 | ndev->num_supported_rf_interfaces = rsp_1->num_supported_rf_interfaces; | 65 | ndev->num_supported_rf_interfaces = rsp_1->num_supported_rf_interfaces; |
65 | 66 | ||
66 | if (ndev->num_supported_rf_interfaces > | 67 | if (ndev->num_supported_rf_interfaces > |
67 | NCI_MAX_SUPPORTED_RF_INTERFACES) { | 68 | NCI_MAX_SUPPORTED_RF_INTERFACES) { |
68 | ndev->num_supported_rf_interfaces = | 69 | ndev->num_supported_rf_interfaces = |
69 | NCI_MAX_SUPPORTED_RF_INTERFACES; | 70 | NCI_MAX_SUPPORTED_RF_INTERFACES; |
70 | } | 71 | } |
@@ -73,20 +74,26 @@ static void nci_core_init_rsp_packet(struct nci_dev *ndev, struct sk_buff *skb) | |||
73 | rsp_1->supported_rf_interfaces, | 74 | rsp_1->supported_rf_interfaces, |
74 | ndev->num_supported_rf_interfaces); | 75 | ndev->num_supported_rf_interfaces); |
75 | 76 | ||
76 | rsp_2 = (void *) (skb->data + 6 + ndev->num_supported_rf_interfaces); | 77 | rsp_2 = (void *) (skb->data + 6 + rsp_1->num_supported_rf_interfaces); |
77 | 78 | ||
78 | ndev->max_logical_connections = | 79 | ndev->max_logical_connections = |
79 | rsp_2->max_logical_connections; | 80 | rsp_2->max_logical_connections; |
80 | ndev->max_routing_table_size = | 81 | ndev->max_routing_table_size = |
81 | __le16_to_cpu(rsp_2->max_routing_table_size); | 82 | __le16_to_cpu(rsp_2->max_routing_table_size); |
82 | ndev->max_control_packet_payload_length = | 83 | ndev->max_ctrl_pkt_payload_len = |
83 | rsp_2->max_control_packet_payload_length; | 84 | rsp_2->max_ctrl_pkt_payload_len; |
84 | ndev->rf_sending_buffer_size = | 85 | ndev->max_size_for_large_params = |
85 | __le16_to_cpu(rsp_2->rf_sending_buffer_size); | 86 | __le16_to_cpu(rsp_2->max_size_for_large_params); |
86 | ndev->rf_receiving_buffer_size = | 87 | ndev->max_data_pkt_payload_size = |
87 | __le16_to_cpu(rsp_2->rf_receiving_buffer_size); | 88 | rsp_2->max_data_pkt_payload_size; |
88 | ndev->manufacturer_id = | 89 | ndev->initial_num_credits = |
89 | __le16_to_cpu(rsp_2->manufacturer_id); | 90 | rsp_2->initial_num_credits; |
91 | ndev->manufact_id = | ||
92 | rsp_2->manufact_id; | ||
93 | ndev->manufact_specific_info = | ||
94 | __le32_to_cpu(rsp_2->manufact_specific_info); | ||
95 | |||
96 | atomic_set(&ndev->credits_cnt, ndev->initial_num_credits); | ||
90 | 97 | ||
91 | nfc_dbg("nfcc_features 0x%x", | 98 | nfc_dbg("nfcc_features 0x%x", |
92 | ndev->nfcc_features); | 99 | ndev->nfcc_features); |
@@ -104,39 +111,23 @@ static void nci_core_init_rsp_packet(struct nci_dev *ndev, struct sk_buff *skb) | |||
104 | ndev->max_logical_connections); | 111 | ndev->max_logical_connections); |
105 | nfc_dbg("max_routing_table_size %d", | 112 | nfc_dbg("max_routing_table_size %d", |
106 | ndev->max_routing_table_size); | 113 | ndev->max_routing_table_size); |
107 | nfc_dbg("max_control_packet_payload_length %d", | 114 | nfc_dbg("max_ctrl_pkt_payload_len %d", |
108 | ndev->max_control_packet_payload_length); | 115 | ndev->max_ctrl_pkt_payload_len); |
109 | nfc_dbg("rf_sending_buffer_size %d", | 116 | nfc_dbg("max_size_for_large_params %d", |
110 | ndev->rf_sending_buffer_size); | 117 | ndev->max_size_for_large_params); |
111 | nfc_dbg("rf_receiving_buffer_size %d", | 118 | nfc_dbg("max_data_pkt_payload_size %d", |
112 | ndev->rf_receiving_buffer_size); | 119 | ndev->max_data_pkt_payload_size); |
113 | nfc_dbg("manufacturer_id 0x%x", | 120 | nfc_dbg("initial_num_credits %d", |
114 | ndev->manufacturer_id); | 121 | ndev->initial_num_credits); |
115 | 122 | nfc_dbg("manufact_id 0x%x", | |
123 | ndev->manufact_id); | ||
124 | nfc_dbg("manufact_specific_info 0x%x", | ||
125 | ndev->manufact_specific_info); | ||
126 | |||
127 | exit: | ||
116 | nci_req_complete(ndev, rsp_1->status); | 128 | nci_req_complete(ndev, rsp_1->status); |
117 | } | 129 | } |
118 | 130 | ||
119 | static void nci_core_conn_create_rsp_packet(struct nci_dev *ndev, | ||
120 | struct sk_buff *skb) | ||
121 | { | ||
122 | struct nci_core_conn_create_rsp *rsp = (void *) skb->data; | ||
123 | |||
124 | nfc_dbg("entry, status 0x%x", rsp->status); | ||
125 | |||
126 | if (rsp->status != NCI_STATUS_OK) | ||
127 | return; | ||
128 | |||
129 | ndev->max_pkt_payload_size = rsp->max_pkt_payload_size; | ||
130 | ndev->initial_num_credits = rsp->initial_num_credits; | ||
131 | ndev->conn_id = rsp->conn_id; | ||
132 | |||
133 | atomic_set(&ndev->credits_cnt, ndev->initial_num_credits); | ||
134 | |||
135 | nfc_dbg("max_pkt_payload_size %d", ndev->max_pkt_payload_size); | ||
136 | nfc_dbg("initial_num_credits %d", ndev->initial_num_credits); | ||
137 | nfc_dbg("conn_id %d", ndev->conn_id); | ||
138 | } | ||
139 | |||
140 | static void nci_rf_disc_map_rsp_packet(struct nci_dev *ndev, | 131 | static void nci_rf_disc_map_rsp_packet(struct nci_dev *ndev, |
141 | struct sk_buff *skb) | 132 | struct sk_buff *skb) |
142 | { | 133 | { |
@@ -196,10 +187,6 @@ void nci_rsp_packet(struct nci_dev *ndev, struct sk_buff *skb) | |||
196 | nci_core_init_rsp_packet(ndev, skb); | 187 | nci_core_init_rsp_packet(ndev, skb); |
197 | break; | 188 | break; |
198 | 189 | ||
199 | case NCI_OP_CORE_CONN_CREATE_RSP: | ||
200 | nci_core_conn_create_rsp_packet(ndev, skb); | ||
201 | break; | ||
202 | |||
203 | case NCI_OP_RF_DISCOVER_MAP_RSP: | 190 | case NCI_OP_RF_DISCOVER_MAP_RSP: |
204 | nci_rf_disc_map_rsp_packet(ndev, skb); | 191 | nci_rf_disc_map_rsp_packet(ndev, skb); |
205 | break; | 192 | break; |
diff --git a/net/rfkill/core.c b/net/rfkill/core.c index 5be19575c340..354760ebbbd2 100644 --- a/net/rfkill/core.c +++ b/net/rfkill/core.c | |||
@@ -644,7 +644,7 @@ static ssize_t rfkill_soft_store(struct device *dev, | |||
644 | if (!capable(CAP_NET_ADMIN)) | 644 | if (!capable(CAP_NET_ADMIN)) |
645 | return -EPERM; | 645 | return -EPERM; |
646 | 646 | ||
647 | err = strict_strtoul(buf, 0, &state); | 647 | err = kstrtoul(buf, 0, &state); |
648 | if (err) | 648 | if (err) |
649 | return err; | 649 | return err; |
650 | 650 | ||
@@ -688,7 +688,7 @@ static ssize_t rfkill_state_store(struct device *dev, | |||
688 | if (!capable(CAP_NET_ADMIN)) | 688 | if (!capable(CAP_NET_ADMIN)) |
689 | return -EPERM; | 689 | return -EPERM; |
690 | 690 | ||
691 | err = strict_strtoul(buf, 0, &state); | 691 | err = kstrtoul(buf, 0, &state); |
692 | if (err) | 692 | if (err) |
693 | return err; | 693 | return err; |
694 | 694 | ||
diff --git a/net/socket.c b/net/socket.c index 2877647f347b..425ef4270460 100644 --- a/net/socket.c +++ b/net/socket.c | |||
@@ -538,6 +538,8 @@ int sock_tx_timestamp(struct sock *sk, __u8 *tx_flags) | |||
538 | *tx_flags |= SKBTX_HW_TSTAMP; | 538 | *tx_flags |= SKBTX_HW_TSTAMP; |
539 | if (sock_flag(sk, SOCK_TIMESTAMPING_TX_SOFTWARE)) | 539 | if (sock_flag(sk, SOCK_TIMESTAMPING_TX_SOFTWARE)) |
540 | *tx_flags |= SKBTX_SW_TSTAMP; | 540 | *tx_flags |= SKBTX_SW_TSTAMP; |
541 | if (sock_flag(sk, SOCK_WIFI_STATUS)) | ||
542 | *tx_flags |= SKBTX_WIFI_STATUS; | ||
541 | return 0; | 543 | return 0; |
542 | } | 544 | } |
543 | EXPORT_SYMBOL(sock_tx_timestamp); | 545 | EXPORT_SYMBOL(sock_tx_timestamp); |
@@ -674,6 +676,22 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk, | |||
674 | } | 676 | } |
675 | EXPORT_SYMBOL_GPL(__sock_recv_timestamp); | 677 | EXPORT_SYMBOL_GPL(__sock_recv_timestamp); |
676 | 678 | ||
679 | void __sock_recv_wifi_status(struct msghdr *msg, struct sock *sk, | ||
680 | struct sk_buff *skb) | ||
681 | { | ||
682 | int ack; | ||
683 | |||
684 | if (!sock_flag(sk, SOCK_WIFI_STATUS)) | ||
685 | return; | ||
686 | if (!skb->wifi_acked_valid) | ||
687 | return; | ||
688 | |||
689 | ack = skb->wifi_acked; | ||
690 | |||
691 | put_cmsg(msg, SOL_SOCKET, SCM_WIFI_STATUS, sizeof(ack), &ack); | ||
692 | } | ||
693 | EXPORT_SYMBOL_GPL(__sock_recv_wifi_status); | ||
694 | |||
677 | static inline void sock_recv_drops(struct msghdr *msg, struct sock *sk, | 695 | static inline void sock_recv_drops(struct msghdr *msg, struct sock *sk, |
678 | struct sk_buff *skb) | 696 | struct sk_buff *skb) |
679 | { | 697 | { |
diff --git a/net/wireless/core.c b/net/wireless/core.c index 220f3bd176f8..ccdfed897651 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
@@ -492,6 +492,10 @@ int wiphy_register(struct wiphy *wiphy) | |||
492 | !(wiphy->wowlan.flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY))) | 492 | !(wiphy->wowlan.flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY))) |
493 | return -EINVAL; | 493 | return -EINVAL; |
494 | 494 | ||
495 | if (WARN_ON(wiphy->ap_sme_capa && | ||
496 | !(wiphy->flags & WIPHY_FLAG_HAVE_AP_SME))) | ||
497 | return -EINVAL; | ||
498 | |||
495 | if (WARN_ON(wiphy->addresses && !wiphy->n_addresses)) | 499 | if (WARN_ON(wiphy->addresses && !wiphy->n_addresses)) |
496 | return -EINVAL; | 500 | return -EINVAL; |
497 | 501 | ||
diff --git a/net/wireless/core.h b/net/wireless/core.h index b9ec3061ed72..1c7d4df5418c 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h | |||
@@ -54,6 +54,8 @@ struct cfg80211_registered_device { | |||
54 | int opencount; /* also protected by devlist_mtx */ | 54 | int opencount; /* also protected by devlist_mtx */ |
55 | wait_queue_head_t dev_wait; | 55 | wait_queue_head_t dev_wait; |
56 | 56 | ||
57 | u32 ap_beacons_nlpid; | ||
58 | |||
57 | /* BSSes/scanning */ | 59 | /* BSSes/scanning */ |
58 | spinlock_t bss_lock; | 60 | spinlock_t bss_lock; |
59 | struct list_head bss_list; | 61 | struct list_head bss_list; |
@@ -376,7 +378,7 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, | |||
376 | enum nl80211_channel_type channel_type, | 378 | enum nl80211_channel_type channel_type, |
377 | bool channel_type_valid, unsigned int wait, | 379 | bool channel_type_valid, unsigned int wait, |
378 | const u8 *buf, size_t len, bool no_cck, | 380 | const u8 *buf, size_t len, bool no_cck, |
379 | u64 *cookie); | 381 | bool dont_wait_for_ack, u64 *cookie); |
380 | 382 | ||
381 | /* SME */ | 383 | /* SME */ |
382 | int __cfg80211_connect(struct cfg80211_registered_device *rdev, | 384 | int __cfg80211_connect(struct cfg80211_registered_device *rdev, |
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index 21fc9702f81c..6c1bafd508c8 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c | |||
@@ -879,6 +879,9 @@ void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlpid) | |||
879 | } | 879 | } |
880 | 880 | ||
881 | spin_unlock_bh(&wdev->mgmt_registrations_lock); | 881 | spin_unlock_bh(&wdev->mgmt_registrations_lock); |
882 | |||
883 | if (nlpid == wdev->ap_unexpected_nlpid) | ||
884 | wdev->ap_unexpected_nlpid = 0; | ||
882 | } | 885 | } |
883 | 886 | ||
884 | void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev) | 887 | void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev) |
@@ -901,7 +904,7 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, | |||
901 | enum nl80211_channel_type channel_type, | 904 | enum nl80211_channel_type channel_type, |
902 | bool channel_type_valid, unsigned int wait, | 905 | bool channel_type_valid, unsigned int wait, |
903 | const u8 *buf, size_t len, bool no_cck, | 906 | const u8 *buf, size_t len, bool no_cck, |
904 | u64 *cookie) | 907 | bool dont_wait_for_ack, u64 *cookie) |
905 | { | 908 | { |
906 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 909 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
907 | const struct ieee80211_mgmt *mgmt; | 910 | const struct ieee80211_mgmt *mgmt; |
@@ -992,7 +995,8 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, | |||
992 | /* Transmit the Action frame as requested by user space */ | 995 | /* Transmit the Action frame as requested by user space */ |
993 | return rdev->ops->mgmt_tx(&rdev->wiphy, dev, chan, offchan, | 996 | return rdev->ops->mgmt_tx(&rdev->wiphy, dev, chan, offchan, |
994 | channel_type, channel_type_valid, | 997 | channel_type, channel_type_valid, |
995 | wait, buf, len, no_cck, cookie); | 998 | wait, buf, len, no_cck, dont_wait_for_ack, |
999 | cookie); | ||
996 | } | 1000 | } |
997 | 1001 | ||
998 | bool cfg80211_rx_mgmt(struct net_device *dev, int freq, const u8 *buf, | 1002 | bool cfg80211_rx_mgmt(struct net_device *dev, int freq, const u8 *buf, |
@@ -1107,3 +1111,30 @@ void cfg80211_pmksa_candidate_notify(struct net_device *dev, int index, | |||
1107 | nl80211_pmksa_candidate_notify(rdev, dev, index, bssid, preauth, gfp); | 1111 | nl80211_pmksa_candidate_notify(rdev, dev, index, bssid, preauth, gfp); |
1108 | } | 1112 | } |
1109 | EXPORT_SYMBOL(cfg80211_pmksa_candidate_notify); | 1113 | EXPORT_SYMBOL(cfg80211_pmksa_candidate_notify); |
1114 | |||
1115 | bool cfg80211_rx_spurious_frame(struct net_device *dev, | ||
1116 | const u8 *addr, gfp_t gfp) | ||
1117 | { | ||
1118 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
1119 | |||
1120 | if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP && | ||
1121 | wdev->iftype != NL80211_IFTYPE_P2P_GO)) | ||
1122 | return false; | ||
1123 | |||
1124 | return nl80211_unexpected_frame(dev, addr, gfp); | ||
1125 | } | ||
1126 | EXPORT_SYMBOL(cfg80211_rx_spurious_frame); | ||
1127 | |||
1128 | bool cfg80211_rx_unexpected_4addr_frame(struct net_device *dev, | ||
1129 | const u8 *addr, gfp_t gfp) | ||
1130 | { | ||
1131 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
1132 | |||
1133 | if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP && | ||
1134 | wdev->iftype != NL80211_IFTYPE_P2P_GO && | ||
1135 | wdev->iftype != NL80211_IFTYPE_AP_VLAN)) | ||
1136 | return false; | ||
1137 | |||
1138 | return nl80211_unexpected_4addr_frame(dev, addr, gfp); | ||
1139 | } | ||
1140 | EXPORT_SYMBOL(cfg80211_rx_unexpected_4addr_frame); | ||
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 48260c2d092a..6bc7c4b32fa5 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -98,7 +98,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { | |||
98 | [NL80211_ATTR_KEY_IDX] = { .type = NLA_U8 }, | 98 | [NL80211_ATTR_KEY_IDX] = { .type = NLA_U8 }, |
99 | [NL80211_ATTR_KEY_CIPHER] = { .type = NLA_U32 }, | 99 | [NL80211_ATTR_KEY_CIPHER] = { .type = NLA_U32 }, |
100 | [NL80211_ATTR_KEY_DEFAULT] = { .type = NLA_FLAG }, | 100 | [NL80211_ATTR_KEY_DEFAULT] = { .type = NLA_FLAG }, |
101 | [NL80211_ATTR_KEY_SEQ] = { .type = NLA_BINARY, .len = 8 }, | 101 | [NL80211_ATTR_KEY_SEQ] = { .type = NLA_BINARY, .len = 16 }, |
102 | [NL80211_ATTR_KEY_TYPE] = { .type = NLA_U32 }, | 102 | [NL80211_ATTR_KEY_TYPE] = { .type = NLA_U32 }, |
103 | 103 | ||
104 | [NL80211_ATTR_BEACON_INTERVAL] = { .type = NLA_U32 }, | 104 | [NL80211_ATTR_BEACON_INTERVAL] = { .type = NLA_U32 }, |
@@ -132,8 +132,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { | |||
132 | [NL80211_ATTR_MESH_CONFIG] = { .type = NLA_NESTED }, | 132 | [NL80211_ATTR_MESH_CONFIG] = { .type = NLA_NESTED }, |
133 | [NL80211_ATTR_SUPPORT_MESH_AUTH] = { .type = NLA_FLAG }, | 133 | [NL80211_ATTR_SUPPORT_MESH_AUTH] = { .type = NLA_FLAG }, |
134 | 134 | ||
135 | [NL80211_ATTR_HT_CAPABILITY] = { .type = NLA_BINARY, | 135 | [NL80211_ATTR_HT_CAPABILITY] = { .len = NL80211_HT_CAPABILITY_LEN }, |
136 | .len = NL80211_HT_CAPABILITY_LEN }, | ||
137 | 136 | ||
138 | [NL80211_ATTR_MGMT_SUBTYPE] = { .type = NLA_U8 }, | 137 | [NL80211_ATTR_MGMT_SUBTYPE] = { .type = NLA_U8 }, |
139 | [NL80211_ATTR_IE] = { .type = NLA_BINARY, | 138 | [NL80211_ATTR_IE] = { .type = NLA_BINARY, |
@@ -197,6 +196,9 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { | |||
197 | [NL80211_ATTR_TDLS_OPERATION] = { .type = NLA_U8 }, | 196 | [NL80211_ATTR_TDLS_OPERATION] = { .type = NLA_U8 }, |
198 | [NL80211_ATTR_TDLS_SUPPORT] = { .type = NLA_FLAG }, | 197 | [NL80211_ATTR_TDLS_SUPPORT] = { .type = NLA_FLAG }, |
199 | [NL80211_ATTR_TDLS_EXTERNAL_SETUP] = { .type = NLA_FLAG }, | 198 | [NL80211_ATTR_TDLS_EXTERNAL_SETUP] = { .type = NLA_FLAG }, |
199 | [NL80211_ATTR_DONT_WAIT_FOR_ACK] = { .type = NLA_FLAG }, | ||
200 | [NL80211_ATTR_PROBE_RESP] = { .type = NLA_BINARY, | ||
201 | .len = IEEE80211_MAX_DATA_LEN }, | ||
200 | }; | 202 | }; |
201 | 203 | ||
202 | /* policy for the key attributes */ | 204 | /* policy for the key attributes */ |
@@ -204,7 +206,7 @@ static const struct nla_policy nl80211_key_policy[NL80211_KEY_MAX + 1] = { | |||
204 | [NL80211_KEY_DATA] = { .type = NLA_BINARY, .len = WLAN_MAX_KEY_LEN }, | 206 | [NL80211_KEY_DATA] = { .type = NLA_BINARY, .len = WLAN_MAX_KEY_LEN }, |
205 | [NL80211_KEY_IDX] = { .type = NLA_U8 }, | 207 | [NL80211_KEY_IDX] = { .type = NLA_U8 }, |
206 | [NL80211_KEY_CIPHER] = { .type = NLA_U32 }, | 208 | [NL80211_KEY_CIPHER] = { .type = NLA_U32 }, |
207 | [NL80211_KEY_SEQ] = { .type = NLA_BINARY, .len = 8 }, | 209 | [NL80211_KEY_SEQ] = { .type = NLA_BINARY, .len = 16 }, |
208 | [NL80211_KEY_DEFAULT] = { .type = NLA_FLAG }, | 210 | [NL80211_KEY_DEFAULT] = { .type = NLA_FLAG }, |
209 | [NL80211_KEY_DEFAULT_MGMT] = { .type = NLA_FLAG }, | 211 | [NL80211_KEY_DEFAULT_MGMT] = { .type = NLA_FLAG }, |
210 | [NL80211_KEY_TYPE] = { .type = NLA_U32 }, | 212 | [NL80211_KEY_TYPE] = { .type = NLA_U32 }, |
@@ -759,6 +761,10 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, | |||
759 | NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX, | 761 | NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX, |
760 | dev->wiphy.available_antennas_rx); | 762 | dev->wiphy.available_antennas_rx); |
761 | 763 | ||
764 | if (dev->wiphy.flags & WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD) | ||
765 | NLA_PUT_U32(msg, NL80211_ATTR_PROBE_RESP_OFFLOAD, | ||
766 | dev->wiphy.probe_resp_offload); | ||
767 | |||
762 | if ((dev->wiphy.available_antennas_tx || | 768 | if ((dev->wiphy.available_antennas_tx || |
763 | dev->wiphy.available_antennas_rx) && dev->ops->get_antenna) { | 769 | dev->wiphy.available_antennas_rx) && dev->ops->get_antenna) { |
764 | u32 tx_ant = 0, rx_ant = 0; | 770 | u32 tx_ant = 0, rx_ant = 0; |
@@ -891,6 +897,11 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, | |||
891 | } | 897 | } |
892 | if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) | 898 | if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) |
893 | CMD(sched_scan_start, START_SCHED_SCAN); | 899 | CMD(sched_scan_start, START_SCHED_SCAN); |
900 | CMD(probe_client, PROBE_CLIENT); | ||
901 | if (dev->wiphy.flags & WIPHY_FLAG_REPORTS_OBSS) { | ||
902 | i++; | ||
903 | NLA_PUT_U32(msg, i, NL80211_CMD_REGISTER_BEACONS); | ||
904 | } | ||
894 | 905 | ||
895 | #undef CMD | 906 | #undef CMD |
896 | 907 | ||
@@ -1008,6 +1019,12 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, | |||
1008 | if (nl80211_put_iface_combinations(&dev->wiphy, msg)) | 1019 | if (nl80211_put_iface_combinations(&dev->wiphy, msg)) |
1009 | goto nla_put_failure; | 1020 | goto nla_put_failure; |
1010 | 1021 | ||
1022 | if (dev->wiphy.flags & WIPHY_FLAG_HAVE_AP_SME) | ||
1023 | NLA_PUT_U32(msg, NL80211_ATTR_DEVICE_AP_SME, | ||
1024 | dev->wiphy.ap_sme_capa); | ||
1025 | |||
1026 | NLA_PUT_U32(msg, NL80211_ATTR_FEATURE_FLAGS, dev->wiphy.features); | ||
1027 | |||
1011 | return genlmsg_end(msg, hdr); | 1028 | return genlmsg_end(msg, hdr); |
1012 | 1029 | ||
1013 | nla_put_failure: | 1030 | nla_put_failure: |
@@ -1253,6 +1270,12 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) | |||
1253 | goto bad_res; | 1270 | goto bad_res; |
1254 | } | 1271 | } |
1255 | 1272 | ||
1273 | if (netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && | ||
1274 | netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) { | ||
1275 | result = -EINVAL; | ||
1276 | goto bad_res; | ||
1277 | } | ||
1278 | |||
1256 | nla_for_each_nested(nl_txq_params, | 1279 | nla_for_each_nested(nl_txq_params, |
1257 | info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS], | 1280 | info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS], |
1258 | rem_txq_params) { | 1281 | rem_txq_params) { |
@@ -2150,6 +2173,13 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info) | |||
2150 | nla_len(info->attrs[NL80211_ATTR_IE_ASSOC_RESP]); | 2173 | nla_len(info->attrs[NL80211_ATTR_IE_ASSOC_RESP]); |
2151 | } | 2174 | } |
2152 | 2175 | ||
2176 | if (info->attrs[NL80211_ATTR_PROBE_RESP]) { | ||
2177 | params.probe_resp = | ||
2178 | nla_data(info->attrs[NL80211_ATTR_PROBE_RESP]); | ||
2179 | params.probe_resp_len = | ||
2180 | nla_len(info->attrs[NL80211_ATTR_PROBE_RESP]); | ||
2181 | } | ||
2182 | |||
2153 | err = call(&rdev->wiphy, dev, ¶ms); | 2183 | err = call(&rdev->wiphy, dev, ¶ms); |
2154 | if (!err && params.interval) | 2184 | if (!err && params.interval) |
2155 | wdev->beacon_interval = params.interval; | 2185 | wdev->beacon_interval = params.interval; |
@@ -5266,12 +5296,13 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info) | |||
5266 | bool channel_type_valid = false; | 5296 | bool channel_type_valid = false; |
5267 | u32 freq; | 5297 | u32 freq; |
5268 | int err; | 5298 | int err; |
5269 | void *hdr; | 5299 | void *hdr = NULL; |
5270 | u64 cookie; | 5300 | u64 cookie; |
5271 | struct sk_buff *msg; | 5301 | struct sk_buff *msg = NULL; |
5272 | unsigned int wait = 0; | 5302 | unsigned int wait = 0; |
5273 | bool offchan; | 5303 | bool offchan, no_cck, dont_wait_for_ack; |
5274 | bool no_cck; | 5304 | |
5305 | dont_wait_for_ack = info->attrs[NL80211_ATTR_DONT_WAIT_FOR_ACK]; | ||
5275 | 5306 | ||
5276 | if (!info->attrs[NL80211_ATTR_FRAME] || | 5307 | if (!info->attrs[NL80211_ATTR_FRAME] || |
5277 | !info->attrs[NL80211_ATTR_WIPHY_FREQ]) | 5308 | !info->attrs[NL80211_ATTR_WIPHY_FREQ]) |
@@ -5315,29 +5346,36 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info) | |||
5315 | if (chan == NULL) | 5346 | if (chan == NULL) |
5316 | return -EINVAL; | 5347 | return -EINVAL; |
5317 | 5348 | ||
5318 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | 5349 | if (!dont_wait_for_ack) { |
5319 | if (!msg) | 5350 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); |
5320 | return -ENOMEM; | 5351 | if (!msg) |
5352 | return -ENOMEM; | ||
5321 | 5353 | ||
5322 | hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0, | 5354 | hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0, |
5323 | NL80211_CMD_FRAME); | 5355 | NL80211_CMD_FRAME); |
5324 | 5356 | ||
5325 | if (IS_ERR(hdr)) { | 5357 | if (IS_ERR(hdr)) { |
5326 | err = PTR_ERR(hdr); | 5358 | err = PTR_ERR(hdr); |
5327 | goto free_msg; | 5359 | goto free_msg; |
5360 | } | ||
5328 | } | 5361 | } |
5362 | |||
5329 | err = cfg80211_mlme_mgmt_tx(rdev, dev, chan, offchan, channel_type, | 5363 | err = cfg80211_mlme_mgmt_tx(rdev, dev, chan, offchan, channel_type, |
5330 | channel_type_valid, wait, | 5364 | channel_type_valid, wait, |
5331 | nla_data(info->attrs[NL80211_ATTR_FRAME]), | 5365 | nla_data(info->attrs[NL80211_ATTR_FRAME]), |
5332 | nla_len(info->attrs[NL80211_ATTR_FRAME]), | 5366 | nla_len(info->attrs[NL80211_ATTR_FRAME]), |
5333 | no_cck, &cookie); | 5367 | no_cck, dont_wait_for_ack, &cookie); |
5334 | if (err) | 5368 | if (err) |
5335 | goto free_msg; | 5369 | goto free_msg; |
5336 | 5370 | ||
5337 | NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, cookie); | 5371 | if (msg) { |
5372 | NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, cookie); | ||
5338 | 5373 | ||
5339 | genlmsg_end(msg, hdr); | 5374 | genlmsg_end(msg, hdr); |
5340 | return genlmsg_reply(msg, info); | 5375 | return genlmsg_reply(msg, info); |
5376 | } | ||
5377 | |||
5378 | return 0; | ||
5341 | 5379 | ||
5342 | nla_put_failure: | 5380 | nla_put_failure: |
5343 | err = -ENOBUFS; | 5381 | err = -ENOBUFS; |
@@ -5827,6 +5865,91 @@ static int nl80211_set_rekey_data(struct sk_buff *skb, struct genl_info *info) | |||
5827 | return err; | 5865 | return err; |
5828 | } | 5866 | } |
5829 | 5867 | ||
5868 | static int nl80211_register_unexpected_frame(struct sk_buff *skb, | ||
5869 | struct genl_info *info) | ||
5870 | { | ||
5871 | struct net_device *dev = info->user_ptr[1]; | ||
5872 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
5873 | |||
5874 | if (wdev->iftype != NL80211_IFTYPE_AP && | ||
5875 | wdev->iftype != NL80211_IFTYPE_P2P_GO) | ||
5876 | return -EINVAL; | ||
5877 | |||
5878 | if (wdev->ap_unexpected_nlpid) | ||
5879 | return -EBUSY; | ||
5880 | |||
5881 | wdev->ap_unexpected_nlpid = info->snd_pid; | ||
5882 | return 0; | ||
5883 | } | ||
5884 | |||
5885 | static int nl80211_probe_client(struct sk_buff *skb, | ||
5886 | struct genl_info *info) | ||
5887 | { | ||
5888 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | ||
5889 | struct net_device *dev = info->user_ptr[1]; | ||
5890 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
5891 | struct sk_buff *msg; | ||
5892 | void *hdr; | ||
5893 | const u8 *addr; | ||
5894 | u64 cookie; | ||
5895 | int err; | ||
5896 | |||
5897 | if (wdev->iftype != NL80211_IFTYPE_AP && | ||
5898 | wdev->iftype != NL80211_IFTYPE_P2P_GO) | ||
5899 | return -EOPNOTSUPP; | ||
5900 | |||
5901 | if (!info->attrs[NL80211_ATTR_MAC]) | ||
5902 | return -EINVAL; | ||
5903 | |||
5904 | if (!rdev->ops->probe_client) | ||
5905 | return -EOPNOTSUPP; | ||
5906 | |||
5907 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | ||
5908 | if (!msg) | ||
5909 | return -ENOMEM; | ||
5910 | |||
5911 | hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0, | ||
5912 | NL80211_CMD_PROBE_CLIENT); | ||
5913 | |||
5914 | if (IS_ERR(hdr)) { | ||
5915 | err = PTR_ERR(hdr); | ||
5916 | goto free_msg; | ||
5917 | } | ||
5918 | |||
5919 | addr = nla_data(info->attrs[NL80211_ATTR_MAC]); | ||
5920 | |||
5921 | err = rdev->ops->probe_client(&rdev->wiphy, dev, addr, &cookie); | ||
5922 | if (err) | ||
5923 | goto free_msg; | ||
5924 | |||
5925 | NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, cookie); | ||
5926 | |||
5927 | genlmsg_end(msg, hdr); | ||
5928 | |||
5929 | return genlmsg_reply(msg, info); | ||
5930 | |||
5931 | nla_put_failure: | ||
5932 | err = -ENOBUFS; | ||
5933 | free_msg: | ||
5934 | nlmsg_free(msg); | ||
5935 | return err; | ||
5936 | } | ||
5937 | |||
5938 | static int nl80211_register_beacons(struct sk_buff *skb, struct genl_info *info) | ||
5939 | { | ||
5940 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | ||
5941 | |||
5942 | if (!(rdev->wiphy.flags & WIPHY_FLAG_REPORTS_OBSS)) | ||
5943 | return -EOPNOTSUPP; | ||
5944 | |||
5945 | if (rdev->ap_beacons_nlpid) | ||
5946 | return -EBUSY; | ||
5947 | |||
5948 | rdev->ap_beacons_nlpid = info->snd_pid; | ||
5949 | |||
5950 | return 0; | ||
5951 | } | ||
5952 | |||
5830 | #define NL80211_FLAG_NEED_WIPHY 0x01 | 5953 | #define NL80211_FLAG_NEED_WIPHY 0x01 |
5831 | #define NL80211_FLAG_NEED_NETDEV 0x02 | 5954 | #define NL80211_FLAG_NEED_NETDEV 0x02 |
5832 | #define NL80211_FLAG_NEED_RTNL 0x04 | 5955 | #define NL80211_FLAG_NEED_RTNL 0x04 |
@@ -6382,6 +6505,30 @@ static struct genl_ops nl80211_ops[] = { | |||
6382 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 6505 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | |
6383 | NL80211_FLAG_NEED_RTNL, | 6506 | NL80211_FLAG_NEED_RTNL, |
6384 | }, | 6507 | }, |
6508 | { | ||
6509 | .cmd = NL80211_CMD_UNEXPECTED_FRAME, | ||
6510 | .doit = nl80211_register_unexpected_frame, | ||
6511 | .policy = nl80211_policy, | ||
6512 | .flags = GENL_ADMIN_PERM, | ||
6513 | .internal_flags = NL80211_FLAG_NEED_NETDEV | | ||
6514 | NL80211_FLAG_NEED_RTNL, | ||
6515 | }, | ||
6516 | { | ||
6517 | .cmd = NL80211_CMD_PROBE_CLIENT, | ||
6518 | .doit = nl80211_probe_client, | ||
6519 | .policy = nl80211_policy, | ||
6520 | .flags = GENL_ADMIN_PERM, | ||
6521 | .internal_flags = NL80211_FLAG_NEED_NETDEV | | ||
6522 | NL80211_FLAG_NEED_RTNL, | ||
6523 | }, | ||
6524 | { | ||
6525 | .cmd = NL80211_CMD_REGISTER_BEACONS, | ||
6526 | .doit = nl80211_register_beacons, | ||
6527 | .policy = nl80211_policy, | ||
6528 | .flags = GENL_ADMIN_PERM, | ||
6529 | .internal_flags = NL80211_FLAG_NEED_WIPHY | | ||
6530 | NL80211_FLAG_NEED_RTNL, | ||
6531 | }, | ||
6385 | }; | 6532 | }; |
6386 | 6533 | ||
6387 | static struct genl_multicast_group nl80211_mlme_mcgrp = { | 6534 | static struct genl_multicast_group nl80211_mlme_mcgrp = { |
@@ -6634,10 +6781,7 @@ void nl80211_send_reg_change_event(struct regulatory_request *request) | |||
6634 | if (wiphy_idx_valid(request->wiphy_idx)) | 6781 | if (wiphy_idx_valid(request->wiphy_idx)) |
6635 | NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, request->wiphy_idx); | 6782 | NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, request->wiphy_idx); |
6636 | 6783 | ||
6637 | if (genlmsg_end(msg, hdr) < 0) { | 6784 | genlmsg_end(msg, hdr); |
6638 | nlmsg_free(msg); | ||
6639 | return; | ||
6640 | } | ||
6641 | 6785 | ||
6642 | rcu_read_lock(); | 6786 | rcu_read_lock(); |
6643 | genlmsg_multicast_allns(msg, 0, nl80211_regulatory_mcgrp.id, | 6787 | genlmsg_multicast_allns(msg, 0, nl80211_regulatory_mcgrp.id, |
@@ -6673,10 +6817,7 @@ static void nl80211_send_mlme_event(struct cfg80211_registered_device *rdev, | |||
6673 | NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex); | 6817 | NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex); |
6674 | NLA_PUT(msg, NL80211_ATTR_FRAME, len, buf); | 6818 | NLA_PUT(msg, NL80211_ATTR_FRAME, len, buf); |
6675 | 6819 | ||
6676 | if (genlmsg_end(msg, hdr) < 0) { | 6820 | genlmsg_end(msg, hdr); |
6677 | nlmsg_free(msg); | ||
6678 | return; | ||
6679 | } | ||
6680 | 6821 | ||
6681 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 6822 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, |
6682 | nl80211_mlme_mcgrp.id, gfp); | 6823 | nl80211_mlme_mcgrp.id, gfp); |
@@ -6757,10 +6898,7 @@ static void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev, | |||
6757 | NLA_PUT_FLAG(msg, NL80211_ATTR_TIMED_OUT); | 6898 | NLA_PUT_FLAG(msg, NL80211_ATTR_TIMED_OUT); |
6758 | NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr); | 6899 | NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr); |
6759 | 6900 | ||
6760 | if (genlmsg_end(msg, hdr) < 0) { | 6901 | genlmsg_end(msg, hdr); |
6761 | nlmsg_free(msg); | ||
6762 | return; | ||
6763 | } | ||
6764 | 6902 | ||
6765 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 6903 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, |
6766 | nl80211_mlme_mcgrp.id, gfp); | 6904 | nl80211_mlme_mcgrp.id, gfp); |
@@ -6816,10 +6954,7 @@ void nl80211_send_connect_result(struct cfg80211_registered_device *rdev, | |||
6816 | if (resp_ie) | 6954 | if (resp_ie) |
6817 | NLA_PUT(msg, NL80211_ATTR_RESP_IE, resp_ie_len, resp_ie); | 6955 | NLA_PUT(msg, NL80211_ATTR_RESP_IE, resp_ie_len, resp_ie); |
6818 | 6956 | ||
6819 | if (genlmsg_end(msg, hdr) < 0) { | 6957 | genlmsg_end(msg, hdr); |
6820 | nlmsg_free(msg); | ||
6821 | return; | ||
6822 | } | ||
6823 | 6958 | ||
6824 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 6959 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, |
6825 | nl80211_mlme_mcgrp.id, gfp); | 6960 | nl80211_mlme_mcgrp.id, gfp); |
@@ -6857,10 +6992,7 @@ void nl80211_send_roamed(struct cfg80211_registered_device *rdev, | |||
6857 | if (resp_ie) | 6992 | if (resp_ie) |
6858 | NLA_PUT(msg, NL80211_ATTR_RESP_IE, resp_ie_len, resp_ie); | 6993 | NLA_PUT(msg, NL80211_ATTR_RESP_IE, resp_ie_len, resp_ie); |
6859 | 6994 | ||
6860 | if (genlmsg_end(msg, hdr) < 0) { | 6995 | genlmsg_end(msg, hdr); |
6861 | nlmsg_free(msg); | ||
6862 | return; | ||
6863 | } | ||
6864 | 6996 | ||
6865 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 6997 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, |
6866 | nl80211_mlme_mcgrp.id, gfp); | 6998 | nl80211_mlme_mcgrp.id, gfp); |
@@ -6898,10 +7030,7 @@ void nl80211_send_disconnected(struct cfg80211_registered_device *rdev, | |||
6898 | if (ie) | 7030 | if (ie) |
6899 | NLA_PUT(msg, NL80211_ATTR_IE, ie_len, ie); | 7031 | NLA_PUT(msg, NL80211_ATTR_IE, ie_len, ie); |
6900 | 7032 | ||
6901 | if (genlmsg_end(msg, hdr) < 0) { | 7033 | genlmsg_end(msg, hdr); |
6902 | nlmsg_free(msg); | ||
6903 | return; | ||
6904 | } | ||
6905 | 7034 | ||
6906 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 7035 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, |
6907 | nl80211_mlme_mcgrp.id, GFP_KERNEL); | 7036 | nl80211_mlme_mcgrp.id, GFP_KERNEL); |
@@ -6934,10 +7063,7 @@ void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev, | |||
6934 | NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex); | 7063 | NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex); |
6935 | NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid); | 7064 | NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid); |
6936 | 7065 | ||
6937 | if (genlmsg_end(msg, hdr) < 0) { | 7066 | genlmsg_end(msg, hdr); |
6938 | nlmsg_free(msg); | ||
6939 | return; | ||
6940 | } | ||
6941 | 7067 | ||
6942 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 7068 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, |
6943 | nl80211_mlme_mcgrp.id, gfp); | 7069 | nl80211_mlme_mcgrp.id, gfp); |
@@ -6972,10 +7098,7 @@ void nl80211_send_new_peer_candidate(struct cfg80211_registered_device *rdev, | |||
6972 | if (ie_len && ie) | 7098 | if (ie_len && ie) |
6973 | NLA_PUT(msg, NL80211_ATTR_IE, ie_len , ie); | 7099 | NLA_PUT(msg, NL80211_ATTR_IE, ie_len , ie); |
6974 | 7100 | ||
6975 | if (genlmsg_end(msg, hdr) < 0) { | 7101 | genlmsg_end(msg, hdr); |
6976 | nlmsg_free(msg); | ||
6977 | return; | ||
6978 | } | ||
6979 | 7102 | ||
6980 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 7103 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, |
6981 | nl80211_mlme_mcgrp.id, gfp); | 7104 | nl80211_mlme_mcgrp.id, gfp); |
@@ -7014,10 +7137,7 @@ void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev, | |||
7014 | if (tsc) | 7137 | if (tsc) |
7015 | NLA_PUT(msg, NL80211_ATTR_KEY_SEQ, 6, tsc); | 7138 | NLA_PUT(msg, NL80211_ATTR_KEY_SEQ, 6, tsc); |
7016 | 7139 | ||
7017 | if (genlmsg_end(msg, hdr) < 0) { | 7140 | genlmsg_end(msg, hdr); |
7018 | nlmsg_free(msg); | ||
7019 | return; | ||
7020 | } | ||
7021 | 7141 | ||
7022 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 7142 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, |
7023 | nl80211_mlme_mcgrp.id, gfp); | 7143 | nl80211_mlme_mcgrp.id, gfp); |
@@ -7068,10 +7188,7 @@ void nl80211_send_beacon_hint_event(struct wiphy *wiphy, | |||
7068 | goto nla_put_failure; | 7188 | goto nla_put_failure; |
7069 | nla_nest_end(msg, nl_freq); | 7189 | nla_nest_end(msg, nl_freq); |
7070 | 7190 | ||
7071 | if (genlmsg_end(msg, hdr) < 0) { | 7191 | genlmsg_end(msg, hdr); |
7072 | nlmsg_free(msg); | ||
7073 | return; | ||
7074 | } | ||
7075 | 7192 | ||
7076 | rcu_read_lock(); | 7193 | rcu_read_lock(); |
7077 | genlmsg_multicast_allns(msg, 0, nl80211_regulatory_mcgrp.id, | 7194 | genlmsg_multicast_allns(msg, 0, nl80211_regulatory_mcgrp.id, |
@@ -7114,10 +7231,7 @@ static void nl80211_send_remain_on_chan_event( | |||
7114 | if (cmd == NL80211_CMD_REMAIN_ON_CHANNEL) | 7231 | if (cmd == NL80211_CMD_REMAIN_ON_CHANNEL) |
7115 | NLA_PUT_U32(msg, NL80211_ATTR_DURATION, duration); | 7232 | NLA_PUT_U32(msg, NL80211_ATTR_DURATION, duration); |
7116 | 7233 | ||
7117 | if (genlmsg_end(msg, hdr) < 0) { | 7234 | genlmsg_end(msg, hdr); |
7118 | nlmsg_free(msg); | ||
7119 | return; | ||
7120 | } | ||
7121 | 7235 | ||
7122 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 7236 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, |
7123 | nl80211_mlme_mcgrp.id, gfp); | 7237 | nl80211_mlme_mcgrp.id, gfp); |
@@ -7188,10 +7302,7 @@ void nl80211_send_sta_del_event(struct cfg80211_registered_device *rdev, | |||
7188 | NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex); | 7302 | NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex); |
7189 | NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr); | 7303 | NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr); |
7190 | 7304 | ||
7191 | if (genlmsg_end(msg, hdr) < 0) { | 7305 | genlmsg_end(msg, hdr); |
7192 | nlmsg_free(msg); | ||
7193 | return; | ||
7194 | } | ||
7195 | 7306 | ||
7196 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 7307 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, |
7197 | nl80211_mlme_mcgrp.id, gfp); | 7308 | nl80211_mlme_mcgrp.id, gfp); |
@@ -7202,13 +7313,68 @@ void nl80211_send_sta_del_event(struct cfg80211_registered_device *rdev, | |||
7202 | nlmsg_free(msg); | 7313 | nlmsg_free(msg); |
7203 | } | 7314 | } |
7204 | 7315 | ||
7316 | static bool __nl80211_unexpected_frame(struct net_device *dev, u8 cmd, | ||
7317 | const u8 *addr, gfp_t gfp) | ||
7318 | { | ||
7319 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
7320 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | ||
7321 | struct sk_buff *msg; | ||
7322 | void *hdr; | ||
7323 | int err; | ||
7324 | u32 nlpid = ACCESS_ONCE(wdev->ap_unexpected_nlpid); | ||
7325 | |||
7326 | if (!nlpid) | ||
7327 | return false; | ||
7328 | |||
7329 | msg = nlmsg_new(100, gfp); | ||
7330 | if (!msg) | ||
7331 | return true; | ||
7332 | |||
7333 | hdr = nl80211hdr_put(msg, 0, 0, 0, cmd); | ||
7334 | if (!hdr) { | ||
7335 | nlmsg_free(msg); | ||
7336 | return true; | ||
7337 | } | ||
7338 | |||
7339 | NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); | ||
7340 | NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex); | ||
7341 | NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr); | ||
7342 | |||
7343 | err = genlmsg_end(msg, hdr); | ||
7344 | if (err < 0) { | ||
7345 | nlmsg_free(msg); | ||
7346 | return true; | ||
7347 | } | ||
7348 | |||
7349 | genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlpid); | ||
7350 | return true; | ||
7351 | |||
7352 | nla_put_failure: | ||
7353 | genlmsg_cancel(msg, hdr); | ||
7354 | nlmsg_free(msg); | ||
7355 | return true; | ||
7356 | } | ||
7357 | |||
7358 | bool nl80211_unexpected_frame(struct net_device *dev, const u8 *addr, gfp_t gfp) | ||
7359 | { | ||
7360 | return __nl80211_unexpected_frame(dev, NL80211_CMD_UNEXPECTED_FRAME, | ||
7361 | addr, gfp); | ||
7362 | } | ||
7363 | |||
7364 | bool nl80211_unexpected_4addr_frame(struct net_device *dev, | ||
7365 | const u8 *addr, gfp_t gfp) | ||
7366 | { | ||
7367 | return __nl80211_unexpected_frame(dev, | ||
7368 | NL80211_CMD_UNEXPECTED_4ADDR_FRAME, | ||
7369 | addr, gfp); | ||
7370 | } | ||
7371 | |||
7205 | int nl80211_send_mgmt(struct cfg80211_registered_device *rdev, | 7372 | int nl80211_send_mgmt(struct cfg80211_registered_device *rdev, |
7206 | struct net_device *netdev, u32 nlpid, | 7373 | struct net_device *netdev, u32 nlpid, |
7207 | int freq, const u8 *buf, size_t len, gfp_t gfp) | 7374 | int freq, const u8 *buf, size_t len, gfp_t gfp) |
7208 | { | 7375 | { |
7209 | struct sk_buff *msg; | 7376 | struct sk_buff *msg; |
7210 | void *hdr; | 7377 | void *hdr; |
7211 | int err; | ||
7212 | 7378 | ||
7213 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); | 7379 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); |
7214 | if (!msg) | 7380 | if (!msg) |
@@ -7225,16 +7391,9 @@ int nl80211_send_mgmt(struct cfg80211_registered_device *rdev, | |||
7225 | NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq); | 7391 | NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq); |
7226 | NLA_PUT(msg, NL80211_ATTR_FRAME, len, buf); | 7392 | NLA_PUT(msg, NL80211_ATTR_FRAME, len, buf); |
7227 | 7393 | ||
7228 | err = genlmsg_end(msg, hdr); | 7394 | genlmsg_end(msg, hdr); |
7229 | if (err < 0) { | ||
7230 | nlmsg_free(msg); | ||
7231 | return err; | ||
7232 | } | ||
7233 | 7395 | ||
7234 | err = genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlpid); | 7396 | return genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlpid); |
7235 | if (err < 0) | ||
7236 | return err; | ||
7237 | return 0; | ||
7238 | 7397 | ||
7239 | nla_put_failure: | 7398 | nla_put_failure: |
7240 | genlmsg_cancel(msg, hdr); | 7399 | genlmsg_cancel(msg, hdr); |
@@ -7267,10 +7426,7 @@ void nl80211_send_mgmt_tx_status(struct cfg80211_registered_device *rdev, | |||
7267 | if (ack) | 7426 | if (ack) |
7268 | NLA_PUT_FLAG(msg, NL80211_ATTR_ACK); | 7427 | NLA_PUT_FLAG(msg, NL80211_ATTR_ACK); |
7269 | 7428 | ||
7270 | if (genlmsg_end(msg, hdr) < 0) { | 7429 | genlmsg_end(msg, hdr); |
7271 | nlmsg_free(msg); | ||
7272 | return; | ||
7273 | } | ||
7274 | 7430 | ||
7275 | genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, gfp); | 7431 | genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, gfp); |
7276 | return; | 7432 | return; |
@@ -7312,10 +7468,7 @@ nl80211_send_cqm_rssi_notify(struct cfg80211_registered_device *rdev, | |||
7312 | 7468 | ||
7313 | nla_nest_end(msg, pinfoattr); | 7469 | nla_nest_end(msg, pinfoattr); |
7314 | 7470 | ||
7315 | if (genlmsg_end(msg, hdr) < 0) { | 7471 | genlmsg_end(msg, hdr); |
7316 | nlmsg_free(msg); | ||
7317 | return; | ||
7318 | } | ||
7319 | 7472 | ||
7320 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 7473 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, |
7321 | nl80211_mlme_mcgrp.id, gfp); | 7474 | nl80211_mlme_mcgrp.id, gfp); |
@@ -7357,10 +7510,7 @@ void nl80211_gtk_rekey_notify(struct cfg80211_registered_device *rdev, | |||
7357 | 7510 | ||
7358 | nla_nest_end(msg, rekey_attr); | 7511 | nla_nest_end(msg, rekey_attr); |
7359 | 7512 | ||
7360 | if (genlmsg_end(msg, hdr) < 0) { | 7513 | genlmsg_end(msg, hdr); |
7361 | nlmsg_free(msg); | ||
7362 | return; | ||
7363 | } | ||
7364 | 7514 | ||
7365 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 7515 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, |
7366 | nl80211_mlme_mcgrp.id, gfp); | 7516 | nl80211_mlme_mcgrp.id, gfp); |
@@ -7403,10 +7553,7 @@ void nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev, | |||
7403 | 7553 | ||
7404 | nla_nest_end(msg, attr); | 7554 | nla_nest_end(msg, attr); |
7405 | 7555 | ||
7406 | if (genlmsg_end(msg, hdr) < 0) { | 7556 | genlmsg_end(msg, hdr); |
7407 | nlmsg_free(msg); | ||
7408 | return; | ||
7409 | } | ||
7410 | 7557 | ||
7411 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 7558 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, |
7412 | nl80211_mlme_mcgrp.id, gfp); | 7559 | nl80211_mlme_mcgrp.id, gfp); |
@@ -7448,7 +7595,45 @@ nl80211_send_cqm_pktloss_notify(struct cfg80211_registered_device *rdev, | |||
7448 | 7595 | ||
7449 | nla_nest_end(msg, pinfoattr); | 7596 | nla_nest_end(msg, pinfoattr); |
7450 | 7597 | ||
7451 | if (genlmsg_end(msg, hdr) < 0) { | 7598 | genlmsg_end(msg, hdr); |
7599 | |||
7600 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | ||
7601 | nl80211_mlme_mcgrp.id, gfp); | ||
7602 | return; | ||
7603 | |||
7604 | nla_put_failure: | ||
7605 | genlmsg_cancel(msg, hdr); | ||
7606 | nlmsg_free(msg); | ||
7607 | } | ||
7608 | |||
7609 | void cfg80211_probe_status(struct net_device *dev, const u8 *addr, | ||
7610 | u64 cookie, bool acked, gfp_t gfp) | ||
7611 | { | ||
7612 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
7613 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | ||
7614 | struct sk_buff *msg; | ||
7615 | void *hdr; | ||
7616 | int err; | ||
7617 | |||
7618 | msg = nlmsg_new(NLMSG_GOODSIZE, gfp); | ||
7619 | if (!msg) | ||
7620 | return; | ||
7621 | |||
7622 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PROBE_CLIENT); | ||
7623 | if (!hdr) { | ||
7624 | nlmsg_free(msg); | ||
7625 | return; | ||
7626 | } | ||
7627 | |||
7628 | NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); | ||
7629 | NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex); | ||
7630 | NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr); | ||
7631 | NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, cookie); | ||
7632 | if (acked) | ||
7633 | NLA_PUT_FLAG(msg, NL80211_ATTR_ACK); | ||
7634 | |||
7635 | err = genlmsg_end(msg, hdr); | ||
7636 | if (err < 0) { | ||
7452 | nlmsg_free(msg); | 7637 | nlmsg_free(msg); |
7453 | return; | 7638 | return; |
7454 | } | 7639 | } |
@@ -7461,6 +7646,45 @@ nl80211_send_cqm_pktloss_notify(struct cfg80211_registered_device *rdev, | |||
7461 | genlmsg_cancel(msg, hdr); | 7646 | genlmsg_cancel(msg, hdr); |
7462 | nlmsg_free(msg); | 7647 | nlmsg_free(msg); |
7463 | } | 7648 | } |
7649 | EXPORT_SYMBOL(cfg80211_probe_status); | ||
7650 | |||
7651 | void cfg80211_report_obss_beacon(struct wiphy *wiphy, | ||
7652 | const u8 *frame, size_t len, | ||
7653 | int freq, gfp_t gfp) | ||
7654 | { | ||
7655 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | ||
7656 | struct sk_buff *msg; | ||
7657 | void *hdr; | ||
7658 | u32 nlpid = ACCESS_ONCE(rdev->ap_beacons_nlpid); | ||
7659 | |||
7660 | if (!nlpid) | ||
7661 | return; | ||
7662 | |||
7663 | msg = nlmsg_new(len + 100, gfp); | ||
7664 | if (!msg) | ||
7665 | return; | ||
7666 | |||
7667 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME); | ||
7668 | if (!hdr) { | ||
7669 | nlmsg_free(msg); | ||
7670 | return; | ||
7671 | } | ||
7672 | |||
7673 | NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); | ||
7674 | if (freq) | ||
7675 | NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq); | ||
7676 | NLA_PUT(msg, NL80211_ATTR_FRAME, len, frame); | ||
7677 | |||
7678 | genlmsg_end(msg, hdr); | ||
7679 | |||
7680 | genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlpid); | ||
7681 | return; | ||
7682 | |||
7683 | nla_put_failure: | ||
7684 | genlmsg_cancel(msg, hdr); | ||
7685 | nlmsg_free(msg); | ||
7686 | } | ||
7687 | EXPORT_SYMBOL(cfg80211_report_obss_beacon); | ||
7464 | 7688 | ||
7465 | static int nl80211_netlink_notify(struct notifier_block * nb, | 7689 | static int nl80211_netlink_notify(struct notifier_block * nb, |
7466 | unsigned long state, | 7690 | unsigned long state, |
@@ -7475,9 +7699,12 @@ static int nl80211_netlink_notify(struct notifier_block * nb, | |||
7475 | 7699 | ||
7476 | rcu_read_lock(); | 7700 | rcu_read_lock(); |
7477 | 7701 | ||
7478 | list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list) | 7702 | list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list) { |
7479 | list_for_each_entry_rcu(wdev, &rdev->netdev_list, list) | 7703 | list_for_each_entry_rcu(wdev, &rdev->netdev_list, list) |
7480 | cfg80211_mlme_unregister_socket(wdev, notify->pid); | 7704 | cfg80211_mlme_unregister_socket(wdev, notify->pid); |
7705 | if (rdev->ap_beacons_nlpid == notify->pid) | ||
7706 | rdev->ap_beacons_nlpid = 0; | ||
7707 | } | ||
7481 | 7708 | ||
7482 | rcu_read_unlock(); | 7709 | rcu_read_unlock(); |
7483 | 7710 | ||
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h index f24a1fbeaf19..12bf4d185abe 100644 --- a/net/wireless/nl80211.h +++ b/net/wireless/nl80211.h | |||
@@ -117,4 +117,9 @@ void nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev, | |||
117 | struct net_device *netdev, int index, | 117 | struct net_device *netdev, int index, |
118 | const u8 *bssid, bool preauth, gfp_t gfp); | 118 | const u8 *bssid, bool preauth, gfp_t gfp); |
119 | 119 | ||
120 | bool nl80211_unexpected_frame(struct net_device *dev, | ||
121 | const u8 *addr, gfp_t gfp); | ||
122 | bool nl80211_unexpected_4addr_frame(struct net_device *dev, | ||
123 | const u8 *addr, gfp_t gfp); | ||
124 | |||
120 | #endif /* __NET_WIRELESS_NL80211_H */ | 125 | #endif /* __NET_WIRELESS_NL80211_H */ |
diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 0fb142410404..31119e32e092 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c | |||
@@ -259,17 +259,20 @@ static int cmp_ies(u8 num, u8 *ies1, size_t len1, u8 *ies2, size_t len2) | |||
259 | { | 259 | { |
260 | const u8 *ie1 = cfg80211_find_ie(num, ies1, len1); | 260 | const u8 *ie1 = cfg80211_find_ie(num, ies1, len1); |
261 | const u8 *ie2 = cfg80211_find_ie(num, ies2, len2); | 261 | const u8 *ie2 = cfg80211_find_ie(num, ies2, len2); |
262 | int r; | ||
263 | 262 | ||
263 | /* equal if both missing */ | ||
264 | if (!ie1 && !ie2) | 264 | if (!ie1 && !ie2) |
265 | return 0; | 265 | return 0; |
266 | if (!ie1 || !ie2) | 266 | /* sort missing IE before (left of) present IE */ |
267 | if (!ie1) | ||
267 | return -1; | 268 | return -1; |
269 | if (!ie2) | ||
270 | return 1; | ||
268 | 271 | ||
269 | r = memcmp(ie1 + 2, ie2 + 2, min(ie1[1], ie2[1])); | 272 | /* sort by length first, then by contents */ |
270 | if (r == 0 && ie1[1] != ie2[1]) | 273 | if (ie1[1] != ie2[1]) |
271 | return ie2[1] - ie1[1]; | 274 | return ie2[1] - ie1[1]; |
272 | return r; | 275 | return memcmp(ie1 + 2, ie2 + 2, ie1[1]); |
273 | } | 276 | } |
274 | 277 | ||
275 | static bool is_bss(struct cfg80211_bss *a, | 278 | static bool is_bss(struct cfg80211_bss *a, |
@@ -352,8 +355,8 @@ static bool is_mesh(struct cfg80211_bss *a, | |||
352 | sizeof(struct ieee80211_meshconf_ie) - 2) == 0; | 355 | sizeof(struct ieee80211_meshconf_ie) - 2) == 0; |
353 | } | 356 | } |
354 | 357 | ||
355 | static int cmp_bss(struct cfg80211_bss *a, | 358 | static int cmp_bss_core(struct cfg80211_bss *a, |
356 | struct cfg80211_bss *b) | 359 | struct cfg80211_bss *b) |
357 | { | 360 | { |
358 | int r; | 361 | int r; |
359 | 362 | ||
@@ -375,7 +378,15 @@ static int cmp_bss(struct cfg80211_bss *a, | |||
375 | b->len_information_elements); | 378 | b->len_information_elements); |
376 | } | 379 | } |
377 | 380 | ||
378 | r = memcmp(a->bssid, b->bssid, ETH_ALEN); | 381 | return memcmp(a->bssid, b->bssid, ETH_ALEN); |
382 | } | ||
383 | |||
384 | static int cmp_bss(struct cfg80211_bss *a, | ||
385 | struct cfg80211_bss *b) | ||
386 | { | ||
387 | int r; | ||
388 | |||
389 | r = cmp_bss_core(a, b); | ||
379 | if (r) | 390 | if (r) |
380 | return r; | 391 | return r; |
381 | 392 | ||
@@ -386,6 +397,52 @@ static int cmp_bss(struct cfg80211_bss *a, | |||
386 | b->len_information_elements); | 397 | b->len_information_elements); |
387 | } | 398 | } |
388 | 399 | ||
400 | static int cmp_hidden_bss(struct cfg80211_bss *a, | ||
401 | struct cfg80211_bss *b) | ||
402 | { | ||
403 | const u8 *ie1; | ||
404 | const u8 *ie2; | ||
405 | int i; | ||
406 | int r; | ||
407 | |||
408 | r = cmp_bss_core(a, b); | ||
409 | if (r) | ||
410 | return r; | ||
411 | |||
412 | ie1 = cfg80211_find_ie(WLAN_EID_SSID, | ||
413 | a->information_elements, | ||
414 | a->len_information_elements); | ||
415 | ie2 = cfg80211_find_ie(WLAN_EID_SSID, | ||
416 | b->information_elements, | ||
417 | b->len_information_elements); | ||
418 | |||
419 | /* Key comparator must use same algorithm in any rb-tree | ||
420 | * search function (order is important), otherwise ordering | ||
421 | * of items in the tree is broken and search gives incorrect | ||
422 | * results. This code uses same order as cmp_ies() does. */ | ||
423 | |||
424 | /* sort missing IE before (left of) present IE */ | ||
425 | if (!ie1) | ||
426 | return -1; | ||
427 | if (!ie2) | ||
428 | return 1; | ||
429 | |||
430 | /* zero-size SSID is used as an indication of the hidden bss */ | ||
431 | if (!ie2[1]) | ||
432 | return 0; | ||
433 | |||
434 | /* sort by length first, then by contents */ | ||
435 | if (ie1[1] != ie2[1]) | ||
436 | return ie2[1] - ie1[1]; | ||
437 | |||
438 | /* zeroed SSID ie is another indication of a hidden bss */ | ||
439 | for (i = 0; i < ie2[1]; i++) | ||
440 | if (ie2[i + 2]) | ||
441 | return -1; | ||
442 | |||
443 | return 0; | ||
444 | } | ||
445 | |||
389 | struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy, | 446 | struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy, |
390 | struct ieee80211_channel *channel, | 447 | struct ieee80211_channel *channel, |
391 | const u8 *bssid, | 448 | const u8 *bssid, |
@@ -502,6 +559,48 @@ rb_find_bss(struct cfg80211_registered_device *dev, | |||
502 | } | 559 | } |
503 | 560 | ||
504 | static struct cfg80211_internal_bss * | 561 | static struct cfg80211_internal_bss * |
562 | rb_find_hidden_bss(struct cfg80211_registered_device *dev, | ||
563 | struct cfg80211_internal_bss *res) | ||
564 | { | ||
565 | struct rb_node *n = dev->bss_tree.rb_node; | ||
566 | struct cfg80211_internal_bss *bss; | ||
567 | int r; | ||
568 | |||
569 | while (n) { | ||
570 | bss = rb_entry(n, struct cfg80211_internal_bss, rbn); | ||
571 | r = cmp_hidden_bss(&res->pub, &bss->pub); | ||
572 | |||
573 | if (r == 0) | ||
574 | return bss; | ||
575 | else if (r < 0) | ||
576 | n = n->rb_left; | ||
577 | else | ||
578 | n = n->rb_right; | ||
579 | } | ||
580 | |||
581 | return NULL; | ||
582 | } | ||
583 | |||
584 | static void | ||
585 | copy_hidden_ies(struct cfg80211_internal_bss *res, | ||
586 | struct cfg80211_internal_bss *hidden) | ||
587 | { | ||
588 | if (unlikely(res->pub.beacon_ies)) | ||
589 | return; | ||
590 | if (WARN_ON(!hidden->pub.beacon_ies)) | ||
591 | return; | ||
592 | |||
593 | res->pub.beacon_ies = kmalloc(hidden->pub.len_beacon_ies, GFP_ATOMIC); | ||
594 | if (unlikely(!res->pub.beacon_ies)) | ||
595 | return; | ||
596 | |||
597 | res->beacon_ies_allocated = true; | ||
598 | res->pub.len_beacon_ies = hidden->pub.len_beacon_ies; | ||
599 | memcpy(res->pub.beacon_ies, hidden->pub.beacon_ies, | ||
600 | res->pub.len_beacon_ies); | ||
601 | } | ||
602 | |||
603 | static struct cfg80211_internal_bss * | ||
505 | cfg80211_bss_update(struct cfg80211_registered_device *dev, | 604 | cfg80211_bss_update(struct cfg80211_registered_device *dev, |
506 | struct cfg80211_internal_bss *res) | 605 | struct cfg80211_internal_bss *res) |
507 | { | 606 | { |
@@ -604,6 +703,21 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev, | |||
604 | 703 | ||
605 | kref_put(&res->ref, bss_release); | 704 | kref_put(&res->ref, bss_release); |
606 | } else { | 705 | } else { |
706 | struct cfg80211_internal_bss *hidden; | ||
707 | |||
708 | /* First check if the beacon is a probe response from | ||
709 | * a hidden bss. If so, copy beacon ies (with nullified | ||
710 | * ssid) into the probe response bss entry (with real ssid). | ||
711 | * It is required basically for PSM implementation | ||
712 | * (probe responses do not contain tim ie) */ | ||
713 | |||
714 | /* TODO: The code is not trying to update existing probe | ||
715 | * response bss entries when beacon ies are | ||
716 | * getting changed. */ | ||
717 | hidden = rb_find_hidden_bss(dev, res); | ||
718 | if (hidden) | ||
719 | copy_hidden_ies(res, hidden); | ||
720 | |||
607 | /* this "consumes" the reference */ | 721 | /* this "consumes" the reference */ |
608 | list_add_tail(&res->list, &dev->bss_list); | 722 | list_add_tail(&res->list, &dev->bss_list); |
609 | rb_insert_bss(dev, res); | 723 | rb_insert_bss(dev, res); |
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c index 6897436b1d3f..3c24eb97e9d7 100644 --- a/net/wireless/wext-compat.c +++ b/net/wireless/wext-compat.c | |||
@@ -819,12 +819,24 @@ static int cfg80211_wext_giwfreq(struct net_device *dev, | |||
819 | struct iw_freq *freq, char *extra) | 819 | struct iw_freq *freq, char *extra) |
820 | { | 820 | { |
821 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 821 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
822 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | ||
823 | struct ieee80211_channel *chan; | ||
822 | 824 | ||
823 | switch (wdev->iftype) { | 825 | switch (wdev->iftype) { |
824 | case NL80211_IFTYPE_STATION: | 826 | case NL80211_IFTYPE_STATION: |
825 | return cfg80211_mgd_wext_giwfreq(dev, info, freq, extra); | 827 | return cfg80211_mgd_wext_giwfreq(dev, info, freq, extra); |
826 | case NL80211_IFTYPE_ADHOC: | 828 | case NL80211_IFTYPE_ADHOC: |
827 | return cfg80211_ibss_wext_giwfreq(dev, info, freq, extra); | 829 | return cfg80211_ibss_wext_giwfreq(dev, info, freq, extra); |
830 | case NL80211_IFTYPE_MONITOR: | ||
831 | if (!rdev->ops->get_channel) | ||
832 | return -EINVAL; | ||
833 | |||
834 | chan = rdev->ops->get_channel(wdev->wiphy); | ||
835 | if (!chan) | ||
836 | return -EINVAL; | ||
837 | freq->m = chan->center_freq; | ||
838 | freq->e = 6; | ||
839 | return 0; | ||
828 | default: | 840 | default: |
829 | if (!wdev->channel) | 841 | if (!wdev->channel) |
830 | return -EINVAL; | 842 | return -EINVAL; |