aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/l2cap_core.c
diff options
context:
space:
mode:
authorAndrei Emeltchenko <andrei.emeltchenko@intel.com>2011-10-13 09:18:55 -0400
committerGustavo F. Padovan <padovan@profusion.mobi>2011-10-13 16:09:44 -0400
commitf89cef09cee60a9715150a6e335dce4e64df7400 (patch)
treec087c72f926c38a2282615e51fe3d3f8d04a591e /net/bluetooth/l2cap_core.c
parent8f7975b153faab4b78369458a892dd705e7c395b (diff)
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: Andrei Emeltchenko <andrei.emeltchenko@intel.com> Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Diffstat (limited to 'net/bluetooth/l2cap_core.c')
-rw-r--r--net/bluetooth/l2cap_core.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 410c9cda057c..22133464d65b 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -1870,6 +1870,37 @@ static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
1870 *ptr += L2CAP_CONF_OPT_SIZE + len; 1870 *ptr += L2CAP_CONF_OPT_SIZE + len;
1871} 1871}
1872 1872
1873static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan)
1874{
1875 struct l2cap_conf_efs efs;
1876
1877 switch(chan->mode) {
1878 case L2CAP_MODE_ERTM:
1879 efs.id = chan->local_id;
1880 efs.stype = chan->local_stype;
1881 efs.msdu = cpu_to_le16(chan->local_msdu);
1882 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
1883 efs.acc_lat = cpu_to_le32(L2CAP_DEFAULT_ACC_LAT);
1884 efs.flush_to = cpu_to_le32(L2CAP_DEFAULT_FLUSH_TO);
1885 break;
1886
1887 case L2CAP_MODE_STREAMING:
1888 efs.id = 1;
1889 efs.stype = L2CAP_SERV_BESTEFFORT;
1890 efs.msdu = cpu_to_le16(chan->local_msdu);
1891 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
1892 efs.acc_lat = 0;
1893 efs.flush_to = 0;
1894 break;
1895
1896 default:
1897 return;
1898 }
1899
1900 l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs),
1901 (unsigned long) &efs);
1902}
1903
1873static void l2cap_ack_timeout(unsigned long arg) 1904static void l2cap_ack_timeout(unsigned long arg)
1874{ 1905{
1875 struct l2cap_chan *chan = (void *) arg; 1906 struct l2cap_chan *chan = (void *) arg;
@@ -1921,6 +1952,11 @@ static inline bool __l2cap_ews_supported(struct l2cap_chan *chan)
1921 return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_WINDOW; 1952 return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_WINDOW;
1922} 1953}
1923 1954
1955static inline bool __l2cap_efs_supported(struct l2cap_chan *chan)
1956{
1957 return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_FLOW;
1958}
1959
1924static inline void l2cap_txwin_setup(struct l2cap_chan *chan) 1960static inline void l2cap_txwin_setup(struct l2cap_chan *chan)
1925{ 1961{
1926 if (chan->tx_win > L2CAP_DEFAULT_TX_WINDOW && 1962 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 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state)) 1985 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state))
1950 break; 1986 break;
1951 1987
1988 if (__l2cap_efs_supported(chan))
1989 set_bit(FLAG_EFS_ENABLE, &chan->flags);
1990
1952 /* fall through */ 1991 /* fall through */
1953 default: 1992 default:
1954 chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask); 1993 chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask);
@@ -1993,6 +2032,9 @@ done:
1993 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), 2032 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
1994 (unsigned long) &rfc); 2033 (unsigned long) &rfc);
1995 2034
2035 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
2036 l2cap_add_opt_efs(&ptr, chan);
2037
1996 if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS)) 2038 if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS))
1997 break; 2039 break;
1998 2040
@@ -2020,6 +2062,9 @@ done:
2020 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), 2062 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
2021 (unsigned long) &rfc); 2063 (unsigned long) &rfc);
2022 2064
2065 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
2066 l2cap_add_opt_efs(&ptr, chan);
2067
2023 if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS)) 2068 if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS))
2024 break; 2069 break;
2025 2070