#define BT_ISO_BASE            20
 
+/* Socket option value 21 reserved */
+
+#define BT_PKT_SEQNUM          22
+
+#define BT_SCM_PKT_SEQNUM      0x05
+
 __printf(1, 2)
 void bt_info(const char *fmt, ...);
 __printf(1, 2)
 enum {
        BT_SK_DEFER_SETUP,
        BT_SK_SUSPEND,
-       BT_SK_PKT_STATUS
+       BT_SK_PKT_STATUS,
+       BT_SK_PKT_SEQNUM,
 };
 
 struct bt_sock_list {
        u8 pkt_type;
        u8 force_active;
        u16 expect;
+       u16 pkt_seqnum;
        u8 incoming:1;
        u8 pkt_status:2;
        union {
 
 #define hci_skb_pkt_type(skb) bt_cb((skb))->pkt_type
 #define hci_skb_pkt_status(skb) bt_cb((skb))->pkt_status
+#define hci_skb_pkt_seqnum(skb) bt_cb((skb))->pkt_seqnum
 #define hci_skb_expect(skb) bt_cb((skb))->expect
 #define hci_skb_opcode(skb) bt_cb((skb))->hci.opcode
 #define hci_skb_event(skb) bt_cb((skb))->hci.req_event
 
                        put_cmsg(msg, SOL_BLUETOOTH, BT_SCM_PKT_STATUS,
                                 sizeof(pkt_status), &pkt_status);
                }
+
+               if (test_bit(BT_SK_PKT_SEQNUM, &bt_sk(sk)->flags)) {
+                       u16 pkt_seqnum = hci_skb_pkt_seqnum(skb);
+
+                       put_cmsg(msg, SOL_BLUETOOTH, BT_SCM_PKT_SEQNUM,
+                                sizeof(pkt_seqnum), &pkt_seqnum);
+               }
        }
 
        skb_free_datagram(sk, skb);
 
                        clear_bit(BT_SK_PKT_STATUS, &bt_sk(sk)->flags);
                break;
 
+       case BT_PKT_SEQNUM:
+               err = copy_safe_from_sockptr(&opt, sizeof(opt), optval, optlen);
+               if (err)
+                       break;
+
+               if (opt)
+                       set_bit(BT_SK_PKT_SEQNUM, &bt_sk(sk)->flags);
+               else
+                       clear_bit(BT_SK_PKT_SEQNUM, &bt_sk(sk)->flags);
+               break;
+
        case BT_ISO_QOS:
                if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND &&
                    sk->sk_state != BT_CONNECT2 &&
 void iso_recv(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
 {
        struct iso_conn *conn = hcon->iso_data;
-       __u16 pb, ts, len;
+       __u16 pb, ts, len, sn;
 
        if (!conn)
                goto drop;
                                goto drop;
                        }
 
+                       sn = __le16_to_cpu(hdr->sn);
                        len = __le16_to_cpu(hdr->slen);
                } else {
                        struct hci_iso_data_hdr *hdr;
                                goto drop;
                        }
 
+                       sn = __le16_to_cpu(hdr->sn);
                        len = __le16_to_cpu(hdr->slen);
                }
 
                flags  = hci_iso_data_flags(len);
                len    = hci_iso_data_len(len);
 
-               BT_DBG("Start: total len %d, frag len %d flags 0x%4.4x", len,
-                      skb->len, flags);
+               BT_DBG("Start: total len %d, frag len %d flags 0x%4.4x sn %d",
+                      len, skb->len, flags, sn);
 
                if (len == skb->len) {
                        /* Complete frame received */
                        hci_skb_pkt_status(skb) = flags & 0x03;
+                       hci_skb_pkt_seqnum(skb) = sn;
                        iso_recv_frame(conn, skb);
                        return;
                }
                        goto drop;
 
                hci_skb_pkt_status(conn->rx_skb) = flags & 0x03;
+               hci_skb_pkt_seqnum(conn->rx_skb) = sn;
                skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
                                          skb->len);
                conn->rx_len = len - skb->len;