rmnet_ll_qmap.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471
  1. /*
  2. * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License version 2 and
  6. * only version 2 as published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. */
  13. #include <linux/netlink.h>
  14. #include <uapi/linux/rtnetlink.h>
  15. #include <linux/net.h>
  16. #include <net/sock.h>
  17. #include "dfc.h"
  18. #include "rmnet_qmi.h"
  19. #include "rmnet_qmap.h"
  20. #include "qmi_rmnet_i.h"
  21. #define QMAP_LL_VER 1
  22. #define QMAP_LL_MAX_BEARER 15
  23. #define QMAP_SWITCH_TO_LL 1
  24. #define QMAP_SWITCH_TO_DEFAULT 2
  25. #define QMAP_SWITCH_QUERY 3
  26. /* Switch status from modem */
  27. #define SWITCH_STATUS_ERROR 0
  28. #define SWITCH_STATUS_SUCCESS 1
  29. #define SWITCH_STATUS_DEFAULT 2
  30. #define SWITCH_STATUS_LL 3
  31. #define SWITCH_STATUS_FAIL_TEMP 4
  32. #define SWITCH_STATUS_FAIL_PERM 5
  33. /* Internal switch status */
  34. #define SWITCH_STATUS_NONE 0xFF
  35. #define SWITCH_STATUS_TIMEOUT 0xFE
  36. #define SWITCH_STATUS_NO_EFFECT 0xFD
  37. #define LL_MASK_NL_ACK 1
  38. #define LL_MASK_AUTO_RETRY 2
  39. #define LL_TIMEOUT (5 * HZ)
  40. #define LL_RETRY_TIME (10 * HZ)
  41. #define LL_MAX_RETRY (3)
  42. struct qmap_ll_bearer {
  43. u8 bearer_id;
  44. u8 status;
  45. u8 reserved[2];
  46. } __aligned(1);
  47. struct qmap_ll_switch {
  48. struct qmap_cmd_hdr hdr;
  49. u8 cmd_ver;
  50. u8 reserved;
  51. u8 request_type;
  52. u8 num_bearers;
  53. struct qmap_ll_bearer bearer[0];
  54. } __aligned(1);
  55. struct qmap_ll_switch_resp {
  56. struct qmap_cmd_hdr hdr;
  57. u8 cmd_ver;
  58. u8 reserved[2];
  59. u8 num_bearers;
  60. struct qmap_ll_bearer bearer[0];
  61. } __aligned(1);
  62. struct qmap_ll_switch_status {
  63. struct qmap_cmd_hdr hdr;
  64. u8 cmd_ver;
  65. u8 reserved[2];
  66. u8 num_bearers;
  67. struct qmap_ll_bearer bearer[0];
  68. } __aligned(1);
  69. static void ll_send_nl_ack(struct rmnet_bearer_map *bearer)
  70. {
  71. struct sk_buff *skb;
  72. struct nlmsghdr *nlh;
  73. struct nlmsgerr *errmsg;
  74. unsigned int flags = NLM_F_CAPPED;
  75. if (!(bearer->ch_switch.flags & LL_MASK_NL_ACK))
  76. return;
  77. skb = nlmsg_new(sizeof(*errmsg), GFP_ATOMIC);
  78. if (!skb)
  79. return;
  80. nlh = __nlmsg_put(skb, bearer->ch_switch.nl_pid,
  81. bearer->ch_switch.nl_seq, NLMSG_ERROR,
  82. sizeof(*errmsg), flags);
  83. errmsg = nlmsg_data(nlh);
  84. errmsg->error = 0;
  85. errmsg->msg.nlmsg_type = bearer->bearer_id;
  86. errmsg->msg.nlmsg_flags = bearer->ch_switch.status_code;
  87. errmsg->msg.nlmsg_seq = bearer->ch_switch.current_ch;
  88. nlmsg_end(skb, nlh);
  89. rtnl_unicast(skb, &init_net, bearer->ch_switch.nl_pid);
  90. }
  91. static void ll_qmap_maybe_set_ch(struct qos_info *qos,
  92. struct rmnet_bearer_map *bearer, u8 status)
  93. {
  94. u8 ch;
  95. if (status == SWITCH_STATUS_DEFAULT)
  96. ch = RMNET_CH_DEFAULT;
  97. else if (status == SWITCH_STATUS_LL)
  98. ch = RMNET_CH_LL;
  99. else
  100. return;
  101. bearer->ch_switch.current_ch = ch;
  102. if (bearer->mq_idx < MAX_MQ_NUM)
  103. qos->mq[bearer->mq_idx].is_ll_ch = ch;
  104. }
  105. static void ll_switch_complete(struct rmnet_bearer_map *bearer, u8 status)
  106. {
  107. bearer->ch_switch.status_code = status;
  108. if (status == SWITCH_STATUS_FAIL_TEMP &&
  109. bearer->ch_switch.retry_left) {
  110. /* Temp failure retry */
  111. bearer->ch_switch.state = CH_SWITCH_FAILED_RETRY;
  112. mod_timer(&bearer->ch_switch.guard_timer,
  113. jiffies + LL_RETRY_TIME);
  114. bearer->ch_switch.retry_left--;
  115. } else {
  116. /* Success or permanent failure */
  117. bearer->ch_switch.timer_quit = true;
  118. del_timer(&bearer->ch_switch.guard_timer);
  119. bearer->ch_switch.state = CH_SWITCH_NONE;
  120. bearer->ch_switch.retry_left = 0;
  121. ll_send_nl_ack(bearer);
  122. bearer->ch_switch.flags = 0;
  123. }
  124. }
  125. static int ll_qmap_handle_switch_resp(struct sk_buff *skb)
  126. {
  127. struct qmap_ll_switch_resp *cmd;
  128. struct rmnet_bearer_map *bearer;
  129. struct qos_info *qos;
  130. struct net_device *dev;
  131. int i;
  132. if (skb->len < sizeof(struct qmap_ll_switch_resp))
  133. return QMAP_CMD_DONE;
  134. cmd = (struct qmap_ll_switch_resp *)skb->data;
  135. if (!cmd->num_bearers)
  136. return QMAP_CMD_DONE;
  137. if (skb->len < sizeof(*cmd) +
  138. cmd->num_bearers * sizeof(struct qmap_ll_bearer))
  139. return QMAP_CMD_DONE;
  140. dev = rmnet_qmap_get_dev(cmd->hdr.mux_id);
  141. if (!dev)
  142. return QMAP_CMD_DONE;
  143. qos = rmnet_get_qos_pt(dev);
  144. if (!qos)
  145. return QMAP_CMD_DONE;
  146. trace_dfc_ll_switch("ACK", 0, cmd->num_bearers, cmd->bearer);
  147. spin_lock_bh(&qos->qos_lock);
  148. for (i = 0; i < cmd->num_bearers; i++) {
  149. bearer = qmi_rmnet_get_bearer_map(qos,
  150. cmd->bearer[i].bearer_id);
  151. if (!bearer)
  152. continue;
  153. ll_qmap_maybe_set_ch(qos, bearer, cmd->bearer[i].status);
  154. if (bearer->ch_switch.state == CH_SWITCH_STARTED &&
  155. bearer->ch_switch.switch_txid == cmd->hdr.tx_id) {
  156. /* This is an ACK to the switch request */
  157. if (cmd->bearer[i].status == SWITCH_STATUS_SUCCESS)
  158. bearer->ch_switch.state = CH_SWITCH_ACKED;
  159. else
  160. ll_switch_complete(bearer,
  161. cmd->bearer[i].status);
  162. }
  163. }
  164. spin_unlock_bh(&qos->qos_lock);
  165. return QMAP_CMD_DONE;
  166. }
  167. static int ll_qmap_handle_switch_status(struct sk_buff *skb)
  168. {
  169. struct qmap_ll_switch_status *cmd;
  170. struct rmnet_bearer_map *bearer;
  171. struct qos_info *qos;
  172. struct net_device *dev;
  173. int i;
  174. if (skb->len < sizeof(struct qmap_ll_switch_status))
  175. return QMAP_CMD_INVALID;
  176. cmd = (struct qmap_ll_switch_status *)skb->data;
  177. if (!cmd->num_bearers)
  178. return QMAP_CMD_ACK;
  179. if (skb->len < sizeof(*cmd) +
  180. cmd->num_bearers * sizeof(struct qmap_ll_bearer))
  181. return QMAP_CMD_INVALID;
  182. dev = rmnet_qmap_get_dev(cmd->hdr.mux_id);
  183. if (!dev)
  184. return QMAP_CMD_ACK;
  185. qos = rmnet_get_qos_pt(dev);
  186. if (!qos)
  187. return QMAP_CMD_ACK;
  188. trace_dfc_ll_switch("STS", 0, cmd->num_bearers, cmd->bearer);
  189. spin_lock_bh(&qos->qos_lock);
  190. for (i = 0; i < cmd->num_bearers; i++) {
  191. bearer = qmi_rmnet_get_bearer_map(qos,
  192. cmd->bearer[i].bearer_id);
  193. if (!bearer)
  194. continue;
  195. ll_qmap_maybe_set_ch(qos, bearer, cmd->bearer[i].status);
  196. if (bearer->ch_switch.state == CH_SWITCH_ACKED)
  197. ll_switch_complete(bearer, cmd->bearer[i].status);
  198. }
  199. spin_unlock_bh(&qos->qos_lock);
  200. return QMAP_CMD_ACK;
  201. }
  202. int ll_qmap_cmd_handler(struct sk_buff *skb)
  203. {
  204. struct qmap_cmd_hdr *cmd;
  205. int rc = QMAP_CMD_DONE;
  206. cmd = (struct qmap_cmd_hdr *)skb->data;
  207. if (cmd->cmd_name == QMAP_LL_SWITCH) {
  208. if (cmd->cmd_type != QMAP_CMD_ACK)
  209. return rc;
  210. } else if (cmd->cmd_type != QMAP_CMD_REQUEST) {
  211. return rc;
  212. }
  213. switch (cmd->cmd_name) {
  214. case QMAP_LL_SWITCH:
  215. rc = ll_qmap_handle_switch_resp(skb);
  216. break;
  217. case QMAP_LL_SWITCH_STATUS:
  218. rc = ll_qmap_handle_switch_status(skb);
  219. break;
  220. default:
  221. if (cmd->cmd_type == QMAP_CMD_REQUEST)
  222. rc = QMAP_CMD_UNSUPPORTED;
  223. }
  224. return rc;
  225. }
  226. static int ll_qmap_send_switch(u8 mux_id, u8 channel, u8 num_bearers,
  227. u8 *bearer_list, __be32 *txid)
  228. {
  229. struct sk_buff *skb;
  230. struct qmap_ll_switch *ll_switch;
  231. unsigned int len;
  232. int i;
  233. if (!num_bearers || num_bearers > QMAP_LL_MAX_BEARER || !bearer_list)
  234. return -EINVAL;
  235. len = sizeof(struct qmap_ll_switch) +
  236. num_bearers * sizeof(struct qmap_ll_bearer);
  237. skb = alloc_skb(len, GFP_ATOMIC);
  238. if (!skb)
  239. return -ENOMEM;
  240. skb->protocol = htons(ETH_P_MAP);
  241. ll_switch = skb_put(skb, len);
  242. memset(ll_switch, 0, len);
  243. ll_switch->hdr.cd_bit = 1;
  244. ll_switch->hdr.mux_id = mux_id;
  245. ll_switch->hdr.pkt_len = htons(len - QMAP_HDR_LEN);
  246. ll_switch->hdr.cmd_name = QMAP_LL_SWITCH;
  247. ll_switch->hdr.cmd_type = QMAP_CMD_REQUEST;
  248. ll_switch->hdr.tx_id = htonl(rmnet_qmap_next_txid());
  249. ll_switch->cmd_ver = QMAP_LL_VER;
  250. if (channel == RMNET_CH_CTL)
  251. ll_switch->request_type = QMAP_SWITCH_QUERY;
  252. else if (channel == RMNET_CH_LL)
  253. ll_switch->request_type = QMAP_SWITCH_TO_LL;
  254. else
  255. ll_switch->request_type = QMAP_SWITCH_TO_DEFAULT;
  256. ll_switch->num_bearers = num_bearers;
  257. for (i = 0; i < num_bearers; i++)
  258. ll_switch->bearer[i].bearer_id = bearer_list[i];
  259. if (txid)
  260. *txid = ll_switch->hdr.tx_id;
  261. trace_dfc_ll_switch("REQ", ll_switch->request_type,
  262. ll_switch->num_bearers, ll_switch->bearer);
  263. return rmnet_qmap_send(skb, RMNET_CH_CTL, false);
  264. }
  265. /*
  266. * Start channel switch. The switch request is sent only if all bearers
  267. * are eligible to switch. Return 0 if switch request is sent.
  268. */
  269. int rmnet_ll_switch(struct net_device *dev, struct tcmsg *tcm, int attrlen)
  270. {
  271. u8 switch_to_ch;
  272. u8 num_bearers;
  273. u8 *bearer_list;
  274. u32 flags;
  275. struct qos_info *qos;
  276. struct rmnet_bearer_map *bearer;
  277. __be32 txid;
  278. int i;
  279. int j;
  280. int rc = -EINVAL;
  281. if (!dev || !tcm)
  282. return -EINVAL;
  283. /*
  284. * tcm__pad1: switch type (ch #, 0xFF query)
  285. * tcm__pad2: num bearers
  286. * tcm_info: flags
  287. * tcm_ifindex: netlink fd
  288. * tcm_handle: pid
  289. * tcm_parent: seq
  290. */
  291. switch_to_ch = tcm->tcm__pad1;
  292. num_bearers = tcm->tcm__pad2;
  293. flags = tcm->tcm_info;
  294. if (switch_to_ch != RMNET_CH_CTL && switch_to_ch >= RMNET_CH_MAX)
  295. return -EOPNOTSUPP;
  296. if (!num_bearers || num_bearers > QMAP_LL_MAX_BEARER)
  297. return -EINVAL;
  298. if (attrlen - sizeof(*tcm) < num_bearers)
  299. return -EINVAL;
  300. bearer_list = (u8 *)tcm + sizeof(*tcm);
  301. for (i = 0; i < num_bearers; i++)
  302. for (j = 0; j < num_bearers; j++)
  303. if (j != i && bearer_list[i] == bearer_list[j])
  304. return -EINVAL;
  305. qos = rmnet_get_qos_pt(dev);
  306. if (!qos)
  307. return -EINVAL;
  308. spin_lock_bh(&qos->qos_lock);
  309. /* Validate the bearer list */
  310. for (i = 0; i < num_bearers; i++) {
  311. bearer = qmi_rmnet_get_bearer_map(qos, bearer_list[i]);
  312. if (!bearer) {
  313. rc = -EFAULT;
  314. goto out;
  315. }
  316. if (bearer->ch_switch.state != CH_SWITCH_NONE) {
  317. rc = -EBUSY;
  318. goto out;
  319. }
  320. }
  321. /* Send QMAP switch command */
  322. rc = ll_qmap_send_switch(qos->mux_id, switch_to_ch,
  323. num_bearers, bearer_list, &txid);
  324. if (rc)
  325. goto out;
  326. /* Update state */
  327. for (i = 0; i < num_bearers; i++) {
  328. bearer = qmi_rmnet_get_bearer_map(qos, bearer_list[i]);
  329. if (!bearer)
  330. continue;
  331. bearer->ch_switch.switch_to_ch = switch_to_ch;
  332. bearer->ch_switch.switch_txid = txid;
  333. bearer->ch_switch.state = CH_SWITCH_STARTED;
  334. bearer->ch_switch.status_code = SWITCH_STATUS_NONE;
  335. bearer->ch_switch.retry_left =
  336. (flags & LL_MASK_AUTO_RETRY) ? LL_MAX_RETRY : 0;
  337. bearer->ch_switch.flags = flags;
  338. bearer->ch_switch.timer_quit = false;
  339. mod_timer(&bearer->ch_switch.guard_timer,
  340. jiffies + LL_TIMEOUT);
  341. bearer->ch_switch.nl_pid = tcm->tcm_handle;
  342. bearer->ch_switch.nl_seq = tcm->tcm_parent;
  343. }
  344. out:
  345. spin_unlock_bh(&qos->qos_lock);
  346. return rc;
  347. }
  348. void rmnet_ll_guard_fn(struct timer_list *t)
  349. {
  350. struct rmnet_ch_switch *ch_switch;
  351. struct rmnet_bearer_map *bearer;
  352. int switch_status = SWITCH_STATUS_TIMEOUT;
  353. __be32 txid;
  354. int rc;
  355. ch_switch = container_of(t, struct rmnet_ch_switch, guard_timer);
  356. bearer = container_of(ch_switch, struct rmnet_bearer_map, ch_switch);
  357. spin_lock_bh(&bearer->qos->qos_lock);
  358. if (bearer->ch_switch.timer_quit ||
  359. bearer->ch_switch.state == CH_SWITCH_NONE)
  360. goto out;
  361. if (bearer->ch_switch.state == CH_SWITCH_FAILED_RETRY) {
  362. if (bearer->ch_switch.current_ch ==
  363. bearer->ch_switch.switch_to_ch) {
  364. switch_status = SWITCH_STATUS_NO_EFFECT;
  365. goto send_err;
  366. }
  367. rc = ll_qmap_send_switch(bearer->qos->mux_id,
  368. bearer->ch_switch.switch_to_ch,
  369. 1,
  370. &bearer->bearer_id,
  371. &txid);
  372. if (!rc) {
  373. bearer->ch_switch.switch_txid = txid;
  374. bearer->ch_switch.state = CH_SWITCH_STARTED;
  375. bearer->ch_switch.status_code = SWITCH_STATUS_NONE;
  376. goto out;
  377. }
  378. }
  379. send_err:
  380. bearer->ch_switch.state = CH_SWITCH_NONE;
  381. bearer->ch_switch.status_code = switch_status;
  382. bearer->ch_switch.retry_left = 0;
  383. ll_send_nl_ack(bearer);
  384. bearer->ch_switch.flags = 0;
  385. out:
  386. spin_unlock_bh(&bearer->qos->qos_lock);
  387. }