Commit f89cef09 authored by Andrei Emeltchenko's avatar Andrei Emeltchenko Committed by Gustavo F. Padovan

Bluetooth: EFS: add efs option in L2CAP conf req

Add Extended Flow Specification option when building L2CAP
Configuration Request. EFS is added if both the local and
remote L2CAP entities have indicated support for the
Extended Flow Specification for BR/EDR.

...
< ACL data: handle 1 flags 0x00 dlen 10
    L2CAP(s): Info req: type 2
> ACL data: handle 1 flags 0x02 dlen 16
    L2CAP(s): Info rsp: type 2 result 0
      Extended feature mask 0x01f8
        Enhanced Retransmission mode
        Streaming mode
        FCS Option
        Extended Flow Specification
        Fixed Channels
        Extended Window Size
...
< ACL data: handle 1 flags 0x00 dlen 45
    L2CAP(s): Config req: dcid 0x0040 flags 0x00 clen 33
      RFC 0x03 (Enhanced Retransmission, TxWin 63, MaxTx 3, RTo 0, MTo 0, MPS 498)
      EFS (Id 0x01, SerType Best Effort, MaxSDU 0xffff, SDUitime 0xffffffff,
          AccLat 0xffffffff, FlushTO 0x0000ffff)
...

Based upon haijun.liu <haijun.liu@atheros.com> series of patches
(sent Sun, 22 Aug 2010)
Signed-off-by: default avatarAndrei Emeltchenko <andrei.emeltchenko@intel.com>
Signed-off-by: default avatarGustavo F. Padovan <padovan@profusion.mobi>
parent 8f7975b1
...@@ -1870,6 +1870,37 @@ static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val) ...@@ -1870,6 +1870,37 @@ static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
*ptr += L2CAP_CONF_OPT_SIZE + len; *ptr += L2CAP_CONF_OPT_SIZE + len;
} }
static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan)
{
struct l2cap_conf_efs efs;
switch(chan->mode) {
case L2CAP_MODE_ERTM:
efs.id = chan->local_id;
efs.stype = chan->local_stype;
efs.msdu = cpu_to_le16(chan->local_msdu);
efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
efs.acc_lat = cpu_to_le32(L2CAP_DEFAULT_ACC_LAT);
efs.flush_to = cpu_to_le32(L2CAP_DEFAULT_FLUSH_TO);
break;
case L2CAP_MODE_STREAMING:
efs.id = 1;
efs.stype = L2CAP_SERV_BESTEFFORT;
efs.msdu = cpu_to_le16(chan->local_msdu);
efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
efs.acc_lat = 0;
efs.flush_to = 0;
break;
default:
return;
}
l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs),
(unsigned long) &efs);
}
static void l2cap_ack_timeout(unsigned long arg) static void l2cap_ack_timeout(unsigned long arg)
{ {
struct l2cap_chan *chan = (void *) arg; struct l2cap_chan *chan = (void *) arg;
...@@ -1921,6 +1952,11 @@ static inline bool __l2cap_ews_supported(struct l2cap_chan *chan) ...@@ -1921,6 +1952,11 @@ static inline bool __l2cap_ews_supported(struct l2cap_chan *chan)
return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_WINDOW; return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_WINDOW;
} }
static inline bool __l2cap_efs_supported(struct l2cap_chan *chan)
{
return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_FLOW;
}
static inline void l2cap_txwin_setup(struct l2cap_chan *chan) static inline void l2cap_txwin_setup(struct l2cap_chan *chan)
{ {
if (chan->tx_win > L2CAP_DEFAULT_TX_WINDOW && if (chan->tx_win > L2CAP_DEFAULT_TX_WINDOW &&
...@@ -1949,6 +1985,9 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data) ...@@ -1949,6 +1985,9 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state)) if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state))
break; break;
if (__l2cap_efs_supported(chan))
set_bit(FLAG_EFS_ENABLE, &chan->flags);
/* fall through */ /* fall through */
default: default:
chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask); chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask);
...@@ -1993,6 +2032,9 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data) ...@@ -1993,6 +2032,9 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
(unsigned long) &rfc); (unsigned long) &rfc);
if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
l2cap_add_opt_efs(&ptr, chan);
if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS)) if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS))
break; break;
...@@ -2020,6 +2062,9 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data) ...@@ -2020,6 +2062,9 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
(unsigned long) &rfc); (unsigned long) &rfc);
if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
l2cap_add_opt_efs(&ptr, chan);
if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS)) if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS))
break; break;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment