1. diff --git a/.config b/.config
  2. index c7188ac..569621f 100644
  3. --- a/.config
  4. +++ b/.config
  5. @@ -1601,6 +1601,13 @@ CONFIG_BT_MRVL=m
  6. CONFIG_BT_MRVL_SDIO=m
  7. CONFIG_BT_ATH3K=m
  8. CONFIG_BT_WILINK=m
  9. +CONFIG_DECT=m
  10. +CONFIG_DECT_DEBUG=y
  11. +CONFIG_DECT_CSF=m
  12. +CONFIG_DECT_RAW=m
  13. +CONFIG_DECT_CCF=m
  14. +CONFIG_DECT_LU1_SAP=m
  15. +# CONFIG_DECT_CCP is not set
  16. CONFIG_AF_RXRPC=m
  17. # CONFIG_AF_RXRPC_IPV6 is not set
  18. # CONFIG_AF_RXRPC_INJECT_LOSS is not set
  19. @@ -3179,6 +3186,15 @@ CONFIG_NVM=y
  20. # CONFIG_NVM_DEBUG is not set
  21. CONFIG_NVM_GENNVM=m
  22. CONFIG_NVM_RRPC=m
  23. +CONFIG_DECTDEVICES=y
  24. +CONFIG_DECT_VTRX=m
  25. +CONFIG_DECT_COA_PCI=m
  26. +CONFIG_DECT_COA_CS=m
  27. +CONFIG_DECT_COA=m
  28. +CONFIG_DECT_COA_U2785=y
  29. +CONFIG_DECT_COA_LMX3161=y
  30. +CONFIG_DECT_COA_FIRMWARE=y
  31. +CONFIG_DECT_COA_P64=y
  32. #
  33. # Input device support
  34. diff --git a/MAINTAINERS b/MAINTAINERS
  35. index 52cc077..3f5e377 100644
  36. --- a/MAINTAINERS
  37. +++ b/MAINTAINERS
  38. @@ -3681,6 +3681,14 @@ F: arch/mips/dec/
  39. F: arch/mips/include/asm/dec/
  40. F: arch/mips/include/asm/mach-dec/
  41. +DECT NETWORK PROTOCOL
  42. +M: Patrick McHardy <kaber@trash.net>
  43. +S: Maintained
  44. +F: net/dect
  45. +F: drivers/dect
  46. +F: include/net/dect
  47. +F: include/linux/dect*.h
  48. +
  49. DEFXX FDDI NETWORK DRIVER
  50. M: "Maciej W. Rozycki" <macro@linux-mips.org>
  51. S: Maintained
  52. diff --git a/drivers/Kconfig b/drivers/Kconfig
  53. index e1e2066..6eb8f71 100644
  54. --- a/drivers/Kconfig
  55. +++ b/drivers/Kconfig
  56. @@ -46,6 +46,8 @@ source "drivers/isdn/Kconfig"
  57. source "drivers/lightnvm/Kconfig"
  58. +source "drivers/dect/Kconfig"
  59. +
  60. # input before char - char/joystick depends on it. As does USB.
  61. source "drivers/input/Kconfig"
  62. diff --git a/drivers/Makefile b/drivers/Makefile
  63. index 194d20b..e11eca1 100644
  64. --- a/drivers/Makefile
  65. +++ b/drivers/Makefile
  66. @@ -117,6 +117,7 @@ obj-$(CONFIG_MD) += md/
  67. obj-$(CONFIG_BT) += bluetooth/
  68. obj-$(CONFIG_ACCESSIBILITY) += accessibility/
  69. obj-$(CONFIG_ISDN) += isdn/
  70. +obj-$(CONFIG_DECT) += dect/
  71. obj-$(CONFIG_EDAC) += edac/
  72. obj-$(CONFIG_EISA) += eisa/
  73. obj-y += lguest/
  74. diff --git a/drivers/dect/Kconfig b/drivers/dect/Kconfig
  75. new file mode 100644
  76. index 0000000..baba4c1
  77. --- /dev/null
  78. +++ b/drivers/dect/Kconfig
  79. @@ -0,0 +1,11 @@
  80. +menuconfig DECTDEVICES
  81. + bool "DECT device support"
  82. + help
  83. + Say Y here to show DECT device driver options.
  84. +
  85. +if DECTDEVICES
  86. +
  87. +source "drivers/dect/vtrx/Kconfig"
  88. +source "drivers/dect/coa/Kconfig"
  89. +
  90. +endif
  91. diff --git a/drivers/dect/Makefile b/drivers/dect/Makefile
  92. new file mode 100644
  93. index 0000000..c58af58
  94. --- /dev/null
  95. +++ b/drivers/dect/Makefile
  96. @@ -0,0 +1,2 @@
  97. +obj-$(CONFIG_DECT_VTRX) += vtrx/
  98. +obj-$(CONFIG_DECT_COA) += coa/
  99. diff --git a/drivers/dect/coa/.gitignore b/drivers/dect/coa/.gitignore
  100. new file mode 100644
  101. index 0000000..7890f99
  102. --- /dev/null
  103. +++ b/drivers/dect/coa/.gitignore
  104. @@ -0,0 +1,4 @@
  105. +bin2c
  106. +*.p
  107. +*.h.tmp
  108. +*.bin
  109. diff --git a/drivers/dect/coa/Kconfig b/drivers/dect/coa/Kconfig
  110. new file mode 100644
  111. index 0000000..207193f
  112. --- /dev/null
  113. +++ b/drivers/dect/coa/Kconfig
  114. @@ -0,0 +1,45 @@
  115. +config DECT_COA_PCI
  116. + tristate "Com-on-Air PCI DECT support"
  117. + depends on DECT
  118. + depends on PCI
  119. + select DECT_COA
  120. + select DECT_COA_U2785
  121. + help
  122. + This option enables support for the Com-on-Air DECT PCI devices.
  123. +
  124. +config DECT_COA_CS
  125. + tristate "Com-on-Air PCMCIA DECT support"
  126. + depends on DECT
  127. + depends on PCMCIA
  128. + select DECT_COA
  129. + select DECT_COA_U2785
  130. + select DECT_COA_LMX3161
  131. + select CRC32
  132. + help
  133. + This option enables support for the Com-on-Air DECT PCMCIA devices.
  134. +
  135. +config DECT_COA
  136. + tristate
  137. +
  138. +config DECT_COA_U2785
  139. + bool
  140. +
  141. +config DECT_COA_LMX3161
  142. + bool
  143. +
  144. +config DECT_COA_FIRMWARE
  145. + bool "Build Com-on-Air firmware (requires ASL macro assembler)"
  146. + depends on DECT_COA
  147. + help
  148. + This option enables rebuild of the firmware for the Com-on-Air
  149. + devices during the kernel build process. The ASL macro compiler
  150. + is required for this.
  151. +
  152. + If unsure, say N.
  153. +
  154. +config DECT_COA_P64
  155. + depends on DECT_COA_PCI && !DECT_COA_CS && DECT_COA_FIRMWARE
  156. + bool "Enable P640 (wideband) support"
  157. + help
  158. + This option enables support for P640j packets, which are used for
  159. + wideband audio. This does not work with the PCMCIA devices.
  160. diff --git a/drivers/dect/coa/Makefile b/drivers/dect/coa/Makefile
  161. new file mode 100644
  162. index 0000000..30033b3
  163. --- /dev/null
  164. +++ b/drivers/dect/coa/Makefile
  165. @@ -0,0 +1,44 @@
  166. +com_on_air-objs := sc1442x_firmware.o sc1442x.o
  167. +com_on_air-$(CONFIG_DECT_COA_U2785) += radio_u2785.o
  168. +com_on_air-$(CONFIG_DECT_COA_LMX3161) += radio_lmx3161.o
  169. +
  170. +obj-$(CONFIG_DECT_COA) += com_on_air.o
  171. +obj-$(CONFIG_DECT_COA_PCI) += com_on_air_pci.o
  172. +obj-$(CONFIG_DECT_COA_CS) += com_on_air_cs.o
  173. +
  174. +$(obj)/sc1442x.o: $(obj)/sc1442x_firmware.c
  175. +$(obj)/sc1442x_firmware.c: NAME=sc1442x
  176. +clean-files += sc1442x_firmware.p
  177. +clean-files += sc1442x_firmware.bin
  178. +clean-files += sc1442x_firmware.h.tmp
  179. +
  180. +hostprogs-$(CONFIG_DECT_COA_FIRMWARE) += bin2c
  181. +
  182. +ifeq ($(CONFIG_DECT_COA_FIRMWARE),y)
  183. +ifeq ($(CONFIG_DECT_COA_P64),y)
  184. +ASL_FLAGS = -D ENABLE_P64
  185. +endif
  186. +
  187. +ASL = asl
  188. +P2BIN = p2bin
  189. +BIN2C = $(obj)/bin2c
  190. +
  191. +quiet_cmd_asl = ASL $<
  192. + cmd_asl = $(ASL) -q -c $< -o $(<:.asm=.p) $(ASL_FLAGS) -shareout $(<:.asm=.h.tmp); \
  193. + $(P2BIN) $(<:.asm=.p) $(<:.asm=.bin) -r 0-509; \
  194. + $(BIN2C) $(<:.asm=.bin) $(NAME)_firmware > $@; \
  195. + ( \
  196. + echo "\#ifndef $$(echo $(NAME) | tr a-z A-Z)_FIRMWARE"; \
  197. + echo "\#define $$(echo $(NAME) | tr a-z A-Z)_FIRMWARE"; \
  198. + echo;\
  199. + echo "extern const unsigned char $(NAME)_firmware[510];"; \
  200. + echo;\
  201. + grep -a define $(<:.asm=.h.tmp); \
  202. + echo;\
  203. + echo "\#endif /* $$(echo $(NAME) | tr a-z A-Z)_FIRMWARE */"; \
  204. + ) > $(@:.c=.h)
  205. +
  206. +$(obj)/%_firmware.c: $(src)/%_firmware.asm $(BIN2C)
  207. + $(call if_changed,asl)
  208. +
  209. +endif
  210. diff --git a/drivers/dect/coa/bin2c.c b/drivers/dect/coa/bin2c.c
  211. new file mode 100644
  212. index 0000000..bab08fa
  213. --- /dev/null
  214. +++ b/drivers/dect/coa/bin2c.c
  215. @@ -0,0 +1,57 @@
  216. +#include <stdio.h>
  217. +#include <sys/types.h>
  218. +#include <sys/stat.h>
  219. +#include <fcntl.h>
  220. +#include <string.h>
  221. +#include <errno.h>
  222. +#include <stdint.h>
  223. +#include <stdlib.h>
  224. +#include <unistd.h>
  225. +
  226. +#define HEADER_FMT \
  227. + "/*\n" \
  228. + " * automatically generated file\n" \
  229. + " * DO NOT EDIT\n" \
  230. + " * edit firmware/filename.asm instead\n" \
  231. + " */\n" \
  232. + "\n" \
  233. + "#include \"%s.h\"\n" \
  234. + "\n" \
  235. + "const unsigned char %s[] = {\n"
  236. +
  237. +#define FOOTER "};\n"
  238. +
  239. +int main(int argc, char *argv[])
  240. +{
  241. + uint32_t wordcount = 0;
  242. + uint16_t w;
  243. + int f;
  244. +
  245. + if (argc < 3) {
  246. + printf("usage: bin2c bin-file varname > c-file\n");
  247. + exit(1);
  248. + }
  249. +
  250. + f = open(argv[1], O_RDONLY);
  251. + if (f < 0) {
  252. + printf("cant open(\"%s\"): %s\n", argv[1], strerror(errno));
  253. + exit(1);
  254. + }
  255. +
  256. + printf(HEADER_FMT, argv[2], argv[2]);
  257. +
  258. + while (2 == read(f, &w, 2)) {
  259. + if (!wordcount)
  260. + printf("\t");
  261. + else
  262. + if (!(wordcount % 4))
  263. + printf(",\n\t");
  264. + else
  265. + printf(", ");
  266. + printf("0x%.2x, 0x%.2x", (w & 0xff00) >> 8, w & 0xff);
  267. + wordcount++;
  268. + }
  269. + printf(FOOTER);
  270. + close(f);
  271. + return 0;
  272. +}
  273. diff --git a/drivers/dect/coa/com_on_air.h b/drivers/dect/coa/com_on_air.h
  274. new file mode 100644
  275. index 0000000..37c2b0a
  276. --- /dev/null
  277. +++ b/drivers/dect/coa/com_on_air.h
  278. @@ -0,0 +1,99 @@
  279. +/*
  280. + * com_on_air - basic driver for the Dosch and Amand "com on air" cards
  281. + *
  282. + * This program is free software; you can redistribute it and/or modify
  283. + * it under the terms of the GNU General Public License version 2 as
  284. + * published by the Free Software Foundation.
  285. + *
  286. + * authors:
  287. + * (C) 2008 Andreas Schuler <krater at badterrorist dot com>
  288. + * (C) 2008 Matthias Wenzel <dect at mazzoo dot de>
  289. + * (C) 2009 Patrick McHardy <[email protected]>
  290. + *
  291. + */
  292. +
  293. +#ifndef COM_ON_AIR_H
  294. +#define COM_ON_AIR_H
  295. +
  296. +#include <linux/types.h>
  297. +
  298. +struct coa_freq_map_entry {
  299. + struct {
  300. + u8 divisor;
  301. + u8 swcnt;
  302. + } rx, tx;
  303. +};
  304. +
  305. +struct coa_freq_map {
  306. + struct coa_freq_map_entry carrier[DECT_CARRIER_NUM];
  307. +};
  308. +
  309. +struct coa_device;
  310. +struct coa_radio_ops {
  311. + void (*rx_init)(const struct coa_device *dev, u16 offset);
  312. + void (*tx_init)(const struct coa_device *dev, u16 offset);
  313. + void (*set_carrier)(const struct coa_device *dev, u16 offset,
  314. + enum dect_slot_states mode, u8 carrier);
  315. + u64 (*map_band)(struct coa_device *dev,
  316. + const struct dect_band *band);
  317. + const char *type;
  318. +};
  319. +
  320. +extern const struct coa_radio_ops coa_u2785_radio_ops;
  321. +extern const struct coa_radio_ops coa_lmx3161_radio_ops;
  322. +
  323. +/**
  324. + * struct sc1442x_phase_state - per-slot phase offset state
  325. + *
  326. + * @framenum: frame number the information was last updated
  327. + * @tap: sc1442x internal clock cycle which sampled the data
  328. + * @phase: offset of number of symbol periods to nominal 11520 symbols per frame
  329. + *
  330. + * This structure is used to store the measured values for one particular
  331. + * frame. The actual phase offset is calculated from the differences of two
  332. + * consequitive frames.
  333. + */
  334. +struct sc1442x_phase_state {
  335. + u8 framenum;
  336. + u8 tap;
  337. + s8 phase;
  338. +};
  339. +
  340. +enum coa_device_types {
  341. + COA_TYPE_PCI,
  342. + COA_TYPE_PCMCIA,
  343. +};
  344. +
  345. +struct coa_device {
  346. + const struct device *dev;
  347. + unsigned int irq;
  348. +
  349. + enum coa_device_types type;
  350. +
  351. + const struct coa_radio_ops *radio_ops;
  352. + struct coa_freq_map freq_map;
  353. + struct sc1442x_phase_state phase_state[DECT_FRAME_SIZE / 2];
  354. +
  355. + spinlock_t lock;
  356. + uint config_base;
  357. + u8 __iomem *sc1442x_base;
  358. + u16 cfg_reg;
  359. + u16 irq_reg;
  360. + u16 code_base;
  361. + u16 data_base;
  362. + u16 data_mask;
  363. +
  364. + u8 ctrl;
  365. + u8 led;
  366. +};
  367. +
  368. +extern irqreturn_t sc1442x_interrupt(int irq, void *dev_id);
  369. +extern const struct dect_transceiver_ops sc1442x_transceiver_ops;
  370. +
  371. +extern int sc1442x_init_device(struct coa_device *dev);
  372. +extern void sc1442x_shutdown_device(struct coa_device *dev);
  373. +
  374. +extern void sc1442x_rfdesc_write(const struct coa_device *dev, u16 offset,
  375. + const u8 *src, u16 length);
  376. +
  377. +#endif
  378. diff --git a/drivers/dect/coa/com_on_air_cs.c b/drivers/dect/coa/com_on_air_cs.c
  379. new file mode 100644
  380. index 0000000..e1f2231
  381. --- /dev/null
  382. +++ b/drivers/dect/coa/com_on_air_cs.c
  383. @@ -0,0 +1,271 @@
  384. +/*
  385. + * com_on_air_cs - basic driver for the Dosch and Amand "com on air" cards
  386. + *
  387. + * This program is free software; you can redistribute it and/or modify
  388. + * it under the terms of the GNU General Public License version 2 as
  389. + * published by the Free Software Foundation.
  390. + *
  391. + * authors:
  392. + * (C) 2008 Andreas Schuler <krater at badterrorist dot com>
  393. + * (C) 2008 Matthias Wenzel <dect at mazzoo dot de>
  394. + * (C) 2009 Patrick McHardy <[email protected]>
  395. + *
  396. + */
  397. +
  398. +#include <linux/kernel.h>
  399. +#include <linux/module.h>
  400. +#include <linux/interrupt.h>
  401. +#include <linux/init.h>
  402. +#include <linux/crc32.h>
  403. +#include <net/dect/transceiver.h>
  404. +
  405. +#include <pcmcia/cistpl.h>
  406. +#include <pcmcia/ciscode.h>
  407. +#include <pcmcia/ds.h>
  408. +#include <pcmcia/cisreg.h>
  409. +
  410. +#include "com_on_air.h"
  411. +
  412. +MODULE_AUTHOR("Matthias Wenzel comonair<a>mazzoo.de;"
  413. + "Andreas Schuler dect<a>badterrorist.com");
  414. +MODULE_DESCRIPTION("Dosch&Amand COM-ON-AIR PCMCIA driver");
  415. +MODULE_LICENSE("GPL");
  416. +
  417. +static int get_card_id(const struct pcmcia_device *link);
  418. +
  419. +static int com_on_air_probe(struct pcmcia_device *link)
  420. +{
  421. + struct dect_transceiver *trx;
  422. + struct coa_device *dev;
  423. + int err;
  424. +
  425. + trx = dect_transceiver_alloc(&sc1442x_transceiver_ops, sizeof(*dev));
  426. + if (!trx) {
  427. + err = -ENOMEM;
  428. + goto err1;
  429. + }
  430. +
  431. + link->priv = trx;
  432. + dev = dect_transceiver_priv(trx);
  433. + dev->type = COA_TYPE_PCMCIA;
  434. + dev->code_base = 0x0;
  435. + dev->data_base = 0x0;
  436. + dev->data_mask = 0x0ff;
  437. + dev->cfg_reg = 0x1ff;
  438. + dev->irq_reg = 0x0;
  439. + dev->dev = &link->dev;
  440. +
  441. + dev_info(dev->dev, "%s %s %s %s\n", link->prod_id[0], link->prod_id[1],
  442. + link->prod_id[2] ? : "", link->prod_id[3] ? : "");
  443. +
  444. + link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
  445. + link->resource[0]->end = 16;
  446. + link->resource[1]->flags |= 0;
  447. +
  448. + link->config_flags = CONF_ENABLE_IRQ;
  449. + link->config_index = 1;
  450. + link->config_regs = PRESENT_OPTION;
  451. + link->config_base = 0x1020;
  452. +
  453. + link->resource[2]->flags = WIN_DATA_WIDTH_16 | WIN_ENABLE;
  454. + link->resource[2]->start = 0;
  455. + link->resource[2]->end = 0x1000;
  456. +
  457. + err = pcmcia_request_window(link, link->resource[2], 500);
  458. + if (err < 0) {
  459. + dev_err(dev->dev, "failed to obtain PCMCIA window\n");
  460. + goto err2;
  461. + }
  462. +
  463. + dev->sc1442x_base = ioremap_nocache(link->resource[2]->start,
  464. + resource_size(link->resource[2]));
  465. + if (!dev->sc1442x_base) {
  466. + dev_err(dev->dev, "failed to remap PCMCIA resource\n");
  467. + err = -EIO;
  468. + goto err3;
  469. + }
  470. +
  471. + link->socket->functions = 0;
  472. +
  473. + err = pcmcia_request_irq(link, sc1442x_interrupt);
  474. + if (err < 0) {
  475. + dev_err(dev->dev, "failed to request IRQ%d\n", link->irq);
  476. + goto err4;
  477. + }
  478. +
  479. + err = pcmcia_enable_device(link);
  480. + if (err < 0) {
  481. + dev_err(dev->dev, "failed to enable PCMCIA device\n");
  482. + goto err5;
  483. + }
  484. +
  485. + dev_dbg(dev->dev, "%svalid client.\n", (link->config_flags) ? "":"in");
  486. + dev_dbg(dev->dev, "Type 0x%x\n", link->socket->state);
  487. + dev_dbg(dev->dev, "Function 0x%x\n", link->func);
  488. + dev_dbg(dev->dev, "config_flags %d\n", link->config_flags);
  489. + dev_dbg(dev->dev, "config_base 0x%x\n", link->config_base);
  490. + dev_dbg(dev->dev, "config_regs %d\n", link->config_regs);
  491. + dev_dbg(dev->dev, "IRQ 0x%x\n", link->irq);
  492. + dev_dbg(dev->dev, "BasePort1 0x%llx\n", link->resource[0]->start);
  493. + dev_dbg(dev->dev, "NumPorts1 0x%llx\n", link->resource[0]->end);
  494. + dev_dbg(dev->dev, "Attributes1 0x%lx\n", link->resource[0]->flags);
  495. + dev_dbg(dev->dev, "BasePort2 0x%llx\n", link->resource[1]->start);
  496. + dev_dbg(dev->dev, "NumPorts2 0x%llx\n", link->resource[1]->end);
  497. + dev_dbg(dev->dev, "Attributes2 0x%lx\n", link->resource[1]->flags);
  498. + dev_dbg(dev->dev, "IOAddrLines 0x%x\n", link->io_lines);
  499. + dev_dbg(dev->dev, "has%s function_config\n",
  500. + link->function_config ? "":" no");
  501. +
  502. + switch (get_card_id(link)) {
  503. + case 0:
  504. + case 3:
  505. + dev->radio_ops = &coa_u2785_radio_ops;
  506. + break;
  507. + case 1:
  508. + case 2:
  509. + dev->radio_ops = &coa_lmx3161_radio_ops;
  510. + break;
  511. + default:
  512. + dev_err(dev->dev, "unknown radio type\n");
  513. + err = -EINVAL;
  514. + goto err5;
  515. + }
  516. +
  517. + dev_info(dev->dev, "Radio type %s\n", dev->radio_ops->type);
  518. +
  519. + dev->irq = link->irq;
  520. + dev->config_base = link->config_base;
  521. + err = sc1442x_init_device(dev);
  522. + if (err < 0)
  523. + goto err5;
  524. +
  525. + err = dect_register_transceiver(trx);
  526. + if (err < 0)
  527. + goto err6;
  528. +
  529. + return 0;
  530. +
  531. +err6:
  532. + sc1442x_shutdown_device(dev);
  533. +err5:
  534. + pcmcia_disable_device(link);
  535. +err4:
  536. + iounmap(dev->sc1442x_base);
  537. +err3:
  538. + pcmcia_release_window(link, link->resource[2]);
  539. +err2:
  540. + dect_transceiver_free(trx);
  541. +err1:
  542. + return err;
  543. +}
  544. +
  545. +static void com_on_air_remove(struct pcmcia_device *link)
  546. +{
  547. + struct dect_transceiver *trx = link->priv;
  548. + struct coa_device *dev = dect_transceiver_priv(trx);
  549. + u8 __iomem *sc1442x_base = dev->sc1442x_base;
  550. +
  551. + sc1442x_shutdown_device(dev);
  552. + pcmcia_disable_device(link);
  553. + dect_unregister_transceiver(trx);
  554. + iounmap(sc1442x_base);
  555. +}
  556. +
  557. +static int com_on_air_suspend(struct pcmcia_device *link)
  558. +{
  559. + struct dect_transceiver *trx = link->priv;
  560. + struct coa_device *dev = dect_transceiver_priv(trx);
  561. +
  562. + sc1442x_shutdown_device(dev);
  563. + return 0;
  564. +}
  565. +
  566. +static int com_on_air_resume(struct pcmcia_device *link)
  567. +{
  568. + struct dect_transceiver *trx = link->priv;
  569. + struct coa_device *dev = dect_transceiver_priv(trx);
  570. +
  571. + return sc1442x_init_device(dev);
  572. +}
  573. +
  574. +static struct pcmcia_device_id com_on_air_ids[] = {
  575. + /*
  576. + * The crc32 hashes below are generated by the tool in
  577. + * Documentation/pcmcia/devicetable.txt
  578. + */
  579. + PCMCIA_DEVICE_PROD_ID12 ("DECTDataDevice", "PCMCIA F22",
  580. + 0x11fe69e9, 0x253670b2),
  581. + PCMCIA_DEVICE_PROD_ID12 ("DECTDataDevice", "PCMCIA",
  582. + 0x11fe69e9, 0x281f1c5d),
  583. + PCMCIA_DEVICE_PROD_ID1234("DOSCH-AMAND", "MMAP PCMCIA",
  584. + "MXM500", "V1.00",
  585. + 0x4bc552e7, 0x0df519bb,
  586. + 0x09e43c7c, 0x3488c81a),
  587. + PCMCIA_DEVICE_PROD_ID12 ("DECTVoIPDevice", "PCMCIA DA099",
  588. + 0xeabb0be4, 0xd7b915fe),
  589. +#if 0
  590. + There are more devices out there, I only own the above three.
  591. + an excerpt from win32 dna.inf:
  592. +
  593. +%String1%=pcmcia.install,PCMCIA\DOSCH-AMAND-MMAP_PCMCIA-C7D7
  594. +%String1%=pcmcia.install,PCMCIA\Dosch-Amand-DECT_MultiMedia-BD0D
  595. +%String1%=pcmcia.install,PCMCIA\DOSCH_&_AMAND-DECT_MULTIMEDIA-1A9F
  596. +%String1%=pcmcia.install,PCMCIA\DECTDataDevice-F13-6433
  597. +%String1%=pcmcia.install,PCMCIA\DECTDataDevice-PCMCIA-0EF8
  598. +%String4%=pci.install,PCI\VEN_11E3&DEV_0001&SUBSYS_000111E3&REV_00
  599. +%String4%=pci.install,PCI\VEN_11E3&DEV_0001&SUBSYS_00011786&REV_32
  600. +%String4%=pci.install,PCI\VEN_1786&DEV_0001&SUBSYS_000111E3&REV_00
  601. +%String5%=freekey2.install,PCMCIA\DECTDataDevice-PCMCIA-FEF2
  602. +%String6%=freekey2.install,PCMCIA\DECTDataDevice-PCMCIA_F22-4BD3
  603. +%String6%=freekey2.install,PCMCIA\DECTDataDevice-PCMCIA_F22-BBD9
  604. +
  605. +#endif
  606. + PCMCIA_DEVICE_NULL
  607. +};
  608. +
  609. +MODULE_DEVICE_TABLE(pcmcia, com_on_air_ids);
  610. +
  611. +/* returns an index into com_on_air_ids[] */
  612. +static int get_card_id(const struct pcmcia_device *link)
  613. +{
  614. + u32 hash[4] = {};
  615. + unsigned int i;
  616. +
  617. + for (i = 0; i < 4; i++) {
  618. + if (link->prod_id[i] == NULL)
  619. + continue;
  620. + hash[i] = crc32(0, link->prod_id[i], strlen(link->prod_id[i]));
  621. + }
  622. +
  623. + for (i = 0; i < ARRAY_SIZE(com_on_air_ids) - 1; i++) {
  624. + if ((hash[0] == com_on_air_ids[i].prod_id_hash[0]) &&
  625. + (hash[1] == com_on_air_ids[i].prod_id_hash[1]) &&
  626. + (hash[2] == com_on_air_ids[i].prod_id_hash[2]) &&
  627. + (hash[3] == com_on_air_ids[i].prod_id_hash[3]))
  628. + return i;
  629. + }
  630. + return -1;
  631. +}
  632. +
  633. +static struct pcmcia_driver coa_driver = {
  634. + .owner = THIS_MODULE,
  635. + .name = KBUILD_MODNAME,
  636. + .probe = com_on_air_probe,
  637. + .remove = com_on_air_remove,
  638. + .suspend = com_on_air_suspend,
  639. + .resume = com_on_air_resume,
  640. + .id_table = com_on_air_ids,
  641. +};
  642. +
  643. +static int __init init_com_on_air_cs(void)
  644. +{
  645. + return pcmcia_register_driver(&coa_driver);
  646. +}
  647. +
  648. +static void __exit exit_com_on_air_cs(void)
  649. +{
  650. + pcmcia_unregister_driver(&coa_driver);
  651. +}
  652. +
  653. +module_init(init_com_on_air_cs);
  654. +module_exit(exit_com_on_air_cs);
  655. diff --git a/drivers/dect/coa/com_on_air_pci.c b/drivers/dect/coa/com_on_air_pci.c
  656. new file mode 100644
  657. index 0000000..08c6e6f
  658. --- /dev/null
  659. +++ b/drivers/dect/coa/com_on_air_pci.c
  660. @@ -0,0 +1,165 @@
  661. +/*
  662. + * Copyright (c) 2009 Patrick McHardy <[email protected]>
  663. + *
  664. + * This program is free software; you can redistribute it and/or modify
  665. + * it under the terms of the GNU General Public License version 2 as
  666. + * published by the Free Software Foundation.
  667. + */
  668. +
  669. +#include <linux/kernel.h>
  670. +#include <linux/module.h>
  671. +#include <linux/init.h>
  672. +#include <linux/interrupt.h>
  673. +#include <linux/pci.h>
  674. +#include <net/dect/transceiver.h>
  675. +
  676. +#include "com_on_air.h"
  677. +
  678. +#define PCI_VENDOR_ID_QUICKLOGIC 0x11e3
  679. +#define PCI_DEVICE_ID_COA 0x0001
  680. +#define DEFINE_PCI_DEVICE_TABLE(_table) const struct pci_device_id _table[]
  681. +
  682. +static int coa_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
  683. +{
  684. + struct dect_transceiver *trx;
  685. + struct coa_device *dev;
  686. + void __iomem *base;
  687. + int err;
  688. +
  689. + err = pci_enable_device(pdev);
  690. + if (err < 0) {
  691. + dev_err(&pdev->dev, "failed to enable PCI device\n");
  692. + goto err1;
  693. + }
  694. + pci_set_master(pdev);
  695. +
  696. + err = pci_request_regions(pdev, KBUILD_MODNAME);
  697. + if (err < 0) {
  698. + dev_err(&pdev->dev, "failed to obtain PCI resources\n");
  699. + goto err2;
  700. + }
  701. +
  702. + base = ioremap_nocache(pci_resource_start(pdev, 0),
  703. + pci_resource_len(pdev, 0));
  704. + if (base == NULL) {
  705. + dev_err(&pdev->dev, "failed to remap PCI resource\n");
  706. + err = -EIO;
  707. + goto err3;
  708. + }
  709. +
  710. + trx = dect_transceiver_alloc(&sc1442x_transceiver_ops, sizeof(*dev));
  711. + if (trx == NULL) {
  712. + err = -ENOMEM;
  713. + goto err4;
  714. + }
  715. + pci_set_drvdata(pdev, trx);
  716. +
  717. + dev = dect_transceiver_priv(trx);
  718. + dev->type = COA_TYPE_PCI;
  719. + dev->dev = &pdev->dev;
  720. + dev->sc1442x_base = base;
  721. + dev->radio_ops = &coa_u2785_radio_ops;
  722. + dev->data_base = 0x0a00;
  723. + dev->data_mask = 0x7ff;
  724. + dev->cfg_reg = 0x1fe2;
  725. + dev->code_base = 0x1a00;
  726. +
  727. + err = sc1442x_init_device(dev);
  728. + if (err < 0) {
  729. + dev_err(&pdev->dev, "failed to initialize chip\n");
  730. + goto err5;
  731. + }
  732. +
  733. + err = request_irq(pdev->irq, sc1442x_interrupt, IRQF_SHARED,
  734. + KBUILD_MODNAME, trx);
  735. + if (err < 0) {
  736. + dev_err(&pdev->dev, "failed to request IRQ%d\n", pdev->irq);
  737. + goto err6;
  738. + }
  739. +
  740. + dev->irq = pdev->irq;
  741. + err = dect_register_transceiver(trx);
  742. + if (err < 0)
  743. + goto err7;
  744. +
  745. + return 0;
  746. +
  747. +err7:
  748. + free_irq(pdev->irq, trx);
  749. +err6:
  750. + sc1442x_shutdown_device(dev);
  751. +err5:
  752. + dect_transceiver_free(trx);
  753. +err4:
  754. + iounmap(base);
  755. +err3:
  756. + pci_release_regions(pdev);
  757. +err2:
  758. + pci_disable_device(pdev);
  759. +err1:
  760. + return err;
  761. +}
  762. +
  763. +static void coa_remove(struct pci_dev *pdev)
  764. +{
  765. + struct dect_transceiver *trx = pci_get_drvdata(pdev);
  766. + struct coa_device *dev = dect_transceiver_priv(trx);
  767. + u8 __iomem *sc1442x_base = dev->sc1442x_base;
  768. +
  769. + sc1442x_shutdown_device(dev);
  770. + free_irq(pdev->irq, trx);
  771. + dect_unregister_transceiver(trx);
  772. + iounmap(sc1442x_base);
  773. + pci_release_regions(pdev);
  774. + pci_disable_device(pdev);
  775. +}
  776. +
  777. +static int coa_suspend(struct pci_dev *pdev, pm_message_t state)
  778. +{
  779. + struct dect_transceiver *trx = pci_get_drvdata(pdev);
  780. + struct coa_device *dev = dect_transceiver_priv(trx);
  781. +
  782. + sc1442x_shutdown_device(dev);
  783. + pci_save_state(pdev);
  784. + return 0;
  785. +}
  786. +
  787. +static int coa_resume(struct pci_dev *pdev)
  788. +{
  789. + struct dect_transceiver *trx = pci_get_drvdata(pdev);
  790. + struct coa_device *dev = dect_transceiver_priv(trx);
  791. +
  792. + pci_restore_state(pdev);
  793. + return sc1442x_init_device(dev);
  794. +}
  795. +
  796. +static DEFINE_PCI_DEVICE_TABLE(coa_pci_tbl) = {
  797. + {PCI_DEVICE(PCI_VENDOR_ID_QUICKLOGIC, PCI_DEVICE_ID_COA)},
  798. + {}
  799. +};
  800. +
  801. +static struct pci_driver coa_driver = {
  802. + .name = KBUILD_MODNAME,
  803. + .id_table = coa_pci_tbl,
  804. + .probe = coa_probe,
  805. + .remove = coa_remove,
  806. + .suspend = coa_suspend,
  807. + .resume = coa_resume,
  808. +};
  809. +
  810. +static int __init coa_pci_init(void)
  811. +{
  812. + return pci_register_driver(&coa_driver);
  813. +}
  814. +
  815. +static void __exit coa_pci_exit(void)
  816. +{
  817. + pci_unregister_driver(&coa_driver);
  818. +}
  819. +
  820. +module_init(coa_pci_init);
  821. +module_exit(coa_pci_exit);
  822. +
  823. +MODULE_DESCRIPTION("Dosch&Amand COM-ON-AIR PCI driver");
  824. +MODULE_LICENSE("GPL");
  825. +MODULE_DEVICE_TABLE(pci, coa_pci_tbl);
  826. diff --git a/drivers/dect/coa/dip_opcodes.h b/drivers/dect/coa/dip_opcodes.h
  827. new file mode 100644
  828. index 0000000..bd50056
  829. --- /dev/null
  830. +++ b/drivers/dect/coa/dip_opcodes.h
  831. @@ -0,0 +1,157 @@
  832. +/*
  833. + * com_on_air - basic driver for the Dosch and Amand "com on air" cards
  834. + *
  835. + * This program is free software; you can redistribute it and/or modify
  836. + * it under the terms of the GNU General Public License version 2 as
  837. + * published by the Free Software Foundation.
  838. + *
  839. + * authors:
  840. + * (C) 2008 Andreas Schuler <krater at badterrorist dot com>
  841. + * (C) 2008 Matthias Wenzel <dect at mazzoo dot de>
  842. + *
  843. + */
  844. +
  845. +#ifndef DIP_OPCODE_H
  846. +#define DIP_OPCODE_H
  847. +
  848. +#define BR 0x01
  849. +#define JMP 0x02
  850. +#define JMP1 0x03
  851. +#define RTN 0x04
  852. +#define BK_A1 0x05
  853. +#define WNTM1 0x06
  854. +#define WNTP1 0x07
  855. +#define WNT 0x08
  856. +#define WT 0x09
  857. +#define RFDIS 0x0a
  858. +#define RFEN 0x0b
  859. +#define LD_PTR 0x0c
  860. +#define SLOTZERO 0x0d
  861. +#define BK_A 0x0e
  862. +#define BK_C 0x0f
  863. +
  864. +
  865. +#define B_RST 0x20
  866. +#define B_ST2 0x21
  867. +#define B_XT 0x24
  868. +#define B_BT2 0x25
  869. +#define B_BTFU 0x25
  870. +#define B_XOFF 0x26
  871. +#define B_ON 0x27
  872. +#define B_XON 0x27
  873. +#define UNLCK 0x28
  874. +#define B_SR 0x29
  875. +#define B_XR 0x2b
  876. +#define EN_SL_ADJ 0x2c
  877. +#define B_BR2 0x2d
  878. +#define B_BRFU 0x2d
  879. +#define B_RINV 0x2e
  880. +#define B_RON 0x2f
  881. +
  882. +
  883. +#define B_ST 0x31
  884. +#define B_TX 0x31
  885. +#define B_AT 0x32
  886. +#define B_RC 0x33
  887. +#define B_BT 0x34
  888. +#define B_BTFP 0x35
  889. +#define B_BTP 0x35
  890. +#define B_AT2 0x37
  891. +#define B_WRS 0x39
  892. +#define B_AR 0x3a
  893. +#define B_BR 0x3c
  894. +#define B_BRP 0x3d
  895. +#define B_BRFP 0x3d
  896. +#define B_AR2 0x3f
  897. +
  898. +
  899. +#define D_RST 0x40
  900. +#define D_ON 0x42
  901. +#define D_OFF 0x43
  902. +#define D_PREP 0x44
  903. +#define WSC 0x48
  904. +
  905. +
  906. +#define D_LDK 0x50
  907. +#define D_LDS 0x57
  908. +#define D_WRS 0x5f
  909. +
  910. +
  911. +#define U_PSC 0x60
  912. +#define U_INT0 0x61
  913. +#define RCK_INT 0x62
  914. +#define RCK_EXT 0x63
  915. +#define B_WB_OFF 0x64
  916. +#define B_WB_ON 0x65
  917. +#define CLK1 0x66
  918. +#define CLK3 0x67
  919. +#define U_CK8 0x68
  920. +#define U_CK4 0x69
  921. +#define U_CK2 0x6a
  922. +#define U_INT1 0x6b
  923. +#define U_CK1 0x6c
  924. +#define U_INT2 0x6d
  925. +#define U_INT3 0x6f
  926. +
  927. +
  928. +#define A_RCV0 0x80
  929. +#define A_RCV36 0x82
  930. +#define A_RCV30 0x83
  931. +#define A_RCV24 0x84
  932. +#define A_RCV18 0x85
  933. +#define A_RCV12 0x86
  934. +#define A_RCV6 0x87
  935. +#define A_RCV33 0x8a
  936. +#define A_RCV27 0x8b
  937. +#define A_RCV21 0x8c
  938. +#define A_RCV15 0x8d
  939. +#define A_RCV9 0x8e
  940. +#define A_RCV3 0x8f
  941. +
  942. +
  943. +#define MEN3N 0xa2
  944. +#define MEN3 0xa3
  945. +#define MEN1N 0xa4
  946. +#define MEN1 0xa5
  947. +#define MEN2N 0xa6
  948. +#define MEN2 0xa7
  949. +#define M_RD 0xa8
  950. +#define M_RST 0xa9
  951. +
  952. +
  953. +#define M_WRS 0xb8
  954. +#define M_WR 0xb9
  955. +
  956. +
  957. +#define A_RST 0xc0
  958. +#define A_MUTE 0xc1
  959. +#define A_STOFF 0xc2
  960. +#define A_ALAW 0xc3
  961. +#define A_DT 0xc4
  962. +#define A_NORM 0xc5
  963. +#define A_LDR 0xc6
  964. +#define A_LDW 0xc7
  965. +#define A_LIN 0xc8
  966. +#define A_MTOFF 0xc9
  967. +#define A_MUTE1 0xca
  968. +#define A_MTOFF1 0xcb
  969. +#define A_STON 0xcc
  970. +#define A_DT1 0xcd
  971. +#define A_LDR1 0xce
  972. +#define A_LDW1 0xcf
  973. +
  974. +
  975. +#define A_STRN 0xe0
  976. +#define P_LD 0xe8
  977. +#define P_EN 0xe9
  978. +#define P_SC 0xea
  979. +#define A_RST1 0xeb
  980. +#define P_LDL 0xec
  981. +#define P_LDH 0xed
  982. +#define C_ON 0xee
  983. +#define C_OFF 0xef
  984. +
  985. +
  986. +#define C_LD 0xfa
  987. +
  988. +#endif
  989. diff --git a/drivers/dect/coa/radio_lmx3161.c b/drivers/dect/coa/radio_lmx3161.c
  990. new file mode 100644
  991. index 0000000..9f6d5ae
  992. --- /dev/null
  993. +++ b/drivers/dect/coa/radio_lmx3161.c
  994. @@ -0,0 +1,84 @@
  995. +/*
  996. + * radio_lmx3161 - NSC LMX3161 Single Chip Radio Transceiver radio operations
  997. + *
  998. + * This program is free software; you can redistribute it and/or modify
  999. + * it under the terms of the GNU General Public License version 2 as
  1000. + * published by the Free Software Foundation.
  1001. + *
  1002. + * Copyright (c) 2009 Patrick McHardy <[email protected]>
  1003. + */
  1004. +
  1005. +#include <linux/kernel.h>
  1006. +#include <linux/module.h>
  1007. +#include <linux/dect.h>
  1008. +#include <net/dect/dect.h>
  1009. +#include <net/dect/transceiver.h>
  1010. +
  1011. +#include "com_on_air.h"
  1012. +
  1013. +/* Intermediate frequency */
  1014. +#define RADIO_LMX3161_FREQ_IF 110592 /* kHz */
  1015. +
  1016. +/*
  1017. + * Control Bits
  1018. + */
  1019. +
  1020. +/* N-counter */
  1021. +#define RADIO_LMX3161_CTRL_N 0x0
  1022. +/* R-counter */
  1023. +#define RADIO_LMX3161_CTRL_R 0x2
  1024. +/* F-latch */
  1025. +#define RADIO_LMX3161_CTRL_F 0x1
  1026. +
  1027. +/*
  1028. + * Function Register (18 bit F-latch)
  1029. + */
  1030. +
  1031. +/* Prescaler modules select */
  1032. +#define RADIO_LMX3161_PRESCALER_32_33
  1033. +#define RADIO_LMX3161_PRESCALER_64_65
  1034. +/* Phase detector polarity: 0 = negative, 1 = positive */
  1035. +#define RADIO_LMX3161_PD (1 << 3)
  1036. +/* Charge pump current gain select: 0 = LOW (1*I_cpo), 1 = high (4*I_cpo) */
  1037. +#define RADIO_LMX3161_CP (1 << 4)
  1038. +/* tri-state charge pump output: 0 = normal, 1 = tri-state */
  1039. +#define RADIO_LMX3161_CP_TRISTATE (1 << 5)
  1040. +/* Receive chain power down control: 0 = power up, 1 = power down */
  1041. +#define RADIO_LMX3161_RX_POWER (1 << 7)
  1042. +/* Transmit chain power down control: 0 = power up, 1 = power down */
  1043. +#define RADIO_LMX3161_TX_POWER (1 << 8)
  1044. +/* Out 0 CMOS output: 0 = low, 1 = high */
  1045. +#define RADIO_LMX3161_CMOS0A (1 << 9)
  1046. +/* Out 1 CMOS output: 0 = low, 1 = high */
  1047. +#define RADIO_LMX3161_CMOS1 (1 << 10)
  1048. +/* Out 2 CMOS output: 0 = low, 1 = high */
  1049. +#define RADIO_LMX3161_CMOS2 (1 << 11)
  1050. +/* Power down mode select: */
  1051. +#define RADIO_LMX3161_POWER_DOWN_MASK (0x3 << 12)
  1052. +#define RADIO_LMX3161_POWER_DOWN_SW 0
  1053. +#define RADIO_LMX3161_POWER_DOWN_HARDWIRE (0x3 << 12)
  1054. +/* Demodulator gain select */
  1055. +/* Demodulator DC level shifting polarity */
  1056. +/* Demodulator DC level shift */
  1057. +
  1058. +static u64 lmx3161_map_band(struct coa_device *dev, const struct dect_band *band)
  1059. +{
  1060. + struct coa_freq_map_entry *fe;
  1061. + u32 frequency;
  1062. + u8 carrier;
  1063. +
  1064. + for (carrier = 0; carrier < band->carriers; carrier++) {
  1065. + frequency = band->frequency[carrier];
  1066. + fe = &dev->freq_map.carrier[carrier];
  1067. + }
  1068. + return 0;
  1069. +}
  1070. +
  1071. +const struct coa_radio_ops coa_lmx3161_radio_ops = {
  1072. + .type = "LMX3161",
  1073. + .rx_init = NULL,
  1074. + .tx_init = NULL,
  1075. + .set_carrier = NULL,
  1076. + .map_band = lmx3161_map_band,
  1077. +};
  1078. +EXPORT_SYMBOL_GPL(coa_lmx3161_radio_ops);
  1079. diff --git a/drivers/dect/coa/radio_u2785.c b/drivers/dect/coa/radio_u2785.c
  1080. new file mode 100644
  1081. index 0000000..dab53a0
  1082. --- /dev/null
  1083. +++ b/drivers/dect/coa/radio_u2785.c
  1084. @@ -0,0 +1,261 @@
  1085. +/*
  1086. + * radio_u2785 - ATMEL U2785 RF IC radio operations
  1087. + *
  1088. + * This program is free software; you can redistribute it and/or modify
  1089. + * it under the terms of the GNU General Public License version 2 as
  1090. + * published by the Free Software Foundation.
  1091. + *
  1092. + * Copyright (c) 2009 Patrick McHardy <[email protected]>
  1093. + */
  1094. +
  1095. +//#define DEBUG
  1096. +#include <linux/kernel.h>
  1097. +#include <linux/module.h>
  1098. +#include <linux/dect.h>
  1099. +#include <net/dect/dect.h>
  1100. +#include <net/dect/transceiver.h>
  1101. +
  1102. +#include "com_on_air.h"
  1103. +
  1104. +#define u2785_debug(dev, fmt, args...) \
  1105. + dev_dbg(dev->dev, "u2785: " fmt, ## args)
  1106. +
  1107. +/* Intermediate frequencies */
  1108. +#define RADIO_U2785_FREQ_IF1 110592 /* kHz */
  1109. +#define RADIO_U2785_FREQ_IF2 112320 /* kHz */
  1110. +
  1111. +/*
  1112. + * RC (Reference Divider)
  1113. + */
  1114. +#define RADIO_U2785_RC_SHIFT 22
  1115. +#define RADIO_U2785_RC_12 (0x1 << RADIO_U2785_RC_SHIFT)
  1116. +#define RADIO_U2785_RC_16 (0x2 << RADIO_U2785_RC_SHIFT)
  1117. +#define RADIO_U2785_RC_24 (0x3 << RADIO_U2785_RC_SHIFT)
  1118. +
  1119. +/*
  1120. + * SC (Swallow Counter) 0-31
  1121. + */
  1122. +#define RADIO_U2785_SC_SHIFT 17
  1123. +#define RADIO_U2785_SC_MAX 31
  1124. +#define RADIO_U2785_SC_MASK (0x1F << RADIO_U2785_SC_SHIFT)
  1125. +
  1126. +/*
  1127. + * MC (Main Divider)
  1128. + */
  1129. +#define RADIO_U2785_MC_SHIFT 15
  1130. +#define RADIO_U2785_MC_MIN 31
  1131. +#define RADIO_U2785_MC_MAX 34
  1132. +#define RADIO_U2785_MC_31 (0x0 << RADIO_U2785_MC_SHIFT)
  1133. +#define RADIO_U2785_MC_32 (0x1 << RADIO_U2785_MC_SHIFT)
  1134. +#define RADIO_U2785_MC_33 (0x2 << RADIO_U2785_MC_SHIFT)
  1135. +#define RADIO_U2785_MC_34 (0x3 << RADIO_U2785_MC_SHIFT)
  1136. +
  1137. +/*
  1138. + * PS (Phase Settings)
  1139. + */
  1140. +
  1141. +/* Phase of GF_DATA */
  1142. +#define RADIO_U2785_PS_GF (0x1 << 14)
  1143. +/* Phase of MCC Internal Connection */
  1144. +#define RADIO_U2785_PS_MCC (0x1 << 13)
  1145. +/* Phase of Charge Pump */
  1146. +#define RADIO_U2785_PS_CP (0x1 << 12)
  1147. +
  1148. +/*
  1149. + * Current-Saving Power-up/down Settings
  1150. + */
  1151. +
  1152. +/* Gaussian Filter */
  1153. +#define RADIO_U2785_GF (0x1 << 11)
  1154. +/* Modulation Compensation Circuit */
  1155. +#define RADIO_U2785_MCC (0x1 << 10)
  1156. +/* Frequency Doubler */
  1157. +#define RADIO_U2785_FD (0x1 << 8)
  1158. +/* OP1 + OP2 (Op Amps) */
  1159. +#define RADIO_U2785_OP (0x1 << 7)
  1160. +
  1161. +/*
  1162. + * Current Gain Settings (in percent)
  1163. + */
  1164. +#define RADIO_U2785_CGS_60 0x0
  1165. +#define RADIO_U2785_CGS_70 0x1
  1166. +#define RADIO_U2785_CGS_80 0x2
  1167. +#define RADIO_U2785_CGS_90 0x3
  1168. +#define RADIO_U2785_CGS_100 0x4
  1169. +#define RADIO_U2785_CGS_110 0x5
  1170. +#define RADIO_U2785_CGS_120 0x6
  1171. +#define RADIO_U2785_CGS_130 0x7
  1172. +
  1173. +/* GFCS (Gaussian-Filter Current Settings) */
  1174. +#define RADIO_U2785_GFCS_SHIFT 7
  1175. +/* CPCS (Charge-Pump Current Settings) */
  1176. +#define RADIO_U2785_CPCS_SHIFT 1
  1177. +/* MCCS (Modulation-Compensation Current Settings) */
  1178. +#define RADIO_U2785_MCCS_SHIFT 4
  1179. +
  1180. +/*
  1181. + * Pretune DAC Voltage
  1182. + */
  1183. +#define RADIO_U2785_DAC_SHIFT 4
  1184. +#define RADIO_U2785_DAC_300mV (0x0 << RADIO_U2785_DAC_SHIFT)
  1185. +#define RADIO_U2785_DAC_600mV (0x1 << RADIO_U2785_DAC_SHIFT)
  1186. +#define RADIO_U2785_DAC_900mV (0x2 << RADIO_U2785_DAC_SHIFT)
  1187. +#define RADIO_U2785_DAC_1200mV (0x3 << RADIO_U2785_DAC_SHIFT)
  1188. +#define RADIO_U2785_DAC_1400mV (0x4 << RADIO_U2785_DAC_SHIFT)
  1189. +#define RADIO_U2785_DAC_1700mV (0x5 << RADIO_U2785_DAC_SHIFT)
  1190. +#define RADIO_U2785_DAC_2000mV (0x6 << RADIO_U2785_DAC_SHIFT)
  1191. +#define RADIO_U2785_DAC_2300mV (0x7 << RADIO_U2785_DAC_SHIFT)
  1192. +
  1193. +/*
  1194. + * Address bit
  1195. + */
  1196. +#define RADIO_U2785_ADDRESS_BIT 0x1
  1197. +
  1198. +static void u2785_write_config(const struct coa_device *dev, u16 offset,
  1199. + u32 init1, u32 init2)
  1200. +{
  1201. + u8 init[5] = {
  1202. + /* first word: 24 bits */
  1203. + [0] = init1 >> 16,
  1204. + [1] = init1 >> 8,
  1205. + [2] = init1 | RADIO_U2785_ADDRESS_BIT,
  1206. + /* second word: 9 bits */
  1207. + [3] = init2 >> 1,
  1208. + [4] = 0,
  1209. + };
  1210. +
  1211. + sc1442x_rfdesc_write(dev, offset, init, sizeof(init));
  1212. +}
  1213. +
  1214. +static void u2785_rx_init(const struct coa_device *dev, u16 offset)
  1215. +{
  1216. + u32 init1 = 0, init2 = 0;
  1217. +
  1218. + init1 |= RADIO_U2785_RC_12;
  1219. + init1 |= RADIO_U2785_MC_32;
  1220. + init1 |= 10 << RADIO_U2785_SC_SHIFT;
  1221. +
  1222. + init1 |= RADIO_U2785_CGS_100 << RADIO_U2785_CPCS_SHIFT;
  1223. +
  1224. + init2 |= RADIO_U2785_FD;
  1225. + init2 |= RADIO_U2785_CGS_100 << RADIO_U2785_MCCS_SHIFT;
  1226. +
  1227. + u2785_write_config(dev, offset, init1, init2);
  1228. +}
  1229. +
  1230. +static void u2785_tx_init(const struct coa_device *dev, u16 offset)
  1231. +{
  1232. + u32 init1 = 0, init2 = 0;
  1233. +
  1234. + init1 |= RADIO_U2785_RC_12;
  1235. + init1 |= RADIO_U2785_MC_34;
  1236. + init1 |= 7 << RADIO_U2785_SC_SHIFT;
  1237. +
  1238. + init1 |= RADIO_U2785_GF;
  1239. + init1 |= RADIO_U2785_MCC;
  1240. + init1 |= RADIO_U2785_CGS_120 << RADIO_U2785_GFCS_SHIFT;
  1241. + init1 |= RADIO_U2785_DAC_1400mV;
  1242. + init1 |= RADIO_U2785_CGS_60 << RADIO_U2785_CPCS_SHIFT;
  1243. +
  1244. + init2 |= RADIO_U2785_FD;
  1245. + init2 |= RADIO_U2785_CGS_130 << RADIO_U2785_MCCS_SHIFT;
  1246. +
  1247. + u2785_write_config(dev, offset, init1, init2);
  1248. +}
  1249. +
  1250. +static void u2785_write_carrier(const struct coa_device *dev, u16 offset,
  1251. + u32 init1)
  1252. +{
  1253. + u8 init[3] = {
  1254. + /* first word: 24 bits */
  1255. + [0] = init1 >> 16,
  1256. + [1] = init1 >> 8,
  1257. + [2] = init1 | RADIO_U2785_ADDRESS_BIT,
  1258. + };
  1259. +
  1260. + sc1442x_rfdesc_write(dev, offset, init, sizeof(init));
  1261. +}
  1262. +
  1263. +static void u2785_set_carrier(const struct coa_device *dev, u16 offset,
  1264. + enum dect_slot_states mode, u8 carrier)
  1265. +{
  1266. + const struct coa_freq_map_entry *fe = &dev->freq_map.carrier[carrier];
  1267. + u32 init1 = 0;
  1268. +
  1269. + init1 |= RADIO_U2785_RC_12;
  1270. +
  1271. + switch (mode) {
  1272. + case DECT_SLOT_SCANNING:
  1273. + case DECT_SLOT_RX:
  1274. + init1 |= (fe->rx.divisor - RADIO_U2785_MC_MIN) <<
  1275. + RADIO_U2785_MC_SHIFT;
  1276. + init1 |= fe->rx.swcnt << RADIO_U2785_SC_SHIFT;
  1277. +
  1278. + init1 |= RADIO_U2785_CGS_100 << RADIO_U2785_CPCS_SHIFT;
  1279. + break;
  1280. + case DECT_SLOT_TX:
  1281. + init1 |= (fe->tx.divisor - RADIO_U2785_MC_MIN) <<
  1282. + RADIO_U2785_MC_SHIFT;
  1283. + init1 |= fe->tx.swcnt << RADIO_U2785_SC_SHIFT;
  1284. +
  1285. + init1 |= RADIO_U2785_GF;
  1286. + init1 |= RADIO_U2785_MCC;
  1287. + init1 |= RADIO_U2785_CGS_120 << RADIO_U2785_GFCS_SHIFT;
  1288. + init1 |= RADIO_U2785_DAC_1400mV;
  1289. + init1 |= RADIO_U2785_CGS_60 << RADIO_U2785_CPCS_SHIFT;
  1290. + break;
  1291. + default:
  1292. + return;
  1293. + }
  1294. +
  1295. + u2785_write_carrier(dev, offset, init1);
  1296. +}
  1297. +
  1298. +static int u2785_map_freq(u32 frequency, u8 *s_mc, u8 *s_sc)
  1299. +{
  1300. + frequency /= DECT_CARRIER_WIDTH;
  1301. +
  1302. + *s_mc = frequency / 32;
  1303. + if (*s_mc < RADIO_U2785_MC_MIN || *s_mc > RADIO_U2785_MC_MAX)
  1304. + return false;
  1305. + *s_sc = frequency % 32;
  1306. + return true;
  1307. +}
  1308. +
  1309. +static u64 u2785_map_band(struct coa_device *dev, const struct dect_band *band)
  1310. +{
  1311. + struct coa_freq_map_entry *fe;
  1312. + u64 carriers = 0;
  1313. + u32 frequency;
  1314. + u8 carrier;
  1315. +
  1316. + for (carrier = 0; carrier < band->carriers; carrier++) {
  1317. + frequency = band->frequency[carrier];
  1318. + fe = &dev->freq_map.carrier[carrier];
  1319. +
  1320. + if (!u2785_map_freq(frequency - RADIO_U2785_FREQ_IF1,
  1321. + &fe->rx.divisor, &fe->rx.swcnt))
  1322. + continue;
  1323. + if (!u2785_map_freq(frequency,
  1324. + &fe->tx.divisor, &fe->tx.swcnt))
  1325. + continue;
  1326. +
  1327. + carriers |= 1 << carrier;
  1328. + u2785_debug(dev, "carrier %u (%u.%03uMHz) => "
  1329. + "rx: div: %u sw: %u tx: div: %u sw: %u\n",
  1330. + carrier, frequency / 1000, frequency % 1000,
  1331. + fe->rx.divisor, fe->rx.swcnt,
  1332. + fe->tx.divisor, fe->tx.swcnt);
  1333. + }
  1334. +
  1335. + return carriers;
  1336. +}
  1337. +
  1338. +const struct coa_radio_ops coa_u2785_radio_ops = {
  1339. + .type = "U2785B",
  1340. + .rx_init = u2785_rx_init,
  1341. + .tx_init = u2785_tx_init,
  1342. + .set_carrier = u2785_set_carrier,
  1343. + .map_band = u2785_map_band,
  1344. +};
  1345. +EXPORT_SYMBOL_GPL(coa_u2785_radio_ops);
  1346. diff --git a/drivers/dect/coa/sc1442x.c b/drivers/dect/coa/sc1442x.c
  1347. new file mode 100644
  1348. index 0000000..73b9869
  1349. --- /dev/null
  1350. +++ b/drivers/dect/coa/sc1442x.c
  1351. @@ -0,0 +1,1032 @@
  1352. +/*
  1353. + * com_on_air - basic driver for the Dosch and Amand "com on air" cards
  1354. + *
  1355. + * This program is free software; you can redistribute it and/or modify
  1356. + * it under the terms of the GNU General Public License version 2 as
  1357. + * published by the Free Software Foundation.
  1358. + *
  1359. + * authors:
  1360. + * (C) 2008 Andreas Schuler <krater at badterrorist dot com>
  1361. + * (C) 2008 Matthias Wenzel <dect at mazzoo dot de>
  1362. + * (C) 2009 Patrick McHardy <[email protected]>
  1363. + *
  1364. + */
  1365. +
  1366. +#include <linux/kernel.h>
  1367. +#include <linux/module.h>
  1368. +#include <linux/skbuff.h>
  1369. +#include <linux/dect.h>
  1370. +#include <net/dect/dect.h>
  1371. +#include <net/dect/mac_csf.h>
  1372. +#include <net/dect/dsc.h>
  1373. +#include <net/dect/transceiver.h>
  1374. +#include <asm/io.h>
  1375. +
  1376. +#include "com_on_air.h"
  1377. +#include "sc1442x_firmware.h"
  1378. +#include "dip_opcodes.h"
  1379. +
  1380. +/*
  1381. + * The sc1442x contain a 2k data RAM and 512b code RAM. The two primary
  1382. + * methods for memory access are direct and indirect access. In indirect
  1383. + * mode, the access goes through the DIP and the memory bank needs to be
  1384. + * mapped by writting its number to the control register. In direct mode
  1385. + * the memory can be accessed directly, the three modes differ only in
  1386. + * the address space layout. The choice between direct and indirect mode
  1387. + * is made by the device vendor.
  1388. + *
  1389. + * The address space is layed out as follows:
  1390. + *
  1391. + * PCI - size 8k:
  1392. + *
  1393. + * 0x0a00 - 0x11ff: data memory
  1394. + * 0x1a00 - 0x1bff: code memory
  1395. + * 0x1f00 - 0x1fff: DIP control and status registers
  1396. + *
  1397. + * PCMCIA - size 1k:
  1398. + *
  1399. + * 0x0000 - 0x01ff: 256 bytes memory
  1400. + * 0x0200 - 0x02ff: DIP control and status registers
  1401. + *
  1402. + * Memory of the PCMCIA device is addressed in 16 bit little endian quantities.
  1403. + *
  1404. + * The first bank of the data memory contains DIP specific control data,
  1405. + * the remaining banks are used to store packet and slot configuration data,
  1406. + * with each slot having one half memory bank assigned.
  1407. + *
  1408. + * The per slot data of 128 bytes is layed out as follows:
  1409. + *
  1410. + * Offset RX TX
  1411. + *
  1412. + * 0x00 - 0x05: Status Preamble
  1413. + * 0x06 - 0x0d: A-Field A-Field
  1414. + * 0x0e - 0x35: B-Field B-Field
  1415. + *
  1416. + * 0x65 - 0x68: Radio Cfg Radio Cfg
  1417. + * 0x69 - 0x6f: BMC Ctrl BMC Ctrl
  1418. + * 0x70 - 0x7f: DCS IV/Key DCS IV/Key
  1419. + * 0x70 - 0x7a: DCS state DCS state
  1420. + */
  1421. +
  1422. +#define SC1442X_DIPSTOPPED 0x80
  1423. +#define SC1442X_PRESCALER_ENABLED 0x40
  1424. +#define SC1442X_TIMER_INTERRUPT_ENABLED 0x02
  1425. +
  1426. +/* Memory access modes */
  1427. +#define SC1442X_LINEAR_MODE 0x01
  1428. +#define SC1442X_LINEAR_MODE_0 (SC14421_LINEAR_MODE | 0x0)
  1429. +#define SC1442X_LINEAR_MODE_1 (SC14421_LINEAR_MODE | 0x2)
  1430. +#define SC1442X_LINEAR_MODE_2 (SC14421_LINEAR_MODE | 0x3)
  1431. +
  1432. +/* Indirect mode RAM bank select */
  1433. +#define SC1442X_RAMBANK0 0x00
  1434. +#define SC1442X_RAMBANK1 0x04
  1435. +#define SC1442X_RAMBANK2 0x08
  1436. +#define SC1442X_RAMBANK3 0x0c
  1437. +#define SC1442X_RAMBANK4 0x10
  1438. +#define SC1442X_RAMBANK5 0x14
  1439. +#define SC1442X_RAMBANK6 0x18
  1440. +#define SC1442X_RAMBANK7 0x1c
  1441. +#define SC1442X_CODEBANK 0x20
  1442. +#define SC1442X_BANKSIZE 0x100
  1443. +
  1444. +/* Interrupts 0-3 */
  1445. +#define SC1442X_IRQ_SLOT_0_5 0x01
  1446. +#define SC1442X_IRQ_SLOT_6_11 0x02
  1447. +#define SC1442X_IRQ_SLOT_12_17 0x04
  1448. +#define SC1442X_IRQ_SLOT_18_23 0x08
  1449. +#define SC1442X_IRQ_TIMER 0x10
  1450. +#define SC1442X_IRQ_MASK 0x1f
  1451. +
  1452. +/* Interrupt status 1: DIP/CLK100/TIM1/TIM0/SPI/UART/P10/KEYB */
  1453. +#define SC14424_RESET_INT_PENDING_1 0x1f02
  1454. +/* Interrupt status 2: CLK8K/TONE */
  1455. +#define SC14424_RESET_INT_PENDING_2 0x1f03
  1456. +
  1457. +/* DIP_INT and CLK100_INT priority level */
  1458. +#define SC14424_INT_PRIORITY_1 0x1f06
  1459. +
  1460. +/* P1 output control */
  1461. +#define SC14424_P1_SET_OUTPUT_DATA 0x1f21
  1462. +#define SC14424_P1_RESET_OUTPUT_DATA 0x1f22
  1463. +
  1464. +/* P1 input/output direction */
  1465. +#define SC14424_P1_DIR_REG 0x1f23
  1466. +
  1467. +/*
  1468. + * Burst Mode Controller control information
  1469. + */
  1470. +
  1471. +/* Maximum number of unmasked errors in S-field bits 8 to 31 */
  1472. +#define SC1442X_BC0_S_ERR_SHIFT 4
  1473. +/* Invert incoming data (RDI) */
  1474. +#define SC1442X_BC0_INV_RDI 0x08
  1475. +/* Invert outgoing data (TDO) */
  1476. +#define SC1442X_BC0_INV_TDO 0x04
  1477. +/* Disable writing B-field on A-field CRC error */
  1478. +#define SC1442X_BC0_SENS_A 0x02
  1479. +/* PP/FP mode */
  1480. +#define SC1442X_BC0_PP_MODE 0x01
  1481. +
  1482. +/* Error test mask for S-field bits 15-8 */
  1483. +#define SC1442X_BC1_MASK_MASK 0xff
  1484. +
  1485. +/* Sliding error test mask for S-field bits 15-8 */
  1486. +#define SC1442X_BC2_SLIDE_MASK 0xff
  1487. +
  1488. +/* DAC output value when BCM is active (for frequency control?) */
  1489. +#define SC1442X_BC3_DAC_MASK 0x1f
  1490. +
  1491. +/* Only perform phase jump for correct A-field CRC + SL_EN_ADJ command */
  1492. +#define SC1442X_BC4_ADP 0x10
  1493. +/* Window in which S-field is accepted */
  1494. +#define SC1442X_BC4_WIN_MASK 0x0f
  1495. +
  1496. +/* Amplitude-trimming of gaussian shape */
  1497. +#define SC1442X_BC5_VOL_SHIFT 4
  1498. +/* Disable scrambling */
  1499. +#define SC1442X_BC5_SC_OFF 0x08
  1500. +/* PD1 synchronization pattern:
  1501. + * 0 = S-field received, 1 = preamble + first 2 bits of synchronization word */
  1502. +#define SC1442X_BC5_DO_FR 0x04
  1503. +/* TDO output shape */
  1504. +#define SC1442X_BC5_TDO_DIGITAL 0x00
  1505. +#define SC1442X_BC5_TDO_GAUSIAN 0x01
  1506. +#define SC1442X_BC5_TDO_POWER_DOWN 0x02
  1507. +#define SC1442X_BC5_TDO_MID_LEVEL 0x03
  1508. +
  1509. +/* Low 4 bits of multiframe number */
  1510. +#define SC1442X_BC6_MFR_SHIFT 4
  1511. +#define SC1442X_BC6_MFR_MASK 0xf0
  1512. +/* Frame number */
  1513. +#define SC1442X_BC6_FR_MASK 0x0f
  1514. +
  1515. +/*
  1516. + * Burst Mode Controller status information
  1517. + */
  1518. +
  1519. +/* Peak binary value of ADC (RSSI) */
  1520. +#define SC1442X_ST0_ADC_MASK 0x3f
  1521. +
  1522. +/* S-pattern recognized according to BMC configuration */
  1523. +#define SC1442X_ST1_IN_SYNC 0x80
  1524. +
  1525. +/* A-field R-CRC correct */
  1526. +#define SC1442X_ST1_A_CRC 0x40
  1527. +
  1528. +/* Protected Bn-subfield R-CRC correct */
  1529. +#define SC1442X_ST1_B_CRC_MASK 0x3c
  1530. +#define SC1442X_ST1_B1_CRC 0x20
  1531. +#define SC1442X_ST1_B2_CRC 0x10
  1532. +#define SC1442X_ST1_B3_CRC 0x08
  1533. +#define SC1442X_ST1_B4_CRC 0x04
  1534. +
  1535. +/* B-field X-CRC correct */
  1536. +#define SC1442X_ST1_X_CRC 0x02
  1537. +
  1538. +/* Z-field equals X-CRC */
  1539. +#define SC1442X_ST1_Z_CRC 0x01
  1540. +
  1541. +/* Phase offset of received S-field: which of the nine internal clock cycles
  1542. + * per symbol sampled the incoming data. The frequency deviation can be
  1543. + * calculated from the difference of the offsets of two consequitive frames as:
  1544. + *
  1545. + * K * (T / 9) / 10m = K * 96ns / 10m = K * 9.6ppm
  1546. + */
  1547. +#define SC1442X_ST2_TAP_SHIFT 4
  1548. +#define SC1442X_ST2_TAP_MASK 0xf0
  1549. +#define SC1442X_ST2_TAP_SCALE (DECT_PHASE_OFFSET_SCALE * 96 / 10)
  1550. +
  1551. +/* Number of unmasked S-field errors according to BMC configuration */
  1552. +#define SC1442X_ST2_S_ERR_SHIFT 0
  1553. +#define SC1442X_ST2_S_ERR_MASK 0x0f
  1554. +
  1555. +/* Phase offset of received S-field: difference of number of symbol periods
  1556. + * between nominal 11520 symbols per frame and actual number of symbols. The
  1557. + * frequency deviation can be calculated from the difference of two
  1558. + * consequitive frames as:
  1559. + *
  1560. + * N * T / 10m = N * 870ns / 10m = N * 87ppm
  1561. + */
  1562. +#define SC1442X_ST3_PHASE_MASK 0xff
  1563. +#define SC1442X_ST3_PHASE_SCALE (DECT_PHASE_OFFSET_SCALE * 87)
  1564. +
  1565. +/* DC offset of received data to comparator reference input (DAC) */
  1566. +#define SC1442X_ST4_DC_MASK 0x3f
  1567. +
  1568. +/*
  1569. + * Codec configuration
  1570. + */
  1571. +
  1572. +#define SC1442X_CC_SIZE 6
  1573. +
  1574. +#define SC1442X_CC0_STANDBY 0xc2
  1575. +#define SC1442X_CC0_POWERDOWN 0x3d
  1576. +
  1577. +/* Logical memory banks */
  1578. +#define SC1442X_BANK_UNITS 8
  1579. +#define SC1442X_SLOT_BANK_SIZE 128
  1580. +
  1581. +static const u8 banktable[] = {
  1582. + SC1442X_RAMBANK1,
  1583. + SC1442X_RAMBANK2,
  1584. + SC1442X_RAMBANK3,
  1585. + SC1442X_RAMBANK4,
  1586. + SC1442X_RAMBANK5,
  1587. + SC1442X_RAMBANK6,
  1588. +};
  1589. +
  1590. +static const u8 slottable[] = {
  1591. + Slot00, Slot01, Slot02, Slot03, Slot04, Slot05, Slot06, Slot07,
  1592. + Slot08, Slot09, Slot10, Slot11, Slot12, Slot13, Slot14, Slot15,
  1593. + Slot16, Slot17, Slot18, Slot19, Slot20, Slot21, Slot22, Slot23,
  1594. +};
  1595. +
  1596. +static const u8 sc1442x_rx_funcs[DECT_PACKET_MAX + 1][DECT_B_MAX + 1][2][2] = {
  1597. + [DECT_PACKET_P00][DECT_B_NONE][0][0] = RX_P00,
  1598. + [DECT_PACKET_P00][DECT_B_NONE][0][1] = RX_P00_Sync,
  1599. + [DECT_PACKET_P32][DECT_B_UNPROTECTED][0][0] = RX_P32U,
  1600. + [DECT_PACKET_P32][DECT_B_UNPROTECTED][1][0] = RX_P32U_Enc,
  1601. + [DECT_PACKET_P640j][DECT_B_UNPROTECTED][0][0] = RX_P640j,
  1602. + [DECT_PACKET_P640j][DECT_B_UNPROTECTED][1][0] = RX_P640j_Enc,
  1603. +};
  1604. +
  1605. +static const u8 sc1442x_tx_funcs[DECT_PACKET_MAX + 1][DECT_B_MAX + 1][2] = {
  1606. + [DECT_PACKET_P00][DECT_B_NONE][0] = TX_P00,
  1607. + [DECT_PACKET_P32][DECT_B_UNPROTECTED][0] = TX_P32U,
  1608. + [DECT_PACKET_P32][DECT_B_UNPROTECTED][1] = TX_P32U_Enc,
  1609. + [DECT_PACKET_P640j][DECT_B_UNPROTECTED][0] = TX_P640j,
  1610. + [DECT_PACKET_P640j][DECT_B_UNPROTECTED][1] = TX_P640j_Enc,
  1611. +};
  1612. +
  1613. +/*
  1614. + * Raw IO functions
  1615. + */
  1616. +
  1617. +static void sc1442x_lock_mem(struct coa_device *dev) __acquires(dev->lock)
  1618. +{
  1619. + spin_lock_irq(&dev->lock);
  1620. +}
  1621. +
  1622. +static void sc1442x_unlock_mem(struct coa_device *dev) __releases(dev->lock)
  1623. +{
  1624. + mmiowb();
  1625. + spin_unlock_irq(&dev->lock);
  1626. +}
  1627. +
  1628. +static u8 sc1442x_readb(const struct coa_device *dev, u16 offset)
  1629. +{
  1630. + switch (dev->type) {
  1631. + case COA_TYPE_PCI:
  1632. + return readb(dev->sc1442x_base + offset);
  1633. + case COA_TYPE_PCMCIA:
  1634. + return le16_to_cpu(readw(dev->sc1442x_base + 2 * offset));
  1635. + default:
  1636. + BUG();
  1637. + }
  1638. +}
  1639. +
  1640. +static u16 sc1442x_readw(const struct coa_device *dev, u16 offset)
  1641. +{
  1642. + u32 tmp;
  1643. +
  1644. + switch (dev->type) {
  1645. + case COA_TYPE_PCI:
  1646. + return le16_to_cpu(readw(dev->sc1442x_base + offset));
  1647. + case COA_TYPE_PCMCIA:
  1648. + tmp = le32_to_cpu(readl(dev->sc1442x_base + 2 * offset));
  1649. + return (tmp >> 8) | (tmp & 0xff);
  1650. + default:
  1651. + BUG();
  1652. + }
  1653. +}
  1654. +
  1655. +static void sc1442x_writeb(const struct coa_device *dev, u16 offset, u8 value)
  1656. +{
  1657. + switch (dev->type) {
  1658. + case COA_TYPE_PCI:
  1659. + writeb(value, dev->sc1442x_base + offset);
  1660. + break;
  1661. + case COA_TYPE_PCMCIA:
  1662. + writew(cpu_to_le16(value), dev->sc1442x_base + 2 * offset);
  1663. + break;
  1664. + }
  1665. +}
  1666. +
  1667. +static void sc1442x_writew(const struct coa_device *dev, u16 offset, u16 value)
  1668. +{
  1669. + u32 tmp;
  1670. +
  1671. + switch (dev->type) {
  1672. + case COA_TYPE_PCI:
  1673. + writew(cpu_to_le16(value), dev->sc1442x_base + offset);
  1674. + break;
  1675. + case COA_TYPE_PCMCIA:
  1676. + tmp = ((value & 0xff00) << 8) | (value & 0xff);
  1677. + writel(cpu_to_le32(tmp), dev->sc1442x_base + 2 * offset);
  1678. + break;
  1679. + }
  1680. +}
  1681. +
  1682. +static void sc1442x_stop_dip(struct coa_device *dev)
  1683. +{
  1684. + /* Prevent the interrupt handler from restarting the DIP */
  1685. + dev->ctrl = SC1442X_DIPSTOPPED;
  1686. +
  1687. + /* Stop the DIP and wait for interrupt handler to complete */
  1688. + sc1442x_writeb(dev, dev->cfg_reg, SC1442X_DIPSTOPPED);
  1689. + synchronize_irq(dev->irq);
  1690. +}
  1691. +
  1692. +static void sc1442x_start_dip(struct coa_device *dev)
  1693. +{
  1694. + dev->ctrl = 0;
  1695. + sc1442x_writeb(dev, dev->cfg_reg, 0x00);
  1696. +}
  1697. +
  1698. +static void sc1442x_switch_to_bank(const struct coa_device *dev, u8 bank)
  1699. +{
  1700. + if (dev->type != COA_TYPE_PCMCIA)
  1701. + return;
  1702. + sc1442x_writeb(dev, dev->cfg_reg, bank | dev->ctrl);
  1703. + /* need to wait for 4 IO cycles */
  1704. + inb_p(dev->config_base);
  1705. + inb_p(dev->config_base);
  1706. + inb_p(dev->config_base);
  1707. + inb_p(dev->config_base);
  1708. +}
  1709. +
  1710. +static void sc1442x_toggle_led(struct coa_device *dev)
  1711. +{
  1712. + if (dev->type != COA_TYPE_PCI)
  1713. + return;
  1714. +
  1715. + if ((dev->led & 0xf) > 0x7)
  1716. + sc1442x_writeb(dev, SC14424_P1_SET_OUTPUT_DATA, 0x40);
  1717. + else
  1718. + sc1442x_writeb(dev, SC14424_P1_RESET_OUTPUT_DATA, 0x40);
  1719. + dev->led++;
  1720. +}
  1721. +
  1722. +/*
  1723. + * Code memory IO functions
  1724. + */
  1725. +static void sc1442x_write_cmd(const struct coa_device *dev, u16 label,
  1726. + u8 opcode, u8 operand)
  1727. +{
  1728. + sc1442x_writew(dev, dev->code_base + 2 * label, operand << 8 | opcode);
  1729. +}
  1730. +
  1731. +static void sc1442x_to_cmem(const struct coa_device *dev,
  1732. + const u8 *src, u16 length)
  1733. +{
  1734. + u16 i;
  1735. +
  1736. + for (i = 0; i < length; i++)
  1737. + sc1442x_writeb(dev, dev->code_base + i, src[i]);
  1738. +}
  1739. +
  1740. +/*
  1741. + * Data memory IO functions
  1742. + */
  1743. +static inline u8 sc1442x_dreadb(const struct coa_device *dev, u16 offset)
  1744. +{
  1745. + return sc1442x_readb(dev, dev->data_base + (offset & dev->data_mask));
  1746. +}
  1747. +
  1748. +static inline u16 sc1442x_dreadw(const struct coa_device *dev, u16 offset)
  1749. +{
  1750. + return sc1442x_readw(dev, dev->data_base + (offset & dev->data_mask));
  1751. +}
  1752. +
  1753. +static inline void sc1442x_dwriteb(const struct coa_device *dev,
  1754. + u16 offset, u8 value)
  1755. +{
  1756. + sc1442x_writeb(dev, dev->data_base + (offset & dev->data_mask), value);
  1757. +}
  1758. +
  1759. +static inline void sc1442x_dwritew(const struct coa_device *dev,
  1760. + u16 offset, u16 value)
  1761. +{
  1762. + sc1442x_writew(dev, dev->data_base + (offset & dev->data_mask), value);
  1763. +}
  1764. +
  1765. +static void sc1442x_to_dmem(const struct coa_device *dev, u16 offset,
  1766. + const void *src, u16 length)
  1767. +{
  1768. + u16 i = 0;
  1769. +
  1770. + for (; length >= 2; length -= 2, i += 2)
  1771. + sc1442x_dwritew(dev, offset + i, *(u16 *)(src + i));
  1772. + for (; length >= 1; length -= 1, i += 1)
  1773. + sc1442x_dwriteb(dev, offset + i, *(u8 *)(src + i));
  1774. +}
  1775. +
  1776. +static void sc1442x_from_dmem(const struct coa_device *dev, void *dst,
  1777. + u16 offset, u16 length)
  1778. +{
  1779. + u16 i = 0;
  1780. +
  1781. + for (; length >= 2; length -= 2, i += 2)
  1782. + *(u16 *)(dst + i) = sc1442x_dreadw(dev, offset + i);
  1783. + for (; length >= 1; length -= 1, i += 1)
  1784. + *(u8 *)(dst + i) = sc1442x_dreadb(dev, offset + i);
  1785. +}
  1786. +
  1787. +static u8 sc1442x_dip_bankaddress(u8 slot)
  1788. +{
  1789. + return (slot / 2 + 2) * SC1442X_SLOT_BANK_SIZE / SC1442X_BANK_UNITS;
  1790. +}
  1791. +
  1792. +static u8 sc1442x_slot_bank(u8 slot)
  1793. +{
  1794. + return banktable[slot / 4];
  1795. +}
  1796. +
  1797. +static u16 sc1442x_slot_offset(u8 slot)
  1798. +{
  1799. + u16 offset;
  1800. +
  1801. + offset = SC1442X_BANKSIZE + slot / 4 * SC1442X_BANKSIZE;
  1802. + if (slot & 0x2)
  1803. + offset += SC1442X_BANKSIZE / 2;
  1804. + return offset;
  1805. +}
  1806. +
  1807. +void sc1442x_rfdesc_write(const struct coa_device *dev, u16 offset,
  1808. + const u8 *src, u16 length)
  1809. +{
  1810. + sc1442x_to_dmem(dev, offset + RF_DESC, src, length);
  1811. +}
  1812. +
  1813. +/*
  1814. + * Ciphering
  1815. + */
  1816. +
  1817. +static void sc1442x_dcs_init(const struct coa_device *dev,
  1818. + const struct dect_transceiver *trx,
  1819. + u8 slot, u32 mfn, u8 framenum)
  1820. +{
  1821. + const struct dect_transceiver_slot *ts = &trx->slots[slot];
  1822. + u16 off = sc1442x_slot_offset(slot);
  1823. + __le64 iv;
  1824. +
  1825. + iv = dect_dsc_iv(mfn, framenum);
  1826. + sc1442x_to_dmem(dev, off + DCS_IV, &iv, 8);
  1827. + sc1442x_to_dmem(dev, off + DCS_CK, &ts->ck, 8);
  1828. +}
  1829. +
  1830. +/* Transfer DCS cipher state between two TDD slots of a MAC connection */
  1831. +static void sc1442x_transfer_dcs_state(struct coa_device *dev,
  1832. + struct dect_transceiver *trx,
  1833. + u8 slot)
  1834. +{
  1835. + u8 slot2 = slot + DECT_HALF_FRAME_SIZE;
  1836. + struct dect_transceiver_slot *ts1 = &trx->slots[slot];
  1837. + struct dect_transceiver_slot *ts2 = &trx->slots[slot2];
  1838. + u8 dcs_state[DCS_STATE_SIZE];
  1839. + u16 off;
  1840. +
  1841. + if (!(ts1->flags & DECT_SLOT_CIPHER) ||
  1842. + !(ts2->flags & DECT_SLOT_CIPHER))
  1843. + return;
  1844. +
  1845. + sc1442x_switch_to_bank(dev, sc1442x_slot_bank(slot));
  1846. + off = sc1442x_slot_offset(slot);
  1847. + sc1442x_from_dmem(dev, dcs_state, off + DCS_STATE, DCS_STATE_SIZE);
  1848. +
  1849. + sc1442x_switch_to_bank(dev, sc1442x_slot_bank(slot2));
  1850. + off = sc1442x_slot_offset(slot2);
  1851. + sc1442x_to_dmem(dev, off + DCS_STATE, dcs_state, DCS_STATE_SIZE);
  1852. +}
  1853. +
  1854. +/*
  1855. + * Transceiver operations
  1856. + */
  1857. +
  1858. +static void sc1442x_disable(const struct dect_transceiver *trx)
  1859. +{
  1860. + sc1442x_stop_dip(dect_transceiver_priv(trx));
  1861. +}
  1862. +
  1863. +static void sc1442x_enable(const struct dect_transceiver *trx)
  1864. +{
  1865. + const struct coa_device *dev = dect_transceiver_priv(trx);
  1866. + u8 slot;
  1867. +
  1868. + /* Restore slot table to a pristine state */
  1869. + sc1442x_switch_to_bank(dev, SC1442X_CODEBANK);
  1870. + for (slot = 0; slot < DECT_FRAME_SIZE; slot++) {
  1871. + sc1442x_write_cmd(dev, slottable[slot] + 0, WT, 1);
  1872. + sc1442x_write_cmd(dev, slottable[slot] + 1, WNT, 1);
  1873. + }
  1874. +
  1875. + if (trx->cell->mode == DECT_MODE_FP) {
  1876. + sc1442x_write_cmd(dev, ClockSyncOn, WT, 1);
  1877. + sc1442x_write_cmd(dev, ClockAdjust, WT, 1);
  1878. + sc1442x_write_cmd(dev, ClockSyncOff, WT, 1);
  1879. +
  1880. + sc1442x_write_cmd(dev, TX_P32U_Enc, JMP, LoadEncKey);
  1881. + sc1442x_write_cmd(dev, RX_P32U_Enc, JMP, LoadEncState);
  1882. + sc1442x_write_cmd(dev, TX_P640j_Enc, JMP, LoadEncKey);
  1883. + sc1442x_write_cmd(dev, RX_P640j_Enc, JMP, LoadEncState);
  1884. + } else {
  1885. + sc1442x_write_cmd(dev, ClockSyncOn, P_SC, PSC_S_SYNC_ON);
  1886. + sc1442x_write_cmd(dev, ClockAdjust, EN_SL_ADJ, 1);
  1887. + sc1442x_write_cmd(dev, ClockSyncOff, P_SC, 0x00);
  1888. +
  1889. + sc1442x_write_cmd(dev, RX_P32U_Enc, JMP, LoadEncKey);
  1890. + sc1442x_write_cmd(dev, TX_P32U_Enc, JMP, LoadEncState);
  1891. + sc1442x_write_cmd(dev, RX_P640j_Enc, JMP, LoadEncKey);
  1892. + sc1442x_write_cmd(dev, TX_P640j_Enc, JMP, LoadEncState);
  1893. + }
  1894. +
  1895. + if (trx->mode == DECT_TRANSCEIVER_MASTER)
  1896. + sc1442x_write_cmd(dev, RFStart, BR, SlotTable);
  1897. + else {
  1898. + sc1442x_write_cmd(dev, RFStart, BR, SyncInit);
  1899. + sc1442x_write_cmd(dev, SyncLoop, BR, Sync);
  1900. + }
  1901. +
  1902. + sc1442x_start_dip(dect_transceiver_priv(trx));
  1903. +}
  1904. +
  1905. +static void sc1442x_confirm(const struct dect_transceiver *trx)
  1906. +{
  1907. + struct coa_device *dev = dect_transceiver_priv(trx);
  1908. +
  1909. + /*
  1910. + * This locks the firmware into a cycle where it will receive every
  1911. + * 24th slot. This must happen within the time it takes to transmit
  1912. + * 22 slots after the interrupt to lock to the correct signal.
  1913. + */
  1914. + sc1442x_lock_mem(dev);
  1915. + sc1442x_switch_to_bank(dev, SC1442X_CODEBANK);
  1916. + sc1442x_write_cmd(dev, SyncLoop, BR, SyncLock);
  1917. + sc1442x_unlock_mem(dev);
  1918. +}
  1919. +
  1920. +static void sc1442x_unlock(const struct dect_transceiver *trx)
  1921. +{
  1922. + struct coa_device *dev = dect_transceiver_priv(trx);
  1923. +
  1924. + /* Restore jump into Sync loop */
  1925. + sc1442x_lock_mem(dev);
  1926. + sc1442x_switch_to_bank(dev, SC1442X_CODEBANK);
  1927. + sc1442x_write_cmd(dev, SyncLoop, BR, Sync);
  1928. + sc1442x_write_cmd(dev, SlotTable, BR, SyncInit);
  1929. + sc1442x_unlock_mem(dev);
  1930. +}
  1931. +
  1932. +static void sc1442x_lock(const struct dect_transceiver *trx, u8 slot)
  1933. +{
  1934. + struct coa_device *dev = dect_transceiver_priv(trx);
  1935. +
  1936. + /*
  1937. + * We're receiving the single slot "slot". Adjust the firmware so it
  1938. + * will jump into the correct slottable position on the next receive
  1939. + * event. This will automagically establish the correct slot numbers
  1940. + * and thereby interrupt timing for all slots.
  1941. + */
  1942. + sc1442x_lock_mem(dev);
  1943. + sc1442x_switch_to_bank(dev, SC1442X_CODEBANK);
  1944. + sc1442x_write_cmd(dev, SlotTable, SLOTZERO, 0);
  1945. + sc1442x_write_cmd(dev, SyncLoop, BR, slottable[slot]);
  1946. + sc1442x_unlock_mem(dev);
  1947. +}
  1948. +
  1949. +static void sc1442x_write_bmc_config(const struct coa_device *dev,
  1950. + u8 slot, bool tx)
  1951. +{
  1952. + u16 off;
  1953. + u8 cfg;
  1954. +
  1955. + off = sc1442x_slot_offset(slot) + BMC_CTRL;
  1956. +
  1957. + cfg = 2 << SC1442X_BC0_S_ERR_SHIFT;
  1958. + cfg |= SC1442X_BC0_INV_TDO;
  1959. + cfg |= SC1442X_BC0_SENS_A;
  1960. + if (slot < 12 && !tx)
  1961. + cfg |= SC1442X_BC0_PP_MODE;
  1962. + sc1442x_dwriteb(dev, off + 0, cfg);
  1963. +
  1964. + /* S-field error mask */
  1965. + sc1442x_dwriteb(dev, off + 1, 0);
  1966. + /* S-field sliding window error mask */
  1967. + sc1442x_dwriteb(dev, off + 2, 0x3f);
  1968. +
  1969. + /* DAC output */
  1970. + sc1442x_dwriteb(dev, off + 3, 0);
  1971. +
  1972. + cfg = SC1442X_BC4_ADP;
  1973. + cfg |= 0xf & SC1442X_BC4_WIN_MASK;
  1974. + cfg |= 0x80;
  1975. + sc1442x_dwriteb(dev, off + 4, cfg);
  1976. +
  1977. + cfg = SC1442X_BC5_DO_FR;
  1978. + cfg |= tx ? SC1442X_BC5_TDO_DIGITAL : SC1442X_BC5_TDO_POWER_DOWN;
  1979. + sc1442x_dwriteb(dev, off + 5, cfg);
  1980. +
  1981. + /* Frame number */
  1982. + sc1442x_dwriteb(dev, off + 6, 0);
  1983. +}
  1984. +
  1985. +static void sc1442x_set_mode(const struct dect_transceiver *trx,
  1986. + const struct dect_channel_desc *chd,
  1987. + enum dect_slot_states mode)
  1988. +{
  1989. + struct coa_device *dev = dect_transceiver_priv(trx);
  1990. + bool cipher = trx->slots[chd->slot].flags & DECT_SLOT_CIPHER;
  1991. + bool sync = trx->slots[chd->slot].flags & DECT_SLOT_SYNC;
  1992. + u8 slot = chd->slot, prev = dect_slot_sub(slot, 1);
  1993. +
  1994. + sc1442x_lock_mem(dev);
  1995. + sc1442x_switch_to_bank(dev, SC1442X_CODEBANK);
  1996. +
  1997. + switch (mode) {
  1998. + case DECT_SLOT_IDLE:
  1999. + sc1442x_write_cmd(dev, slottable[prev] + 0, WT, 1);
  2000. + sc1442x_write_cmd(dev, slottable[prev] + 1, WNT, 1);
  2001. + sc1442x_write_cmd(dev, slottable[slot] + 0, WT, 1);
  2002. + sc1442x_write_cmd(dev, slottable[slot] + 1, WNT, 1);
  2003. + break;
  2004. + case DECT_SLOT_SCANNING:
  2005. + case DECT_SLOT_RX:
  2006. + sc1442x_write_cmd(dev, slottable[prev] + 0, BK_C,
  2007. + sc1442x_dip_bankaddress(slot));
  2008. + sc1442x_write_cmd(dev, slottable[prev] + 1, JMP, RFInit);
  2009. + sc1442x_write_cmd(dev, slottable[slot] + 0, WT, 1);
  2010. + sc1442x_write_cmd(dev, slottable[slot] + 1, JMP,
  2011. + sc1442x_rx_funcs[chd->pkt][chd->b_fmt][cipher][sync]);
  2012. +
  2013. + sc1442x_switch_to_bank(dev, sc1442x_slot_bank(slot));
  2014. + sc1442x_write_bmc_config(dev, slot, false);
  2015. + break;
  2016. + case DECT_SLOT_TX:
  2017. + sc1442x_write_cmd(dev, slottable[prev] + 0, BK_C,
  2018. + sc1442x_dip_bankaddress(slot));
  2019. + sc1442x_write_cmd(dev, slottable[prev] + 1, JMP, RFInit);
  2020. + sc1442x_write_cmd(dev, slottable[slot] + 0, WT, 1);
  2021. + sc1442x_write_cmd(dev, slottable[slot] + 1, JMP,
  2022. + sc1442x_tx_funcs[chd->pkt][chd->b_fmt][cipher]);
  2023. +
  2024. + sc1442x_switch_to_bank(dev, sc1442x_slot_bank(slot));
  2025. + sc1442x_write_bmc_config(dev, slot, true);
  2026. + break;
  2027. + }
  2028. + sc1442x_unlock_mem(dev);
  2029. +}
  2030. +
  2031. +static void sc1442x_set_carrier(const struct dect_transceiver *trx,
  2032. + u8 slot, u8 carrier)
  2033. +{
  2034. + const struct dect_transceiver_slot *ts = &trx->slots[slot];
  2035. + struct coa_device *dev = dect_transceiver_priv(trx);
  2036. + u16 off;
  2037. +
  2038. + WARN_ON(ts->state == DECT_SLOT_IDLE);
  2039. +
  2040. + sc1442x_lock_mem(dev);
  2041. + sc1442x_switch_to_bank(dev, sc1442x_slot_bank(slot));
  2042. + off = sc1442x_slot_offset(slot);
  2043. + dev->radio_ops->set_carrier(dev, off, ts->state, carrier);
  2044. + sc1442x_unlock_mem(dev);
  2045. +}
  2046. +
  2047. +static u64 sc1442x_set_band(const struct dect_transceiver *trx,
  2048. + const struct dect_band *band)
  2049. +{
  2050. + struct coa_device *dev = dect_transceiver_priv(trx);
  2051. +
  2052. + return dev->radio_ops->map_band(dev, band);
  2053. +}
  2054. +
  2055. +static void sc1442x_tx(const struct dect_transceiver *trx, struct sk_buff *skb)
  2056. +{
  2057. + struct coa_device *dev = dect_transceiver_priv(trx);
  2058. + const struct dect_skb_trx_cb *cb = DECT_TRX_CB(skb);
  2059. + const struct dect_transceiver_slot *ts = &trx->slots[cb->slot];
  2060. + u8 slot = cb->slot;
  2061. + u16 off;
  2062. +
  2063. + sc1442x_lock_mem(dev);
  2064. + sc1442x_switch_to_bank(dev, sc1442x_slot_bank(slot));
  2065. + off = sc1442x_slot_offset(slot);
  2066. +
  2067. + /* Duplicate first byte for transmission during ramp-up */
  2068. + sc1442x_dwriteb(dev, off + SD_PREAMBLE_OFF - 1, *skb_mac_header(skb));
  2069. + sc1442x_to_dmem(dev, off + SD_PREAMBLE_OFF,
  2070. + skb_mac_header(skb), skb->mac_len);
  2071. + sc1442x_to_dmem(dev, off + SD_DATA_OFF, skb->data, skb->len);
  2072. + sc1442x_dwriteb(dev, off + BMC_CTRL + BMC_CTRL_MFR_OFF, cb->frame);
  2073. +
  2074. + /* Init DCS for slots in the first half frame */
  2075. + if (ts->flags & DECT_SLOT_CIPHER && slot < DECT_HALF_FRAME_SIZE)
  2076. + sc1442x_dcs_init(dev, trx, slot, cb->mfn, cb->frame);
  2077. +
  2078. + sc1442x_toggle_led(dev);
  2079. + sc1442x_unlock_mem(dev);
  2080. + kfree_skb(skb);
  2081. +}
  2082. +
  2083. +const struct dect_transceiver_ops sc1442x_transceiver_ops = {
  2084. + .name = "sc1442x",
  2085. + .features = DECT_TRANSCEIVER_SLOW_HOPPING |
  2086. +#ifdef CONFIG_DECT_COA_P64
  2087. + DECT_TRANSCEIVER_PACKET_P64 |
  2088. +#endif
  2089. + 0,
  2090. + .eventrate = 6,
  2091. + .latency = 6,
  2092. + .disable = sc1442x_disable,
  2093. + .enable = sc1442x_enable,
  2094. + .confirm = sc1442x_confirm,
  2095. + .unlock = sc1442x_unlock,
  2096. + .lock = sc1442x_lock,
  2097. + .set_mode = sc1442x_set_mode,
  2098. + .set_carrier = sc1442x_set_carrier,
  2099. + .set_band = sc1442x_set_band,
  2100. + .tx = sc1442x_tx,
  2101. + .destructor = dect_transceiver_free,
  2102. +};
  2103. +EXPORT_SYMBOL_GPL(sc1442x_transceiver_ops);
  2104. +
  2105. +static u8 sc1442x_clear_interrupt(const struct coa_device *dev)
  2106. +{
  2107. + u8 int1, int2, cnt = 0;
  2108. +
  2109. + int1 = sc1442x_readb(dev, dev->cfg_reg);
  2110. + /* is the card still plugged? */
  2111. + if (int1 == 0xff)
  2112. + return 0;
  2113. +
  2114. + int2 = int1 & SC1442X_IRQ_MASK;
  2115. +
  2116. + /* Clear interrupt status before checking for any remaining events */
  2117. + if (int2 && dev->type == COA_TYPE_PCI)
  2118. + sc1442x_writeb(dev, SC14424_RESET_INT_PENDING_1, 0x80);
  2119. +
  2120. + while (int1) {
  2121. + cnt++;
  2122. + if (cnt > 254) {
  2123. + int2 = 0;
  2124. + break;
  2125. + }
  2126. +
  2127. + int1 = sc1442x_readb(dev, dev->cfg_reg) & SC1442X_IRQ_MASK;
  2128. + int2 |= int1;
  2129. + }
  2130. +
  2131. + return int2 & SC1442X_IRQ_MASK;
  2132. +}
  2133. +
  2134. +static void sc1442x_update_phase_offset(struct coa_device *dev,
  2135. + struct dect_transceiver_slot *ts,
  2136. + u8 framenum)
  2137. +{
  2138. + struct sc1442x_phase_state *ps = &dev->phase_state[ts->chd.slot / 2];
  2139. + u16 off = sc1442x_slot_offset(ts->chd.slot);
  2140. + s32 phaseoff;
  2141. + s8 phase;
  2142. + u8 tap;
  2143. +
  2144. + /* The phase offset is calculated from the differences of the tap and
  2145. + * phase status of two consequitive frames. The tap field contains
  2146. + * which of the nine internal clock cycles per symbol sampled the
  2147. + * incoming data and measures small scale frequency deviations up to
  2148. + * +-8 * 9.6ppm == +-86.4ppm. The phase field contains the absolute
  2149. + * phase offset in multiples of 87ppm.
  2150. + */
  2151. + tap = sc1442x_dreadb(dev, off + 2) >> SC1442X_ST2_TAP_SHIFT;
  2152. + phase = sc1442x_dreadb(dev, off + 3);
  2153. +
  2154. + if (dect_next_framenum(ps->framenum) == framenum) {
  2155. + phaseoff = (tap - ps->tap) * SC1442X_ST2_TAP_SCALE;
  2156. + phaseoff += (phase - ps->phase) * SC1442X_ST3_PHASE_SCALE;
  2157. +
  2158. + ts->phaseoff = dect_average_phase_offset(ts->phaseoff, phaseoff);
  2159. + }
  2160. +
  2161. + ps->framenum = framenum;
  2162. + ps->tap = tap;
  2163. + ps->phase = phase;
  2164. +}
  2165. +
  2166. +static void sc1442x_process_slot(struct coa_device *dev,
  2167. + struct dect_transceiver *trx,
  2168. + struct dect_transceiver_event *event,
  2169. + u8 slot)
  2170. +{
  2171. + struct dect_transceiver_slot *ts = &trx->slots[slot];
  2172. + struct sk_buff *skb;
  2173. + u8 status, framenum, csum, rssi;
  2174. + u32 mfn;
  2175. + u16 off;
  2176. +
  2177. + if (ts->state == DECT_SLOT_IDLE || ts->state == DECT_SLOT_TX)
  2178. + return;
  2179. +
  2180. + mfn = trx->cell->timer_base[DECT_TIMER_RX].mfn;
  2181. + framenum = trx->cell->timer_base[DECT_TIMER_RX].framenum;
  2182. +
  2183. + sc1442x_switch_to_bank(dev, sc1442x_slot_bank(slot));
  2184. + off = sc1442x_slot_offset(slot);
  2185. +
  2186. + /*
  2187. + * The SC1442X contains a 6 bit ADC for RSSI measurement, convert to
  2188. + * units used by the stack.
  2189. + */
  2190. + status = sc1442x_dreadb(dev, off + SD_RSSI_OFF);
  2191. + rssi = (status & SC1442X_ST0_ADC_MASK) * DECT_RSSI_RANGE / 63;
  2192. +
  2193. + /* validate and clear checksum */
  2194. + status = sc1442x_dreadb(dev, off + SD_CSUM_OFF);
  2195. + if (!(status & SC1442X_ST1_IN_SYNC))
  2196. + goto out;
  2197. + sc1442x_dwriteb(dev, off + SD_CSUM_OFF, 0);
  2198. +
  2199. + if (!(status & SC1442X_ST1_A_CRC)) {
  2200. + ts->rx_a_crc_errors++;
  2201. + if (ts->chd.pkt == DECT_PACKET_P00)
  2202. + goto out;
  2203. + csum = 0;
  2204. + } else
  2205. + csum = DECT_CHECKSUM_A_CRC_OK;
  2206. +
  2207. + if (ts->chd.pkt != DECT_PACKET_P00) {
  2208. + if (!(status & SC1442X_ST1_X_CRC))
  2209. + ts->rx_x_crc_errors++;
  2210. + else
  2211. + csum |= DECT_CHECKSUM_X_CRC_OK;
  2212. +
  2213. + if (!(status & SC1442X_ST1_Z_CRC))
  2214. + ts->rx_z_crc_errors++;
  2215. + else
  2216. + csum |= DECT_CHECKSUM_Z_CRC_OK;
  2217. + }
  2218. +
  2219. + /* calculate phase offset */
  2220. + sc1442x_update_phase_offset(dev, ts, framenum);
  2221. +
  2222. + skb = dect_transceiver_alloc_skb(trx, slot);
  2223. + if (skb == NULL)
  2224. + goto out;
  2225. + sc1442x_from_dmem(dev, skb->data, off + SD_DATA_OFF, skb->len);
  2226. + DECT_TRX_CB(skb)->csum = csum;
  2227. + DECT_TRX_CB(skb)->rssi = rssi;
  2228. + __skb_queue_tail(&event->rx_queue, skb);
  2229. +
  2230. + ts->rx_bytes += skb->len;
  2231. + ts->rx_packets++;
  2232. +
  2233. + sc1442x_toggle_led(dev);
  2234. +out:
  2235. + ts->rssi = dect_average_rssi(ts->rssi, rssi);
  2236. + dect_transceiver_record_rssi(event, slot, rssi);
  2237. +
  2238. + /* Update frame number for next reception */
  2239. + sc1442x_dwriteb(dev, off + BMC_CTRL + BMC_CTRL_MFR_OFF, framenum + 1);
  2240. +
  2241. + /* Init DCS for slots in the first half frame */
  2242. + if (ts->flags & DECT_SLOT_CIPHER && slot < DECT_HALF_FRAME_SIZE)
  2243. + sc1442x_dcs_init(dev, trx, slot, mfn, framenum + 1);
  2244. +}
  2245. +
  2246. +irqreturn_t sc1442x_interrupt(int irq, void *dev_id)
  2247. +{
  2248. + struct dect_transceiver *trx = dev_id;
  2249. + struct coa_device *dev = dect_transceiver_priv(trx);
  2250. + struct dect_transceiver_event *event;
  2251. + u8 slot, i;
  2252. +
  2253. + irq = sc1442x_clear_interrupt(dev);
  2254. + if (!irq)
  2255. + return IRQ_NONE;
  2256. +
  2257. + if (unlikely(hweight8(irq) != 1 && net_ratelimit()))
  2258. + dev_info(dev->dev, "lost some interrupts\n");
  2259. +
  2260. + for (i = 0; i < 4; i++) {
  2261. + if (!(irq & (1 << i)))
  2262. + continue;
  2263. +
  2264. + event = dect_transceiver_event(trx, i % 2, i * 6);
  2265. + if (event == NULL)
  2266. + goto out;
  2267. +
  2268. + spin_lock(&dev->lock);
  2269. + for (slot = 6 * i; slot < 6 * (i + 1); slot++) {
  2270. + sc1442x_process_slot(dev, trx, event, slot);
  2271. + if (slot < DECT_HALF_FRAME_SIZE)
  2272. + sc1442x_transfer_dcs_state(dev, trx, slot);
  2273. + }
  2274. + spin_unlock(&dev->lock);
  2275. +
  2276. + dect_transceiver_queue_event(trx, event);
  2277. + }
  2278. +out:
  2279. + return IRQ_HANDLED;
  2280. +}
  2281. +EXPORT_SYMBOL_GPL(sc1442x_interrupt);
  2282. +
  2283. +static void sc1442x_init_slot(const struct coa_device *dev, u8 slot)
  2284. +{
  2285. + u16 off;
  2286. +
  2287. + sc1442x_switch_to_bank(dev, sc1442x_slot_bank(slot));
  2288. + off = sc1442x_slot_offset(slot);
  2289. + dev->radio_ops->rx_init(dev, off);
  2290. + dev->radio_ops->tx_init(dev, off);
  2291. +}
  2292. +
  2293. +static int sc1442x_check_dram(const struct coa_device *dev)
  2294. +{
  2295. + unsigned int bank, i;
  2296. + unsigned int cnt;
  2297. + u16 off;
  2298. + u8 val;
  2299. +
  2300. + for (bank = 0; bank < 8; bank++) {
  2301. + sc1442x_switch_to_bank(dev, 4 * bank);
  2302. +
  2303. + off = bank * SC1442X_BANKSIZE;
  2304. + for (i = 0; i < SC1442X_BANKSIZE - 2; i++)
  2305. + sc1442x_dwriteb(dev, off + i, bank + i);
  2306. + }
  2307. +
  2308. + cnt = 0;
  2309. + for (bank = 0; bank < 8; bank++) {
  2310. + sc1442x_switch_to_bank(dev, 4 * bank);
  2311. +
  2312. + off = bank * SC1442X_BANKSIZE;
  2313. + for (i = 0; i < SC1442X_BANKSIZE - 2; i++) {
  2314. + val = sc1442x_dreadb(dev, off + i);
  2315. + if (val != ((bank + i) & 0xff)) {
  2316. + dev_err(dev->dev,
  2317. + "memory error bank %.2x offset %.2x: "
  2318. + "%.2x != %.2x\n", bank, i,
  2319. + val, (bank + i) & 0xff);
  2320. + cnt++;
  2321. + }
  2322. + sc1442x_dwriteb(dev, off + i, 0);
  2323. + }
  2324. + }
  2325. +
  2326. + if (cnt > 0)
  2327. + dev_err(dev->dev, "found %u memory r/w errors\n", cnt);
  2328. + return cnt ? -1 : 0;
  2329. +}
  2330. +
  2331. +int sc1442x_init_device(struct coa_device *dev)
  2332. +{
  2333. + unsigned int i;
  2334. + u8 slot;
  2335. +
  2336. + spin_lock_init(&dev->lock);
  2337. + dev->ctrl = SC1442X_DIPSTOPPED;
  2338. +
  2339. + if (sc1442x_check_dram(dev) < 0)
  2340. + return -EIO;
  2341. +
  2342. + dev_info(dev->dev, "Loading firmware ...\n");
  2343. + sc1442x_switch_to_bank(dev, SC1442X_CODEBANK);
  2344. + sc1442x_to_cmem(dev, sc1442x_firmware, sizeof(sc1442x_firmware));
  2345. +
  2346. + sc1442x_clear_interrupt(dev);
  2347. +
  2348. + /* Init DIP */
  2349. + sc1442x_switch_to_bank(dev, SC1442X_RAMBANK0);
  2350. +
  2351. + /* Disable Codec */
  2352. + sc1442x_dwriteb(dev, DIP_CC_INIT, SC1442X_CC0_STANDBY);
  2353. + for (i = 1; i < SC1442X_CC_SIZE; i++)
  2354. + sc1442x_dwriteb(dev, DIP_CC_INIT + i, 0);
  2355. +
  2356. + for (slot = 0; slot < DECT_FRAME_SIZE; slot += 2)
  2357. + sc1442x_init_slot(dev, slot);
  2358. +
  2359. + if (dev->type == COA_TYPE_PCI) {
  2360. + /* Enable DIP interrupt */
  2361. + sc1442x_writeb(dev, SC14424_INT_PRIORITY_1, 0x70);
  2362. + /* Enable SPI for LED control */
  2363. + sc1442x_writeb(dev, SC14424_P1_DIR_REG, 0xd6);
  2364. + }
  2365. + return 0;
  2366. +}
  2367. +EXPORT_SYMBOL_GPL(sc1442x_init_device);
  2368. +
  2369. +void sc1442x_shutdown_device(struct coa_device *dev)
  2370. +{
  2371. + sc1442x_stop_dip(dev);
  2372. +
  2373. + if (dev->type == COA_TYPE_PCI) {
  2374. + /* Clear pening interrupts */
  2375. + sc1442x_writeb(dev, SC14424_RESET_INT_PENDING_1, 0xff);
  2376. + sc1442x_writeb(dev, SC14424_RESET_INT_PENDING_2, 0xff);
  2377. + /* Reset LED */
  2378. + sc1442x_writeb(dev, SC14424_P1_RESET_OUTPUT_DATA, 0x40);
  2379. + }
  2380. +}
  2381. +EXPORT_SYMBOL_GPL(sc1442x_shutdown_device);
  2382. +
  2383. +MODULE_LICENSE("GPL");
  2384. diff --git a/drivers/dect/coa/sc1442x_firmware.asm b/drivers/dect/coa/sc1442x_firmware.asm
  2385. new file mode 100644
  2386. index 0000000..c8097f8
  2387. --- /dev/null
  2388. +++ b/drivers/dect/coa/sc1442x_firmware.asm
  2389. @@ -0,0 +1,429 @@
  2390. + CPU SC14421
  2391. + ORG 0
  2392. +
  2393. + BR Start
  2394. +
  2395. +PB_LED EQU 0x80
  2396. +PB_RX_ON EQU 0x40
  2397. +PB_TX_ON EQU 0x10
  2398. +PB_RADIOPOWER EQU 0x04
  2399. +PB_DCTHRESHOLD EQU 0x02
  2400. +PB_RSSI EQU 0x01
  2401. +
  2402. +; synchronisation control
  2403. +PSC_ARPD1 EQU 0x80
  2404. +PSC_S_SYNC EQU 0x40
  2405. +PSC_S_SYNC_ON EQU 0x20
  2406. +PSC_EOPSM EQU 0x10
  2407. +
  2408. +; memory banks 0-7, lower and upper halfs (128 bytes each)
  2409. +BANK0_LOW EQU 0x00
  2410. +BANK0_HIGH EQU 0x10
  2411. +BANK1_LOW EQU 0x20
  2412. +BANK1_HIGH EQU 0x30
  2413. +BANK2_LOW EQU 0x40
  2414. +BANK2_HIGH EQU 0x50
  2415. +BANK3_LOW EQU 0x60
  2416. +BANK3_HIGH EQU 0x70
  2417. +BANK4_LOW EQU 0x80
  2418. +BANK4_HIGH EQU 0x90
  2419. +BANK5_LOW EQU 0xa0
  2420. +BANK5_HIGH EQU 0xb0
  2421. +BANK6_LOW EQU 0xc0
  2422. +BANK6_HIGH EQU 0xd0
  2423. +BANK7_LOW EQU 0xe0
  2424. +BANK7_HIGH EQU 0xf0
  2425. +
  2426. +; Codec Control
  2427. +DIP_CC_INIT EQU 0x10
  2428. +
  2429. +; Radio configuration word
  2430. +RF_DESC EQU 0x65
  2431. +
  2432. +; BMC control information
  2433. +BMC_CTRL_SIZE EQU 7
  2434. +BMC_CTRL EQU 0x69
  2435. +
  2436. +; (multi) frame number for scambler and DCS
  2437. +BMC_CTRL_MFR_OFF EQU 6
  2438. +
  2439. +; Cipher IV/Key
  2440. +DCS_DESC EQU 0x70
  2441. +DCS_IV EQU DCS_DESC
  2442. +DCS_CK EQU DCS_DESC + 0x8
  2443. +
  2444. +; Cipher state
  2445. +DCS_STATE EQU 0x70
  2446. +DCS_STATE_SIZE EQU 11
  2447. +
  2448. +SD_PREAMBLE_OFF EQU 0x01
  2449. +SD_A_FIELD_OFF EQU 0x06
  2450. +SD_B_FIELD_OFF EQU 0x0E
  2451. +
  2452. +; status descriptor
  2453. +SD_BASE_OFF EQU 0x00
  2454. +SD_RSSI_OFF EQU 0x00
  2455. +SD_CSUM_OFF EQU 0x01
  2456. +SD_DATA_OFF EQU 0x06
  2457. +
  2458. +; U2785 radio
  2459. +U2785_CFG1_LEN EQU 24
  2460. +U2785_CFG2_LEN EQU 9
  2461. +
  2462. +;-------------------------------------------------------------
  2463. +
  2464. +Start: BR InitDIP
  2465. +;-------------------------------------------------------------
  2466. +
  2467. +SlotTable: SLOTZERO
  2468. +
  2469. +Slot00: WT 1
  2470. + WNT 1
  2471. +Slot01: WT 1
  2472. + WNT 1
  2473. +Slot02: WT 1
  2474. + WNT 1
  2475. +Slot03: WT 1
  2476. + WNT 1
  2477. +Slot04: WT 1
  2478. + WNT 1
  2479. +Slot05: WT 1
  2480. + WNT 1
  2481. + U_INT0
  2482. +
  2483. +Slot06: WT 1
  2484. + WNT 1
  2485. +Slot07: WT 1
  2486. + WNT 1
  2487. +Slot08: WT 1
  2488. + WNT 1
  2489. +Slot09: WT 1
  2490. + WNT 1
  2491. +Slot10: WT 1
  2492. + WNT 1
  2493. +Slot11: WT 1
  2494. + WNT 1
  2495. + U_INT1
  2496. +
  2497. +Slot12: WT 1
  2498. + WNT 1
  2499. +Slot13: WT 1
  2500. + WNT 1
  2501. +Slot14: WT 1
  2502. + WNT 1
  2503. +Slot15: WT 1
  2504. + WNT 1
  2505. +Slot16: WT 1
  2506. + WNT 1
  2507. +Slot17: WT 1
  2508. + WNT 1
  2509. + U_INT2
  2510. +
  2511. +Slot18: WT 1
  2512. + WNT 1
  2513. +Slot19: WT 1
  2514. + WNT 1
  2515. +Slot20: WT 1
  2516. + WNT 1
  2517. +Slot21: WT 1
  2518. + WNT 1
  2519. +Slot22: WT 1
  2520. + WNT 1
  2521. +Slot23: WT 1
  2522. + WNT 1
  2523. + U_INT3
  2524. +
  2525. + BR SlotTable
  2526. +
  2527. +;-------------------------------------------------------------------------------
  2528. +; Receive a P00 packet
  2529. +;
  2530. +RX_P00: JMP Receive ; Receive S- and beginning of A-field |
  2531. +RX_P00_End: B_BRFU SD_B_FIELD_OFF ; Receive unprotected full-slot B-field | p: 95 A: 63
  2532. + JMP ReceiveEnd ; End reception | p: 96 B: 0
  2533. + BR WriteBMC1 ;
  2534. +
  2535. +RX_P00_Sync: JMP ReceiveSync ; Receive S- and beginning of A-field |
  2536. + BR RX_P00_End
  2537. +
  2538. +; Receive a P32 packet using the the unprotected full slot B-field format in
  2539. +; the D32-field
  2540. +;
  2541. +RX_P32U_Enc: JMP LoadEncKey
  2542. +RX_P32U: JMP Receive
  2543. + B_BRFU SD_B_FIELD_OFF ; Receive unprotected full-slot B-field | p: 95 A: 63
  2544. + JMP RX_P32U_BZ ; Receive B-field | p: 96 B: 0
  2545. + BR WriteBMC2
  2546. +
  2547. +RX_P640j_Enc: JMP LoadEncKey
  2548. +RX_P640j: JMP Receive
  2549. + B_BR SD_B_FIELD_OFF
  2550. + JMP Transfer_P640j
  2551. + WT 14 ; 15 - 1 (RTN)
  2552. + B_XR
  2553. + JMP ReceiveEnd
  2554. + BR WriteBMC2
  2555. +
  2556. +;-------------------------------------------------------------------------------
  2557. +; Transmit a P00 packet
  2558. +;
  2559. +TX_P00: JMP Transmit ; Transmit S- and beginning of A-field |
  2560. + JMP TransmitEnd ; End transmission | p: 94 A: 62
  2561. + BR label_53 ;
  2562. +
  2563. +; Transmit a P32 packet using the unprotected full slot B-field format in the
  2564. +; D32-field
  2565. +;
  2566. +TX_P32U_Enc: JMP LoadEncKey
  2567. +TX_P32U: JMP Transmit ; Transmit S- and beginning of A-field |
  2568. + B_BTFU SD_B_FIELD_OFF ; Transmit unprotected full-slot B-field data | p: 95 A: 63
  2569. + JMP TX_P32U_BZ ; Transmit the B- and Z-fields | p: 96 B: 0
  2570. + BR label_54 ;
  2571. +
  2572. +TX_P640j_Enc: JMP LoadEncKey
  2573. +TX_P640j: JMP Transmit
  2574. + B_BT SD_B_FIELD_OFF
  2575. + WT 3 ; B_BT has 3 bits of latency
  2576. + JMP Transfer_P640j
  2577. + WT 11 ; 15 - 1 (RTN) - 3 (latency)
  2578. + B_XT
  2579. + WT 13 ; 8 (X/Z-Field) + 5
  2580. + B_RST
  2581. + JMP TransmitEnd
  2582. + BR label_58
  2583. +
  2584. +Transfer_B: WT 45 ; 47 - 2 (JMP/JMP, JMP/RTN)
  2585. + B_XON
  2586. + WT 15
  2587. + B_XOFF
  2588. + RTN
  2589. +
  2590. +Transfer_P640j: JMP Transfer_B
  2591. + JMP Transfer_B
  2592. + JMP Transfer_B
  2593. + JMP Transfer_B
  2594. + JMP Transfer_B
  2595. + JMP Transfer_B
  2596. + JMP Transfer_B
  2597. + JMP Transfer_B
  2598. + JMP Transfer_B
  2599. + WT 46 ; 47 - 1 (RTN)
  2600. + B_XON
  2601. + RTN
  2602. +
  2603. +;-------------------------------------------------------------------------------
  2604. +WriteBMC1: B_WRS SD_BASE_OFF ; write status
  2605. + WT 6
  2606. +
  2607. +label_53: B_RST
  2608. +label_54: P_LDL PB_RX_ON | PB_TX_ON
  2609. + WT 5
  2610. + WNT 1
  2611. + RTN
  2612. +
  2613. +;-------------------------------------------------------------------------------
  2614. +WriteBMC2: B_WRS SD_BASE_OFF ; write status
  2615. + WT 6
  2616. +label_58: B_RST
  2617. + P_LDL PB_RX_ON | PB_TX_ON
  2618. + RTN
  2619. +
  2620. +
  2621. +ReceiveInit: B_RST
  2622. + B_RC BMC_CTRL
  2623. + WT BMC_CTRL_SIZE + 1
  2624. + P_LDH PB_RX_ON
  2625. + P_LDL PB_RSSI ; enable RSSI measurement
  2626. + WT 25
  2627. + WNT 1 ; Wait until beginning of slot |
  2628. + WT 7 ; | p: -33--26
  2629. + RTN
  2630. +
  2631. +;-------------------------------------------------------------------------------
  2632. +; Enable the receiver, receive the S-field and the first 61 bits of the D-field
  2633. +; (93 bits total)
  2634. +;
  2635. +Receive: JMP ReceiveInit
  2636. + B_XON ; | p: -25
  2637. +ClockSyncOn: P_SC PSC_S_SYNC_ON ; | p: -24
  2638. + P_LDH PB_DCTHRESHOLD ; | p: -23
  2639. + WT 5 ; | p: -22--16
  2640. + B_SR ; Receive S-field | p: -17
  2641. +ClockAdjust: EN_SL_ADJ ; | p: -16 S: 0
  2642. + WT 12 ; | p: -15--4 S: 1-12
  2643. + P_LDL PB_DCTHRESHOLD ; | p: -3 S: 13
  2644. + WT 32 ; | p: -2-29 S: 14-45
  2645. +ClockSyncOff: P_SC 0x00 ; | p: 30 S: 46
  2646. + B_AR2 SD_A_FIELD_OFF ; Start reception of A-field/A-field CRC | p: 31 S: 47
  2647. + WT 62 ; Receive first 61 bits of A-field | p: 32-92 A: 0-60
  2648. + RTN ; Return | p: 93 A: 61
  2649. +
  2650. +ReceiveSync: JMP ReceiveInit
  2651. + B_XON ; | p: -25
  2652. + P_SC PSC_S_SYNC_ON ; | p: -24
  2653. + P_LDH PB_DCTHRESHOLD ; | p: -23
  2654. + WT 5 ; | p: -22--16
  2655. + B_SR ; Receive S-field | p: -17
  2656. + EN_SL_ADJ ; | p: -16 S: 0
  2657. + WT 12 ; | p: -15--4 S: 1-12
  2658. + P_LDL PB_DCTHRESHOLD ; | p: -3 S: 13
  2659. + WT 32 ; | p: -2-29 S: 14-45
  2660. + P_SC 0x00 ; | p: 30 S: 46
  2661. + B_AR2 SD_A_FIELD_OFF ; Start reception of A-field/A-field CRC | p: 31 S: 47
  2662. + WT 61 ; Receive first 61 bits of A-field | p: 32-92 A: 0-60
  2663. + RTN ; Return | p: 93 A: 61
  2664. +
  2665. +; Receive the B- and Z-fields of a P32 packet using the protected full slot
  2666. +; B-field format in the D32-field
  2667. +RX_P32U_BZ: WT 249 ; | p: 97-345 B: 1-249
  2668. + WT 79 ; | p: 346-415 B: 250-319
  2669. + ; | p: 416-419 B: 320-323 X: 0-3
  2670. + ; | p: 420-423 Z: 0- 3
  2671. + ; | p: 424 ??
  2672. +ReceiveEnd: P_LDH PB_RSSI ; |
  2673. + P_LDL PB_RX_ON
  2674. + BR SaveEncState
  2675. +;-------------------------------------------------------------------------------
  2676. +; Enable transmitter, transmit the S-field and the first 61 bits of the D-field
  2677. +; (93 bits total)
  2678. +;
  2679. +Transmit: P_LDH 0x00 ;
  2680. + WT 40 ;
  2681. + B_RST ;
  2682. + B_RC BMC_CTRL ;
  2683. + WNT 1 ; Wait until beginning of slot
  2684. + B_ST 0x00 ; Start transmission of S-field data |
  2685. + WT 1 ; Wait one bit | p: -8 S: 0
  2686. + P_LDH PB_TX_ON ; Enable transmitter | p: -7 S: 1
  2687. + WT 37 ; Transmit 29 bits S-field | p: -6-30 S: 2-38
  2688. + B_AT2 SD_A_FIELD_OFF ; Start transission of A-field data/A-field CRC | p: 31 S: 39
  2689. + WT 62 ; Transmit first 61 bits of A-field | p: 32-92 A: 0-60
  2690. + RTN ; Return | p: 93 A: 61
  2691. +
  2692. +;-------------------------------------------------------------------------------
  2693. +;
  2694. +;
  2695. +TX_P32U_BZ: WT 249 ; | p: 97-345 B: 1-249
  2696. + WT 84 ; Last bits of B-field data | p: 346-415 B: 250-319
  2697. + ; X-field | p: 416-419 B: 320-323 X: 0-3
  2698. + ; Z-field (?) | p: 420-424 Z: 0- 3
  2699. + ; 5 bits of crap? | p: 425-429
  2700. + B_RST ; Reset BMC | p: 430
  2701. +
  2702. +TransmitEnd: P_LDL PB_TX_ON ; Disable transmitter |
  2703. + WT 8 ; Wait until transmitter is disabled |
  2704. + P_LDL 0x00 ;
  2705. + BR SaveEncState
  2706. +
  2707. +;-------------------------------------------------------------------------------
  2708. +
  2709. +RFInit: RFEN ; Enable RF-clock
  2710. + WT 2
  2711. +
  2712. + MEN1N ; Transfer first radio configuration word
  2713. + M_WR RF_DESC
  2714. + WT U2785_CFG1_LEN + 1
  2715. + M_RST
  2716. + MEN1
  2717. +
  2718. + MEN1N ; Transfer second radio configuration word
  2719. + M_WR RF_DESC + U2785_CFG1_LEN / 8
  2720. + WT U2785_CFG2_LEN + 1
  2721. + M_RST
  2722. + MEN1
  2723. + ;WT 1
  2724. +
  2725. + P_LDL 0x20
  2726. + WT 10
  2727. + IFNDEF ENABLE_P64
  2728. + MEN2
  2729. + WT 182
  2730. + MEN2N
  2731. + WT 16
  2732. + ENDIF
  2733. + RTN
  2734. +;--------------------------------------------------------------
  2735. +;
  2736. +LoadEncKey: D_RST
  2737. + D_LDK DCS_DESC ; load IV (64 bits) and cipher key (64 bits)
  2738. + WT 16
  2739. + D_LDK 0
  2740. + D_PREP 0
  2741. + WT 39
  2742. + D_PREP 0
  2743. + RTN
  2744. +
  2745. +SaveEncState: D_WRS DCS_STATE
  2746. + WT DCS_STATE_SIZE ; actually should be -1, but does not work
  2747. + D_WRS 0
  2748. + D_RST
  2749. + RTN
  2750. +
  2751. +LoadEncState: D_RST
  2752. + D_LDS DCS_STATE
  2753. + WT DCS_STATE_SIZE ; actually should be -1, but does not work
  2754. + D_LDS 0
  2755. + RTN
  2756. +;-------------------------------------------------------------
  2757. +
  2758. +SyncInit: BK_C BANK1_LOW
  2759. +Sync: JMP RFInit
  2760. + WT 250
  2761. + P_SC PSC_S_SYNC_ON
  2762. + P_LDH PB_RX_ON | PB_DCTHRESHOLD
  2763. + UNLCK
  2764. + WT 64
  2765. + B_XOFF
  2766. + B_SR
  2767. + WNT 20
  2768. + JMP1 SFieldFound
  2769. + B_RST
  2770. + U_INT1
  2771. + WNT 23
  2772. + BR Sync
  2773. +;-------------------------------------------------------------
  2774. +
  2775. +SFieldFound: WNT 23
  2776. + P_SC 0x00
  2777. +SyncLock: JMP RFInit
  2778. + JMP RX_P00
  2779. + U_INT0
  2780. + WNT 22
  2781. +SyncLoop: BR Sync
  2782. +;-------------------------------------------------------------
  2783. +
  2784. +InitDIP: ;B_RST
  2785. + BK_C BANK0_LOW
  2786. + C_LD DIP_CC_INIT
  2787. + WT 10
  2788. + ;B_RC BMC_CTRL
  2789. + ;WT BMC_CTRL_SIZE + 1
  2790. + ;B_RST
  2791. + C_ON
  2792. + WT 10
  2793. + P_EN
  2794. + P_LD 0x04
  2795. + RCK_INT
  2796. + RFEN
  2797. +RFStart: BR SyncInit
  2798. +;-------------------------------------------------------------
  2799. +
  2800. + SHARED DIP_CC_INIT,RF_DESC
  2801. + SHARED BMC_CTRL,BMC_CTRL_MFR_OFF
  2802. + SHARED SD_RSSI_OFF,SD_CSUM_OFF,SD_PREAMBLE_OFF,SD_DATA_OFF
  2803. +
  2804. + SHARED SlotTable
  2805. + SHARED Slot00,Slot01,Slot02,Slot03,Slot04,Slot05,Slot06,Slot07
  2806. + SHARED Slot08,Slot09,Slot10,Slot11,Slot12,Slot13,Slot14,Slot15
  2807. + SHARED Slot16,Slot17,Slot18,Slot19,Slot20,Slot21,Slot22,Slot23
  2808. +
  2809. + SHARED RFStart,RFInit
  2810. + SHARED SyncInit,Sync,SyncLock,SyncLoop
  2811. + SHARED ClockSyncOn,ClockSyncOff,ClockAdjust
  2812. + SHARED PSC_ARPD1,PSC_S_SYNC,PSC_S_SYNC_ON,PSC_EOPSM
  2813. +
  2814. + SHARED RX_P00,RX_P00_Sync,RX_P32U,RX_P32U_Enc,RX_P640j,RX_P640j_Enc
  2815. + SHARED TX_P00,TX_P32U,TX_P32U_Enc,TX_P640j,TX_P640j_Enc
  2816. +
  2817. + SHARED DCS_IV,DCS_CK,DCS_STATE,DCS_STATE_SIZE
  2818. + SHARED LoadEncKey,LoadEncState
  2819. diff --git a/drivers/dect/coa/sc1442x_firmware.c b/drivers/dect/coa/sc1442x_firmware.c
  2820. new file mode 100644
  2821. index 0000000..d1fea60
  2822. --- /dev/null
  2823. +++ b/drivers/dect/coa/sc1442x_firmware.c
  2824. @@ -0,0 +1,73 @@
  2825. +/*
  2826. + * automatically generated file
  2827. + * DO NOT EDIT
  2828. + * edit firmware/filename.asm instead
  2829. + */
  2830. +
  2831. +#include "sc1442x_firmware.h"
  2832. +
  2833. +const unsigned char sc1442x_firmware[] = {
  2834. + 0x01, 0x01, 0x01, 0xef, 0x0d, 0x00, 0x09, 0x01,
  2835. + 0x08, 0x01, 0x09, 0x01, 0x08, 0x01, 0x09, 0x01,
  2836. + 0x08, 0x01, 0x09, 0x01, 0x08, 0x01, 0x09, 0x01,
  2837. + 0x08, 0x01, 0x09, 0x01, 0x08, 0x01, 0x61, 0x00,
  2838. + 0x09, 0x01, 0x08, 0x01, 0x09, 0x01, 0x08, 0x01,
  2839. + 0x09, 0x01, 0x08, 0x01, 0x09, 0x01, 0x08, 0x01,
  2840. + 0x09, 0x01, 0x08, 0x01, 0x09, 0x01, 0x08, 0x01,
  2841. + 0x6b, 0x00, 0x09, 0x01, 0x08, 0x01, 0x09, 0x01,
  2842. + 0x08, 0x01, 0x09, 0x01, 0x08, 0x01, 0x09, 0x01,
  2843. + 0x08, 0x01, 0x09, 0x01, 0x08, 0x01, 0x09, 0x01,
  2844. + 0x08, 0x01, 0x6d, 0x00, 0x09, 0x01, 0x08, 0x01,
  2845. + 0x09, 0x01, 0x08, 0x01, 0x09, 0x01, 0x08, 0x01,
  2846. + 0x09, 0x01, 0x08, 0x01, 0x09, 0x01, 0x08, 0x01,
  2847. + 0x09, 0x01, 0x08, 0x01, 0x6f, 0x00, 0x01, 0x02,
  2848. + 0x02, 0x84, 0x2d, 0x0e, 0x02, 0xa2, 0x01, 0x6f,
  2849. + 0x02, 0x92, 0x01, 0x39, 0x02, 0xc7, 0x02, 0x84,
  2850. + 0x2d, 0x0e, 0x02, 0xa0, 0x01, 0x76, 0x02, 0xc7,
  2851. + 0x02, 0x84, 0x3c, 0x0e, 0x02, 0x63, 0x09, 0x0e,
  2852. + 0x2b, 0x00, 0x02, 0xa2, 0x01, 0x76, 0x02, 0xa5,
  2853. + 0x02, 0xb4, 0x01, 0x71, 0x02, 0xc7, 0x02, 0xa5,
  2854. + 0x25, 0x0e, 0x02, 0xb1, 0x01, 0x72, 0x02, 0xc7,
  2855. + 0x02, 0xa5, 0x34, 0x0e, 0x09, 0x03, 0x02, 0x63,
  2856. + 0x09, 0x0b, 0x24, 0x00, 0x09, 0x0d, 0x20, 0x00,
  2857. + 0x02, 0xb4, 0x01, 0x78, 0x09, 0x2d, 0x27, 0x00,
  2858. + 0x09, 0x0f, 0x26, 0x00, 0x04, 0x00, 0x02, 0x5e,
  2859. + 0x02, 0x5e, 0x02, 0x5e, 0x02, 0x5e, 0x02, 0x5e,
  2860. + 0x02, 0x5e, 0x02, 0x5e, 0x02, 0x5e, 0x02, 0x5e,
  2861. + 0x09, 0x2e, 0x27, 0x00, 0x04, 0x00, 0x39, 0x00,
  2862. + 0x09, 0x06, 0x20, 0x00, 0xec, 0x50, 0x09, 0x05,
  2863. + 0x08, 0x01, 0x04, 0x00, 0x39, 0x00, 0x09, 0x06,
  2864. + 0x20, 0x00, 0xec, 0x50, 0x04, 0x00, 0x20, 0x00,
  2865. + 0x33, 0x69, 0x09, 0x08, 0xed, 0x40, 0xec, 0x01,
  2866. + 0x09, 0x19, 0x08, 0x01, 0x09, 0x07, 0x04, 0x00,
  2867. + 0x02, 0x7b, 0x27, 0x00, 0xea, 0x20, 0xed, 0x02,
  2868. + 0x09, 0x05, 0x29, 0x00, 0x2c, 0x00, 0x09, 0x0c,
  2869. + 0xec, 0x02, 0x09, 0x20, 0xea, 0x00, 0x3f, 0x06,
  2870. + 0x09, 0x3e, 0x04, 0x00, 0x02, 0x7b, 0x27, 0x00,
  2871. + 0xea, 0x20, 0xed, 0x02, 0x09, 0x05, 0x29, 0x00,
  2872. + 0x2c, 0x00, 0x09, 0x0c, 0xec, 0x02, 0x09, 0x20,
  2873. + 0xea, 0x00, 0x3f, 0x06, 0x09, 0x3d, 0x04, 0x00,
  2874. + 0x09, 0xf9, 0x09, 0x4f, 0xed, 0x01, 0xec, 0x40,
  2875. + 0x01, 0xcf, 0xed, 0x00, 0x09, 0x28, 0x20, 0x00,
  2876. + 0x33, 0x69, 0x08, 0x01, 0x31, 0x00, 0x09, 0x01,
  2877. + 0xed, 0x10, 0x09, 0x25, 0x37, 0x06, 0x09, 0x3e,
  2878. + 0x04, 0x00, 0x09, 0xf9, 0x09, 0x54, 0x20, 0x00,
  2879. + 0xec, 0x10, 0x09, 0x08, 0xec, 0x00, 0x01, 0xcf,
  2880. + 0x0b, 0x00, 0x09, 0x02, 0xa4, 0x00, 0xb9, 0x65,
  2881. + 0x09, 0x19, 0xa9, 0x00, 0xa5, 0x00, 0xa4, 0x00,
  2882. + 0xb9, 0x68, 0x09, 0x0a, 0xa9, 0x00, 0xa5, 0x00,
  2883. + 0xec, 0x20, 0x09, 0x0a, 0x04, 0x00, 0x40, 0x00,
  2884. + 0x50, 0x70, 0x09, 0x10, 0x50, 0x00, 0x44, 0x00,
  2885. + 0x09, 0x27, 0x44, 0x00, 0x04, 0x00, 0x5f, 0x70,
  2886. + 0x09, 0x0b, 0x5f, 0x00, 0x40, 0x00, 0x04, 0x00,
  2887. + 0x40, 0x00, 0x57, 0x70, 0x09, 0x0b, 0x57, 0x00,
  2888. + 0x04, 0x00, 0x0f, 0x20, 0x02, 0xb8, 0x09, 0xfa,
  2889. + 0xea, 0x20, 0xed, 0x42, 0x28, 0x00, 0x09, 0x40,
  2890. + 0x26, 0x00, 0x29, 0x00, 0x08, 0x14, 0x03, 0xe8,
  2891. + 0x20, 0x00, 0x6b, 0x00, 0x08, 0x17, 0x01, 0xda,
  2892. + 0x08, 0x17, 0xea, 0x00, 0x02, 0xb8, 0x02, 0x38,
  2893. + 0x61, 0x00, 0x08, 0x16, 0x01, 0xda, 0x0f, 0x00,
  2894. + 0xfa, 0x10, 0x09, 0x0a, 0xee, 0x00, 0x09, 0x0a,
  2895. + 0xe9, 0x00, 0xe8, 0x04, 0x62, 0x00, 0x0b, 0x00,
  2896. + 0x01, 0xd9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  2897. + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
  2898. diff --git a/drivers/dect/coa/sc1442x_firmware.h b/drivers/dect/coa/sc1442x_firmware.h
  2899. new file mode 100644
  2900. index 0000000..8d615bd
  2901. --- /dev/null
  2902. +++ b/drivers/dect/coa/sc1442x_firmware.h
  2903. @@ -0,0 +1,70 @@
  2904. +#ifndef SC1442X_FIRMWARE
  2905. +#define SC1442X_FIRMWARE
  2906. +
  2907. +extern const unsigned char sc1442x_firmware[510];
  2908. +
  2909. +#define DIP_CC_INIT 0x10
  2910. +#define RF_DESC 0x65
  2911. +#define BMC_CTRL 0x69
  2912. +#define BMC_CTRL_MFR_OFF 0x6
  2913. +#define SD_RSSI_OFF 0x0
  2914. +#define SD_CSUM_OFF 0x1
  2915. +#define SD_PREAMBLE_OFF 0x1
  2916. +#define SD_DATA_OFF 0x6
  2917. +#define SlotTable 0x2
  2918. +#define Slot00 0x3
  2919. +#define Slot01 0x5
  2920. +#define Slot02 0x7
  2921. +#define Slot03 0x9
  2922. +#define Slot04 0xB
  2923. +#define Slot05 0xD
  2924. +#define Slot06 0x10
  2925. +#define Slot07 0x12
  2926. +#define Slot08 0x14
  2927. +#define Slot09 0x16
  2928. +#define Slot10 0x18
  2929. +#define Slot11 0x1A
  2930. +#define Slot12 0x1D
  2931. +#define Slot13 0x1F
  2932. +#define Slot14 0x21
  2933. +#define Slot15 0x23
  2934. +#define Slot16 0x25
  2935. +#define Slot17 0x27
  2936. +#define Slot18 0x2A
  2937. +#define Slot19 0x2C
  2938. +#define Slot20 0x2E
  2939. +#define Slot21 0x30
  2940. +#define Slot22 0x32
  2941. +#define Slot23 0x34
  2942. +#define RFStart 0xF8
  2943. +#define RFInit 0xB8
  2944. +#define SyncInit 0xD9
  2945. +#define Sync 0xDA
  2946. +#define SyncLock 0xEA
  2947. +#define SyncLoop 0xEE
  2948. +#define ClockSyncOn 0x86
  2949. +#define ClockSyncOff 0x8E
  2950. +#define ClockAdjust 0x8A
  2951. +#define PSC_ARPD1 0x80
  2952. +#define PSC_S_SYNC 0x40
  2953. +#define PSC_S_SYNC_ON 0x20
  2954. +#define PSC_EOPSM 0x10
  2955. +#define RX_P00 0x38
  2956. +#define RX_P00_Sync 0x3C
  2957. +#define RX_P32U 0x3F
  2958. +#define RX_P32U_Enc 0x3E
  2959. +#define RX_P640j 0x44
  2960. +#define RX_P640j_Enc 0x43
  2961. +#define TX_P00 0x4B
  2962. +#define TX_P32U 0x4F
  2963. +#define TX_P32U_Enc 0x4E
  2964. +#define TX_P640j 0x54
  2965. +#define TX_P640j_Enc 0x53
  2966. +#define DCS_IV 0x70
  2967. +#define DCS_CK 0x78
  2968. +#define DCS_STATE 0x70
  2969. +#define DCS_STATE_SIZE 0xB
  2970. +#define LoadEncKey 0xC7
  2971. +#define LoadEncState 0xD4
  2972. +
  2973. +#endif /* SC1442X_FIRMWARE */
  2974. diff --git a/drivers/dect/vtrx/Kconfig b/drivers/dect/vtrx/Kconfig
  2975. new file mode 100644
  2976. index 0000000..fb86eee
  2977. --- /dev/null
  2978. +++ b/drivers/dect/vtrx/Kconfig
  2979. @@ -0,0 +1,5 @@
  2980. +config DECT_VTRX
  2981. + tristate "DECT virtual transceiver support"
  2982. + depends on DECT
  2983. + help
  2984. + This option enables support for the virtual DECT transceiver.
  2985. diff --git a/drivers/dect/vtrx/Makefile b/drivers/dect/vtrx/Makefile
  2986. new file mode 100644
  2987. index 0000000..08abbf5
  2988. --- /dev/null
  2989. +++ b/drivers/dect/vtrx/Makefile
  2990. @@ -0,0 +1,2 @@
  2991. +obj-$(CONFIG_DECT_VTRX) += dect-vtrx.o
  2992. +dect-vtrx-objs := vtrx.o vtrx-sysfs.o mw_to_dbm.o
  2993. diff --git a/drivers/dect/vtrx/mw_to_dbm.c b/drivers/dect/vtrx/mw_to_dbm.c
  2994. new file mode 100644
  2995. index 0000000..55122a8
  2996. --- /dev/null
  2997. +++ b/drivers/dect/vtrx/mw_to_dbm.c
  2998. @@ -0,0 +1,164 @@
  2999. +/*
  3000. + * DECT virtual transceiver
  3001. + *
  3002. + * Copyright (c) 2010 Patrick McHardy <[email protected]>
  3003. + *
  3004. + * This program is free software; you can redistribute it and/or modify
  3005. + * it under the terms of the GNU General Public License version 2 as
  3006. + * published by the Free Software Foundation.
  3007. + */
  3008. +
  3009. +#include <linux/kernel.h>
  3010. +#include <net/dect/transceiver.h>
  3011. +#include "vtrx.h"
  3012. +
  3013. +static const struct {
  3014. + u64 mw;
  3015. + int dbm;
  3016. +} mw_to_dbm_tbl[] = {
  3017. + { 5ULL, -93 },
  3018. + { 6ULL, -92 },
  3019. + { 7ULL, -91 },
  3020. + { 10ULL, -90 },
  3021. + { 12ULL, -89 },
  3022. + { 15ULL, -88 },
  3023. + { 19ULL, -87 },
  3024. + { 25ULL, -86 },
  3025. + { 31ULL, -85 },
  3026. + { 39ULL, -84 },
  3027. + { 50ULL, -83 },
  3028. + { 63ULL, -82 },
  3029. + { 79ULL, -81 },
  3030. + { 100ULL, -80 },
  3031. + { 125ULL, -79 },
  3032. + { 158ULL, -78 },
  3033. + { 199ULL, -77 },
  3034. + { 251ULL, -76 },
  3035. + { 316ULL, -75 },
  3036. + { 398ULL, -74 },
  3037. + { 501ULL, -73 },
  3038. + { 630ULL, -72 },
  3039. + { 794ULL, -71 },
  3040. + { 1000ULL, -70 },
  3041. + { 1258ULL, -69 },
  3042. + { 1584ULL, -68 },
  3043. + { 1995ULL, -67 },
  3044. + { 2511ULL, -66 },
  3045. + { 3162ULL, -65 },
  3046. + { 3981ULL, -64 },
  3047. + { 5011ULL, -63 },
  3048. + { 6309ULL, -62 },
  3049. + { 7943ULL, -61 },
  3050. + { 10000ULL, -60 },
  3051. + { 12589ULL, -59 },
  3052. + { 15848ULL, -58 },
  3053. + { 19952ULL, -57 },
  3054. + { 25118ULL, -56 },
  3055. + { 31622ULL, -55 },
  3056. + { 39810ULL, -54 },
  3057. + { 50118ULL, -53 },
  3058. + { 63095ULL, -52 },
  3059. + { 79432ULL, -51 },
  3060. + { 100000ULL, -50 },
  3061. + { 125892ULL, -49 },
  3062. + { 158489ULL, -48 },
  3063. + { 199526ULL, -47 },
  3064. + { 251188ULL, -46 },
  3065. + { 316227ULL, -45 },
  3066. + { 398107ULL, -44 },
  3067. + { 501187ULL, -43 },
  3068. + { 630957ULL, -42 },
  3069. + { 794328ULL, -41 },
  3070. + { 1000000ULL, -40 },
  3071. + { 1258925ULL, -39 },
  3072. + { 1584893ULL, -38 },
  3073. + { 1995262ULL, -37 },
  3074. + { 2511886ULL, -36 },
  3075. + { 3162277ULL, -35 },
  3076. + { 3981071ULL, -34 },
  3077. + { 5011872ULL, -33 },
  3078. + { 6309573ULL, -32 },
  3079. + { 7943282ULL, -31 },
  3080. + { 10000000ULL, -30 },
  3081. + { 12589254ULL, -29 },
  3082. + { 15848931ULL, -28 },
  3083. + { 19952623ULL, -27 },
  3084. + { 25118864ULL, -26 },
  3085. + { 31622776ULL, -25 },
  3086. + { 39810717ULL, -24 },
  3087. + { 50118723ULL, -23 },
  3088. + { 63095734ULL, -22 },
  3089. + { 79432823ULL, -21 },
  3090. + { 100000000ULL, -20 },
  3091. + { 125892541ULL, -19 },
  3092. + { 158489319ULL, -18 },
  3093. + { 199526231ULL, -17 },
  3094. + { 251188643ULL, -16 },
  3095. + { 316227766ULL, -15 },
  3096. + { 398107170ULL, -14 },
  3097. + { 501187233ULL, -13 },
  3098. + { 630957344ULL, -12 },
  3099. + { 794328234ULL, -11 },
  3100. + { 1000000000ULL, -10 },
  3101. + { 1258925411ULL, -9 },
  3102. + { 1584893192ULL, -8 },
  3103. + { 1995262314ULL, -7 },
  3104. + { 2511886431ULL, -6 },
  3105. + { 3162277660ULL, -5 },
  3106. + { 3981071705ULL, -4 },
  3107. + { 5011872336ULL, -3 },
  3108. + { 6309573444ULL, -2 },
  3109. + { 7943282347ULL, -1 },
  3110. + { 10000000000ULL, 0 },
  3111. + { 12589254117ULL, 1 },
  3112. + { 15848931924ULL, 2 },
  3113. + { 19952623149ULL, 3 },
  3114. + { 25118864315ULL, 4 },
  3115. + { 31622776601ULL, 5 },
  3116. + { 39810717055ULL, 6 },
  3117. + { 50118723362ULL, 7 },
  3118. + { 63095734448ULL, 8 },
  3119. + { 79432823472ULL, 9 },
  3120. + { 100000000000ULL, 10 },
  3121. + { 125892541179ULL, 11 },
  3122. + { 158489319246ULL, 12 },
  3123. + { 199526231496ULL, 13 },
  3124. + { 251188643150ULL, 14 },
  3125. + { 316227766016ULL, 15 },
  3126. + { 398107170553ULL, 16 },
  3127. + { 501187233627ULL, 17 },
  3128. + { 630957344480ULL, 18 },
  3129. + { 794328234724ULL, 19 },
  3130. + { 1000000000000ULL, 20 },
  3131. + { 1258925411794ULL, 21 },
  3132. + { 1584893192461ULL, 22 },
  3133. + { 1995262314968ULL, 23 },
  3134. + { 2511886431509ULL, 24 },
  3135. +};
  3136. +
  3137. +int dect_mw_to_dbm(u64 mw)
  3138. +{
  3139. + unsigned int min, max, mid;
  3140. + u64 val;
  3141. +
  3142. + min = 0;
  3143. + max = ARRAY_SIZE(mw_to_dbm_tbl) - 1;
  3144. +
  3145. + while (min < max) {
  3146. + mid = min + (max - min) / 2;
  3147. +
  3148. + val = mw_to_dbm_tbl[mid].mw;
  3149. + if (val < mw)
  3150. + min = mid + 1;
  3151. + else
  3152. + max = mid;
  3153. + }
  3154. +
  3155. + if (val > mw) {
  3156. + if (mid == 0)
  3157. + return 0;
  3158. + mid--;
  3159. + }
  3160. +
  3161. + return mw_to_dbm_tbl[mid].dbm;
  3162. +}
  3163. diff --git a/drivers/dect/vtrx/vtrx-sysfs.c b/drivers/dect/vtrx/vtrx-sysfs.c
  3164. new file mode 100644
  3165. index 0000000..c89c85a
  3166. --- /dev/null
  3167. +++ b/drivers/dect/vtrx/vtrx-sysfs.c
  3168. @@ -0,0 +1,230 @@
  3169. +/*
  3170. + * DECT virtual transceiver
  3171. + *
  3172. + * Copyright (c) 2010 Patrick McHardy <[email protected]>
  3173. + *
  3174. + * This program is free software; you can redistribute it and/or modify
  3175. + * it under the terms of the GNU General Public License version 2 as
  3176. + * published by the Free Software Foundation.
  3177. + */
  3178. +
  3179. +#include <linux/kernel.h>
  3180. +#include <linux/stat.h>
  3181. +#include <linux/export.h>
  3182. +#include <net/dect/transceiver.h>
  3183. +#include "vtrx.h"
  3184. +
  3185. +static struct class *dect_class;
  3186. +
  3187. +/*
  3188. + * Transceivers
  3189. + */
  3190. +
  3191. +#define VTRX_ATTR(_name, _mode, _show, _store) \
  3192. + struct device_attribute vtrx_attr_##_name = __ATTR(_name, _mode, _show, _store)
  3193. +
  3194. +#define VTRX_NUMERIC_ATTR(name, field, scale) \
  3195. +static ssize_t vtrx_show_##name(struct device *dev, struct device_attribute *attr, \
  3196. + char *buf) \
  3197. +{ \
  3198. + struct dect_vtrx *vtrx = dev_get_drvdata(dev); \
  3199. + return sprintf(buf, "%llu\n", \
  3200. + (unsigned long long)div64_u64(vtrx->field, scale)); \
  3201. +} \
  3202. + \
  3203. +static ssize_t vtrx_store_##name(struct device *dev, struct device_attribute *attr, \
  3204. + const char *buf, size_t count) \
  3205. +{ \
  3206. + struct dect_vtrx *vtrx = dev_get_drvdata(dev); \
  3207. + char *ptr; \
  3208. + u32 val; \
  3209. + \
  3210. + val = simple_strtoul(buf, &ptr, 10); \
  3211. + if (ptr == buf) \
  3212. + return -EINVAL; \
  3213. + vtrx->field = val * scale; \
  3214. + return count; \
  3215. +} \
  3216. +static VTRX_ATTR(name, S_IRUGO | S_IWUSR, vtrx_show_##name, vtrx_store_##name)
  3217. +
  3218. +VTRX_NUMERIC_ATTR(tx_power, tx_power, DECT_VTRX_POWER_SCALE);
  3219. +VTRX_NUMERIC_ATTR(pos_x, pos_x, 1000);
  3220. +VTRX_NUMERIC_ATTR(pos_y, pos_y, 1000);
  3221. +
  3222. +static ssize_t vtrx_store_remove(struct device *dev, struct device_attribute *attr,
  3223. + const char *buf, size_t count)
  3224. +{
  3225. + struct dect_vtrx *vtrx = dev_get_drvdata(dev);
  3226. +
  3227. + dect_vtrx_free(vtrx);
  3228. + return count;
  3229. +}
  3230. +
  3231. +static VTRX_ATTR(remove, S_IWUSR, NULL, vtrx_store_remove);
  3232. +
  3233. +static struct attribute *vtrx_attrs[] = {
  3234. + &vtrx_attr_tx_power.attr,
  3235. + &vtrx_attr_pos_x.attr,
  3236. + &vtrx_attr_pos_y.attr,
  3237. + &vtrx_attr_remove.attr,
  3238. + NULL
  3239. +};
  3240. +
  3241. +static struct attribute_group vtrx_attr_group = {
  3242. + .attrs = vtrx_attrs,
  3243. +};
  3244. +
  3245. +static const struct attribute_group *vtrx_attr_groups[] = {
  3246. + &vtrx_attr_group,
  3247. + NULL,
  3248. +};
  3249. +
  3250. +static void dect_vtrx_release(struct device *dev)
  3251. +{
  3252. + printk("%s\n", __func__);
  3253. +}
  3254. +
  3255. +static struct device_type dect_vtrx_group = {
  3256. + .name = "vtrx",
  3257. + .groups = vtrx_attr_groups,
  3258. + .release = dect_vtrx_release,
  3259. +};
  3260. +
  3261. +int dect_vtrx_register_sysfs(struct dect_vtrx *vtrx)
  3262. +{
  3263. + struct device *dev = &vtrx->dev;
  3264. +
  3265. + dev->type = &dect_vtrx_group;
  3266. + dev->class = dect_class;
  3267. + dev->parent = &vtrx->group->dev;
  3268. +
  3269. + dev_set_name(dev, "%s", vtrx->trx->name);
  3270. + dev_set_drvdata(dev, vtrx);
  3271. +
  3272. + return device_register(dev);
  3273. +}
  3274. +
  3275. +void dect_vtrx_unregister_sysfs(struct dect_vtrx *vtrx)
  3276. +{
  3277. + device_del(&vtrx->dev);
  3278. +}
  3279. +
  3280. +/*
  3281. + * Groups
  3282. + */
  3283. +
  3284. +#define GROUP_ATTR(_name, _mode, _show, _store) \
  3285. + struct device_attribute group_attr_##_name = __ATTR(_name, _mode, _show, _store)
  3286. +
  3287. +#define GROUP_SHOW(name, field, fmt) \
  3288. +static ssize_t group_show_##name(struct device *dev, struct device_attribute *attr, \
  3289. + char *buf) \
  3290. +{ \
  3291. + struct dect_vtrx_group *group = dev_get_drvdata(dev); \
  3292. + return sprintf(buf, fmt, group->field); \
  3293. +} \
  3294. + \
  3295. +static ssize_t group_store_##name(struct device *dev, struct device_attribute *attr, \
  3296. + const char *buf, size_t count) \
  3297. +{ \
  3298. + struct dect_vtrx_group *group = dev_get_drvdata(dev); \
  3299. + char *ptr; \
  3300. + u32 val; \
  3301. + \
  3302. + val = simple_strtoul(buf, &ptr, 10); \
  3303. + if (ptr == buf) \
  3304. + return -EINVAL; \
  3305. + group->field = val; \
  3306. + return count; \
  3307. +} \
  3308. +static GROUP_ATTR(name, S_IRUGO | S_IWUSR, group_show_##name, group_store_##name)
  3309. +
  3310. +static ssize_t group_store_new(struct device *dev, struct device_attribute *attr,
  3311. + const char *buf, size_t count)
  3312. +{
  3313. + struct dect_vtrx_group *group = dev_get_drvdata(dev);
  3314. + int err;
  3315. +
  3316. + err = dect_vtrx_init(group);
  3317. + return err ? err : count;
  3318. +}
  3319. +
  3320. +static GROUP_ATTR(new_trx, S_IWUSR, NULL, group_store_new);
  3321. +
  3322. +static struct attribute *group_attrs[] = {
  3323. + &group_attr_new_trx.attr,
  3324. + NULL
  3325. +};
  3326. +
  3327. +static struct attribute_group group_attr_group = {
  3328. + .attrs = group_attrs,
  3329. +};
  3330. +
  3331. +static const struct attribute_group *group_attr_groups[] = {
  3332. + &group_attr_group,
  3333. + NULL,
  3334. +};
  3335. +
  3336. +static void dect_vtrx_group_release(struct device *dev)
  3337. +{
  3338. + printk("%s\n", __func__);
  3339. +}
  3340. +
  3341. +static struct device_type dect_vtrx_group_group = {
  3342. + .name = "vtrx-group",
  3343. + .groups = group_attr_groups,
  3344. + .release = dect_vtrx_group_release,
  3345. +};
  3346. +
  3347. +int dect_vtrx_group_register_sysfs(struct dect_vtrx_group *group)
  3348. +{
  3349. + struct device *dev = &group->dev;
  3350. +
  3351. + dev->type = &dect_vtrx_group_group;
  3352. + dev->class = dect_class;
  3353. + dev->parent = NULL;
  3354. +
  3355. + dev_set_name(dev, "%s", group->name);
  3356. + dev_set_drvdata(dev, group);
  3357. +
  3358. + return device_register(dev);
  3359. +}
  3360. +
  3361. +static ssize_t store_new_group(struct class *dev, struct class_attribute *attr,
  3362. + const char *buf, size_t count)
  3363. +{
  3364. + char name[16];
  3365. +
  3366. + sscanf(buf, "%16s", name);
  3367. + if (!dect_vtrx_group_init(name))
  3368. + return -ENOMEM;
  3369. + return count;
  3370. +}
  3371. +
  3372. +static CLASS_ATTR(new_group, S_IWUSR, NULL, store_new_group);
  3373. +
  3374. +void dect_vtrx_group_unregister_sysfs(struct dect_vtrx_group *group)
  3375. +{
  3376. + device_del(&group->dev);
  3377. +}
  3378. +
  3379. +int dect_vtrx_sysfs_init(void)
  3380. +{
  3381. + int err;
  3382. +
  3383. + dect_class = class_create(THIS_MODULE, "dect");
  3384. + if (dect_class == NULL)
  3385. + return -ENOMEM;
  3386. +
  3387. + err = class_create_file(dect_class, &class_attr_new_group);
  3388. + if (err < 0)
  3389. + class_destroy(dect_class);
  3390. +
  3391. + return err;
  3392. +}
  3393. +
  3394. +void dect_vtrx_sysfs_exit(void)
  3395. +{
  3396. + class_remove_file(dect_class, &class_attr_new_group);
  3397. + class_destroy(dect_class);
  3398. +}
  3399. diff --git a/drivers/dect/vtrx/vtrx.c b/drivers/dect/vtrx/vtrx.c
  3400. new file mode 100644
  3401. index 0000000..d6a9084
  3402. --- /dev/null
  3403. +++ b/drivers/dect/vtrx/vtrx.c
  3404. @@ -0,0 +1,397 @@
  3405. +/*
  3406. + * DECT virtual transceiver
  3407. + *
  3408. + * Copyright (c) 2010 Patrick McHardy <[email protected]>
  3409. + *
  3410. + * This program is free software; you can redistribute it and/or modify
  3411. + * it under the terms of the GNU General Public License version 2 as
  3412. + * published by the Free Software Foundation.
  3413. + */
  3414. +
  3415. +#define DEBUG
  3416. +#include <linux/kernel.h>
  3417. +#include <linux/module.h>
  3418. +#include <linux/init.h>
  3419. +#include <linux/kobject.h>
  3420. +#include <linux/hrtimer.h>
  3421. +#include <linux/skbuff.h>
  3422. +#include <net/dect/transceiver.h>
  3423. +#include "vtrx.h"
  3424. +
  3425. +#define vtrx_debug(vtrx, fmt, args...) \
  3426. + pr_debug("vtrx %s: " fmt, (vtrx)->trx->name, ## args)
  3427. +
  3428. +#define DECT_SLOTS_PER_SECOND (DECT_FRAMES_PER_SECOND * DECT_FRAME_SIZE)
  3429. +#define DECT_VTRX_RATE (NSEC_PER_SEC / DECT_SLOTS_PER_SECOND)
  3430. +#define DECT_VTRX_DEFAULT_TRX 2
  3431. +
  3432. +#define DECT_WAVELEN_SCALE 13
  3433. +#define DECT_WAVELEN 160 /* mm */
  3434. +
  3435. +struct dect_skb_vtrx_cb {
  3436. + struct dect_vtrx *vtrx;
  3437. + u8 rssi;
  3438. + u8 carrier;
  3439. +};
  3440. +
  3441. +static LIST_HEAD(vtrx_groups);
  3442. +
  3443. +static inline struct dect_skb_vtrx_cb *DECT_VTRX_CB(const struct sk_buff *skb)
  3444. +{
  3445. + BUILD_BUG_ON(sizeof(struct dect_skb_vtrx_cb) > sizeof(skb->cb));
  3446. + return (struct dect_skb_vtrx_cb *)skb->cb;
  3447. +}
  3448. +
  3449. +static unsigned int dect_vtrx_distance(const struct dect_vtrx *vtrx1,
  3450. + const struct dect_vtrx *vtrx2)
  3451. +{
  3452. + int dx, dy;
  3453. +
  3454. + dx = vtrx1->pos_x - vtrx2->pos_x;
  3455. + dy = vtrx1->pos_y - vtrx2->pos_y;
  3456. +
  3457. + return int_sqrt(dx * dx + dy * dy);
  3458. +}
  3459. +
  3460. +static u8 dect_vtrx_receive_rssi(const struct dect_vtrx *rx_vtrx,
  3461. + const struct sk_buff *skb)
  3462. +{
  3463. + const struct dect_vtrx *tx_vtrx = DECT_VTRX_CB(skb)->vtrx;
  3464. + unsigned int distance;
  3465. + u64 rx_power, tmp;
  3466. + int dbm = 0;
  3467. +
  3468. + distance = dect_vtrx_distance(rx_vtrx, tx_vtrx);
  3469. + if (distance == 0)
  3470. + goto out;
  3471. +
  3472. + tmp = 1000 * (DECT_WAVELEN << DECT_WAVELEN_SCALE) / (4 * 3141 * distance);
  3473. + rx_power = (tx_vtrx->tx_power * tmp * tmp) >> (2 * DECT_WAVELEN_SCALE);
  3474. + dbm = dect_mw_to_dbm(rx_power);
  3475. +out:
  3476. + if (dbm > -33)
  3477. + dbm = -33;
  3478. +
  3479. + return dect_dbm_to_rssi(dbm);
  3480. +}
  3481. +
  3482. +static void dect_vtrx_process_slot(struct dect_vtrx_group *group,
  3483. + struct dect_vtrx *vtrx)
  3484. +{
  3485. + struct dect_transceiver_event *event;
  3486. + struct dect_transceiver_slot *ts;
  3487. + struct dect_transceiver *trx = vtrx->trx;
  3488. + struct sk_buff *skb, *best;
  3489. + u8 slot = group->slot, rcvslot;
  3490. + u8 rssi, best_rssi = 0;
  3491. +
  3492. + event = dect_transceiver_event(trx, slot % 12, slot);
  3493. + if (event == NULL)
  3494. + return;
  3495. +
  3496. + if (trx->state == DECT_TRANSCEIVER_UNLOCKED ||
  3497. + trx->state == DECT_TRANSCEIVER_LOCK_PENDING)
  3498. + rcvslot = DECT_SCAN_SLOT;
  3499. + else
  3500. + rcvslot = slot;
  3501. +
  3502. + rssi = dect_dbm_to_rssi(-80);
  3503. + best = NULL;
  3504. +
  3505. + ts = &trx->slots[rcvslot];
  3506. + if (ts->state != DECT_SLOT_RX &&
  3507. + ts->state != DECT_SLOT_SCANNING)
  3508. + goto queue;
  3509. +
  3510. + skb_queue_walk(&group->txq[slot], skb) {
  3511. + if (DECT_VTRX_CB(skb)->carrier != ts->chd.carrier)
  3512. + continue;
  3513. +
  3514. + rssi = dect_vtrx_receive_rssi(vtrx, skb);
  3515. + if (best == NULL || rssi > best_rssi) {
  3516. + best = skb;
  3517. + best_rssi = rssi;
  3518. + }
  3519. + }
  3520. +
  3521. + if (best == NULL)
  3522. + goto rssi;
  3523. + rssi = best_rssi;
  3524. +
  3525. + skb = skb_clone(best, GFP_ATOMIC);
  3526. + if (skb == NULL)
  3527. + goto rssi;
  3528. +
  3529. + DECT_TRX_CB(skb)->trx = trx;
  3530. + DECT_TRX_CB(skb)->slot = rcvslot;
  3531. + DECT_TRX_CB(skb)->csum = DECT_CHECKSUM_A_CRC_OK | DECT_CHECKSUM_X_CRC_OK;
  3532. + DECT_TRX_CB(skb)->rssi = rssi;
  3533. + __skb_queue_tail(&event->rx_queue, skb);
  3534. +
  3535. + ts->rx_bytes += skb->len;
  3536. + ts->rx_packets++;
  3537. +rssi:
  3538. + ts->rssi = dect_average_rssi(ts->rssi, rssi);
  3539. + dect_transceiver_record_rssi(event, rcvslot, rssi);
  3540. +queue:
  3541. + if (rcvslot != slot && best == NULL)
  3542. + dect_release_transceiver_event(event);
  3543. + else
  3544. + dect_transceiver_queue_event(trx, event);
  3545. +}
  3546. +
  3547. +static enum hrtimer_restart dect_vtrx_timer(struct hrtimer *timer)
  3548. +{
  3549. + struct dect_vtrx_group *group = container_of(timer, struct dect_vtrx_group, timer);
  3550. + struct dect_vtrx *vtrx;
  3551. + ktime_t time;
  3552. +
  3553. + list_for_each_entry(vtrx, &group->act_list, list)
  3554. + dect_vtrx_process_slot(group, vtrx);
  3555. +
  3556. + skb_queue_purge(&group->txq[group->slot]);
  3557. + group->slot = dect_next_slotnum(group->slot);
  3558. +
  3559. + time = ktime_set(0, DECT_VTRX_RATE);
  3560. + hrtimer_forward(timer, hrtimer_cb_get_time(timer), time);
  3561. +
  3562. + return HRTIMER_RESTART;
  3563. +}
  3564. +
  3565. +/*
  3566. + * Transceiver operations
  3567. + */
  3568. +
  3569. +static void dect_vtrx_enable(const struct dect_transceiver *trx)
  3570. +{
  3571. + struct dect_vtrx *vtrx = dect_transceiver_priv(trx);
  3572. + struct dect_vtrx_group *group = vtrx->group;
  3573. + ktime_t time;
  3574. +
  3575. + vtrx_debug(vtrx, "enable");
  3576. + if (list_empty(&group->act_list)) {
  3577. + time = ktime_set(0, DECT_VTRX_RATE);
  3578. + hrtimer_start(&group->timer, time, HRTIMER_MODE_ABS);
  3579. + }
  3580. + list_move_tail(&vtrx->list, &group->act_list);
  3581. +}
  3582. +
  3583. +static void dect_vtrx_disable(const struct dect_transceiver *trx)
  3584. +{
  3585. + struct dect_vtrx *vtrx = dect_transceiver_priv(trx);
  3586. + struct dect_vtrx_group *group = vtrx->group;
  3587. +
  3588. + vtrx_debug(vtrx, "disable");
  3589. + list_move_tail(&vtrx->list, &group->trx_list);
  3590. + if (list_empty(&group->act_list))
  3591. + hrtimer_cancel(&group->timer);
  3592. +}
  3593. +
  3594. +static void dect_vtrx_confirm(const struct dect_transceiver *trx)
  3595. +{
  3596. + struct dect_vtrx *vtrx = dect_transceiver_priv(trx);
  3597. +
  3598. + vtrx_debug(vtrx, "confirm");
  3599. +}
  3600. +
  3601. +static void dect_vtrx_unlock(const struct dect_transceiver *trx)
  3602. +{
  3603. + struct dect_vtrx *vtrx = dect_transceiver_priv(trx);
  3604. +
  3605. + vtrx_debug(vtrx, "unlock");
  3606. +}
  3607. +
  3608. +static void dect_vtrx_lock(const struct dect_transceiver *trx, u8 slot)
  3609. +{
  3610. + struct dect_vtrx *vtrx = dect_transceiver_priv(trx);
  3611. +
  3612. + vtrx_debug(vtrx, "lock");
  3613. +}
  3614. +
  3615. +static void dect_vtrx_set_mode(const struct dect_transceiver *trx,
  3616. + const struct dect_channel_desc *chd,
  3617. + enum dect_slot_states mode)
  3618. +{
  3619. + struct dect_vtrx *vtrx = dect_transceiver_priv(trx);
  3620. +
  3621. + vtrx_debug(vtrx, "set_mode: slot: %u mode: %u",
  3622. + chd->slot, mode);
  3623. +}
  3624. +
  3625. +static void dect_vtrx_set_carrier(const struct dect_transceiver *trx,
  3626. + u8 slot, u8 carrier)
  3627. +{
  3628. + struct dect_vtrx *vtrx = dect_transceiver_priv(trx);
  3629. +
  3630. + vtrx_debug(vtrx, "set carrier: slot: %u carrier: %u\n",
  3631. + slot, carrier);
  3632. +}
  3633. +
  3634. +static u64 dect_vtrx_set_band(const struct dect_transceiver *trx,
  3635. + const struct dect_band *band)
  3636. +{
  3637. + struct dect_vtrx *vtrx = dect_transceiver_priv(trx);
  3638. +
  3639. + vtrx_debug(vtrx, "set band: %u\n", band->band);
  3640. + return band->carriers;
  3641. +}
  3642. +
  3643. +static void dect_vtrx_tx(const struct dect_transceiver *trx, struct sk_buff *skb)
  3644. +{
  3645. + struct dect_vtrx *vtrx = dect_transceiver_priv(trx);
  3646. + struct dect_vtrx_group *group = vtrx->group;
  3647. + u8 slot = DECT_TRX_CB(skb)->slot;
  3648. +
  3649. + vtrx_debug(vtrx, "vtrx tx: slot: %u skb: %p\n", slot, skb);
  3650. + DECT_VTRX_CB(skb)->vtrx = vtrx;
  3651. + DECT_VTRX_CB(skb)->rssi = vtrx->tx_power;
  3652. + DECT_VTRX_CB(skb)->carrier = trx->slots[slot].chd.carrier;
  3653. + skb_queue_tail(&group->txq[slot], skb);
  3654. +}
  3655. +
  3656. +static const struct dect_transceiver_ops vtrx_transceiver_ops = {
  3657. + .name = "vtrx",
  3658. + .eventrate = 1,
  3659. + .latency = 1,
  3660. + .enable = dect_vtrx_enable,
  3661. + .disable = dect_vtrx_disable,
  3662. + .confirm = dect_vtrx_confirm,
  3663. + .unlock = dect_vtrx_unlock,
  3664. + .lock = dect_vtrx_lock,
  3665. + .set_mode = dect_vtrx_set_mode,
  3666. + .set_carrier = dect_vtrx_set_carrier,
  3667. + .set_band = dect_vtrx_set_band,
  3668. + .tx = dect_vtrx_tx,
  3669. + .destructor = dect_transceiver_free,
  3670. +};
  3671. +
  3672. +int dect_vtrx_init(struct dect_vtrx_group *group)
  3673. +{
  3674. + struct dect_transceiver *trx;
  3675. + struct dect_vtrx *vtrx;
  3676. + int err;
  3677. +
  3678. + trx = dect_transceiver_alloc(&vtrx_transceiver_ops, sizeof(*vtrx));
  3679. + if (trx == NULL)
  3680. + return -ENOMEM;
  3681. +
  3682. + err = dect_register_transceiver(trx);
  3683. + if (err < 0)
  3684. + goto err1;
  3685. +
  3686. + vtrx = dect_transceiver_priv(trx);
  3687. + vtrx->group = group;
  3688. + vtrx->trx = trx;
  3689. + vtrx->tx_power = 2 * DECT_VTRX_POWER_SCALE;
  3690. + list_add_tail(&vtrx->list, &group->trx_list);
  3691. +
  3692. + dect_vtrx_register_sysfs(vtrx);
  3693. + return 0;
  3694. +
  3695. +err1:
  3696. + dect_transceiver_free(trx);
  3697. + return err;
  3698. +}
  3699. +
  3700. +void dect_vtrx_free(struct dect_vtrx *vtrx)
  3701. +{
  3702. + dect_vtrx_unregister_sysfs(vtrx);
  3703. + dect_unregister_transceiver(vtrx->trx);
  3704. +}
  3705. +
  3706. +struct dect_vtrx_group *dect_vtrx_group_init(const char *name)
  3707. +{
  3708. + struct dect_vtrx_group *group;
  3709. + unsigned int i;
  3710. + int err;
  3711. +
  3712. + group = kzalloc(sizeof(*group), GFP_KERNEL);
  3713. + if (group == NULL)
  3714. + goto err1;
  3715. +
  3716. + strlcpy(group->name, name, sizeof(group->name));
  3717. + INIT_LIST_HEAD(&group->trx_list);
  3718. + INIT_LIST_HEAD(&group->act_list);
  3719. + hrtimer_init(&group->timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
  3720. + group->timer.function = dect_vtrx_timer;
  3721. +
  3722. + for (i = 0; i < ARRAY_SIZE(group->txq); i++)
  3723. + skb_queue_head_init(&group->txq[i]);
  3724. +
  3725. + err = dect_vtrx_group_register_sysfs(group);
  3726. + if (err < 0)
  3727. + goto err2;
  3728. +
  3729. + list_add_tail(&group->list, &vtrx_groups);
  3730. + return group;
  3731. +
  3732. +err2:
  3733. + kfree(group);
  3734. +err1:
  3735. + return NULL;
  3736. +}
  3737. +
  3738. +void dect_vtrx_group_free(struct dect_vtrx_group *group)
  3739. +{
  3740. + struct dect_vtrx *vtrx, *next;
  3741. + unsigned int i;
  3742. +
  3743. + list_for_each_entry_safe(vtrx, next, &group->act_list, list)
  3744. + dect_vtrx_free(vtrx);
  3745. + list_for_each_entry_safe(vtrx, next, &group->trx_list, list)
  3746. + dect_vtrx_free(vtrx);
  3747. +
  3748. + dect_vtrx_group_unregister_sysfs(group);
  3749. +
  3750. + for (i = 0; i < ARRAY_SIZE(group->txq); i++)
  3751. + __skb_queue_purge(&group->txq[i]);
  3752. +
  3753. + kfree(group);
  3754. +}
  3755. +
  3756. +static int __init vtrx_init(void)
  3757. +{
  3758. + struct dect_vtrx_group *group;
  3759. + unsigned int i;
  3760. + int err;
  3761. +
  3762. + err = dect_vtrx_sysfs_init();
  3763. + if (err < 0)
  3764. + goto err1;
  3765. +
  3766. + group = dect_vtrx_group_init("group-1");
  3767. + if (group == NULL) {
  3768. + err = -ENOMEM;
  3769. + goto err2;
  3770. + }
  3771. +
  3772. + for (i = 0; i < DECT_VTRX_DEFAULT_TRX; i++) {
  3773. + err = dect_vtrx_init(group);
  3774. + if (err < 0)
  3775. + goto err3;
  3776. + }
  3777. +
  3778. + return 0;
  3779. +
  3780. +err3:
  3781. + dect_vtrx_group_free(group);
  3782. +err2:
  3783. + dect_vtrx_sysfs_exit();
  3784. +err1:
  3785. + return err;
  3786. +}
  3787. +
  3788. +static void __exit vtrx_exit(void)
  3789. +{
  3790. + struct dect_vtrx_group *group, *next;
  3791. +
  3792. + list_for_each_entry_safe(group, next, &vtrx_groups, list)
  3793. + dect_vtrx_group_free(group);
  3794. +
  3795. + dect_vtrx_sysfs_exit();
  3796. +}
  3797. +
  3798. +module_init(vtrx_init);
  3799. +module_exit(vtrx_exit);
  3800. +
  3801. +MODULE_LICENSE("GPL");
  3802. diff --git a/drivers/dect/vtrx/vtrx.h b/drivers/dect/vtrx/vtrx.h
  3803. new file mode 100644
  3804. index 0000000..67aaba6
  3805. --- /dev/null
  3806. +++ b/drivers/dect/vtrx/vtrx.h
  3807. @@ -0,0 +1,42 @@
  3808. +#ifndef _DECT_VTRX_H
  3809. +#define _DECT_VTRX_H
  3810. +
  3811. +struct dect_vtrx_group {
  3812. + struct list_head list;
  3813. + struct device dev;
  3814. + char name[16];
  3815. + struct hrtimer timer;
  3816. + struct list_head trx_list;
  3817. + struct list_head act_list;
  3818. + struct sk_buff_head txq[DECT_FRAME_SIZE];
  3819. + unsigned int slot;
  3820. +};
  3821. +
  3822. +struct dect_vtrx {
  3823. + struct list_head list;
  3824. + struct device dev;
  3825. + struct dect_vtrx_group *group;
  3826. + struct dect_transceiver *trx;
  3827. + u64 tx_power;
  3828. + unsigned int pos_x;
  3829. + unsigned int pos_y;
  3830. +};
  3831. +
  3832. +extern struct dect_vtrx_group *dect_vtrx_group_init(const char *name);
  3833. +extern void dect_vtrx_group_free(struct dect_vtrx_group *group);
  3834. +extern int dect_vtrx_group_register_sysfs(struct dect_vtrx_group *group);
  3835. +extern void dect_vtrx_group_unregister_sysfs(struct dect_vtrx_group *group);
  3836. +
  3837. +extern int dect_vtrx_register_sysfs(struct dect_vtrx *vtrx);
  3838. +extern void dect_vtrx_unregister_sysfs(struct dect_vtrx *vtrx);
  3839. +extern int dect_vtrx_init(struct dect_vtrx_group *group);
  3840. +extern void dect_vtrx_free(struct dect_vtrx *vtrx);
  3841. +
  3842. +extern int dect_vtrx_sysfs_init(void);
  3843. +extern void dect_vtrx_sysfs_exit(void);
  3844. +
  3845. +#define DECT_VTRX_POWER_SCALE 10000000000ULL
  3846. +
  3847. +extern int dect_mw_to_dbm(u64 mw);
  3848. +
  3849. +#endif /* _DECT_VTRX_H */
  3850. diff --git a/include/linux/netlink.h b/include/linux/netlink.h
  3851. index da14ab6..18eed27 100644
  3852. --- a/include/linux/netlink.h
  3853. +++ b/include/linux/netlink.h
  3854. @@ -1,7 +1,6 @@
  3855. #ifndef __LINUX_NETLINK_H
  3856. #define __LINUX_NETLINK_H
  3857. -
  3858. #include <linux/capability.h>
  3859. #include <linux/skbuff.h>
  3860. #include <linux/export.h>
  3861. diff --git a/include/linux/socket.h b/include/linux/socket.h
  3862. index b5cc5a6..5b3b3c3 100644
  3863. --- a/include/linux/socket.h
  3864. +++ b/include/linux/socket.h
  3865. @@ -203,7 +203,8 @@ struct ucred {
  3866. #define AF_KCM 41 /* Kernel Connection Multiplexor*/
  3867. #define AF_QIPCRTR 42 /* Qualcomm IPC Router */
  3868. -#define AF_MAX 43 /* For now.. */
  3869. +#define AF_DECT 43 /* DECT sockets*/
  3870. +#define AF_MAX 44 /* For now.. */
  3871. /* Protocol families, same as address families. */
  3872. #define PF_UNSPEC AF_UNSPEC
  3873. @@ -251,6 +252,7 @@ struct ucred {
  3874. #define PF_VSOCK AF_VSOCK
  3875. #define PF_KCM AF_KCM
  3876. #define PF_QIPCRTR AF_QIPCRTR
  3877. +#define PF_DECT AF_DECT
  3878. #define PF_MAX AF_MAX
  3879. /* Maximum queue length specifiable by listen. */
  3880. @@ -329,6 +331,7 @@ struct ucred {
  3881. #define SOL_ALG 279
  3882. #define SOL_NFC 280
  3883. #define SOL_KCM 281
  3884. +#define SOL_DECT 282
  3885. /* IPX options */
  3886. #define IPX_TYPE 1
  3887. diff --git a/include/net/dect/ccp.h b/include/net/dect/ccp.h
  3888. new file mode 100644
  3889. index 0000000..5234c7d
  3890. --- /dev/null
  3891. +++ b/include/net/dect/ccp.h
  3892. @@ -0,0 +1,110 @@
  3893. +/*
  3894. + * DECT MAC Layer - Cell Control Protocol (CCP)
  3895. + *
  3896. + * Copyright (c) 2009 Patrick McHardy <[email protected]>
  3897. + */
  3898. +
  3899. +#ifndef _NET_DECT_CCP
  3900. +#define _NET_DECT_CCP
  3901. +
  3902. +#define DECT_CCP_TIPC_TYPE TIPC_RESERVED_TYPES
  3903. +#define DECT_CCP_CELL_PORT 1000
  3904. +#define DECT_CCP_CLUSTER_PORT_BASE 1000
  3905. +
  3906. +enum dect_ccp_primitives {
  3907. + /* CCF -> CSF */
  3908. + DECT_CCP_SET_MODE,
  3909. + DECT_CCP_SCAN,
  3910. + DECT_CCP_ENABLE,
  3911. + DECT_CCP_PRELOAD,
  3912. + DECT_CCP_MAC_INFO_IND,
  3913. + DECT_CCP_PAGE_REQ,
  3914. + DECT_CCP_TBC_ESTABLISH_REQ,
  3915. + DECT_CCP_TBC_ESTABLISH_RES,
  3916. + DECT_CCP_TBC_DATA_REQ,
  3917. + DECT_CCP_TBC_DIS_REQ,
  3918. + DECT_CCP_TBC_ENC_KEY_REQ,
  3919. + DECT_CCP_TBC_ENC_EKS_REQ,
  3920. + /* CSF -> CCF */
  3921. + DECT_CCP_TBC_ESTABLISH_IND,
  3922. + DECT_CCP_TBC_ESTABLISH_CFM,
  3923. + DECT_CCP_TBC_EVENT_IND,
  3924. + DECT_CCP_TBC_DATA_IND,
  3925. + DECT_CCP_TBC_DIS_IND,
  3926. +};
  3927. +
  3928. +struct dect_ccp_msg_hdr {
  3929. + u8 primitive;
  3930. +} __attribute__((packed));
  3931. +
  3932. +struct dect_ccp_ari {
  3933. + __be64 ari;
  3934. +};
  3935. +
  3936. +struct dect_ccp_mode_msg {
  3937. + u8 mode;
  3938. +} __attribute__((packed));
  3939. +
  3940. +struct dect_ccp_scan_msg {
  3941. + __be64 ari;
  3942. + __be64 ari_mask;
  3943. +} __attribute__((packed));
  3944. +
  3945. +struct dect_ccp_sysinfo_msg {
  3946. + __be64 pari;
  3947. + __be64 sari[DECT_SARI_CYCLE_MAX];
  3948. + __be64 fpc;
  3949. + __be64 hlc;
  3950. + __be64 efpc;
  3951. + __be32 mfn;
  3952. + u8 num_saris;
  3953. + u8 rpn;
  3954. +} __attribute__((packed));
  3955. +
  3956. +struct dect_ccp_page_msg {
  3957. + u8 fast_page;
  3958. + u8 long_page;
  3959. +} __attribute__((packed));
  3960. +
  3961. +struct dect_ccp_tbc_msg {
  3962. + __be32 tbei;
  3963. + __be32 pmid;
  3964. + __be64 ari;
  3965. + u8 ecn;
  3966. + u8 data;
  3967. +} __attribute__((packed));
  3968. +
  3969. +struct dect_ccp_enc_key_msg {
  3970. + __be64 key;
  3971. +} __attribute__((packed));
  3972. +
  3973. +struct dect_ccp_data_msg {
  3974. + u8 channel;
  3975. + u8 data[];
  3976. +} __attribute__((packed));
  3977. +
  3978. +#ifdef CONFIG_DECT_CCP
  3979. +extern int dect_ccp_cluster_init(struct dect_cluster *cl);
  3980. +extern void dect_ccp_cluster_shutdown(struct dect_cluster *cl);
  3981. +
  3982. +extern struct dect_cluster_handle *dect_ccp_cell_init(struct dect_cell *cell,
  3983. + u8 clindex);
  3984. +#else
  3985. +static inline int dect_ccp_cluster_init(struct dect_cluster *cl)
  3986. +{
  3987. + return 0;
  3988. +}
  3989. +
  3990. +static inline void dect_ccp_cluster_shutdown(struct dect_cluster *cl)
  3991. +{
  3992. + return;
  3993. +}
  3994. +
  3995. +static inline struct dect_cluster_handle *
  3996. +dect_ccp_cell_init(struct dect_cell *cell, u8 clindex)
  3997. +{
  3998. + return ERR_PTR(-EOPNOTSUPP);
  3999. +}
  4000. +#endif
  4001. +
  4002. +#endif /* _NET_DECT_CPP */
  4003. diff --git a/include/net/dect/dect.h b/include/net/dect/dect.h
  4004. new file mode 100644
  4005. index 0000000..5e245c8
  4006. --- /dev/null
  4007. +++ b/include/net/dect/dect.h
  4008. @@ -0,0 +1,319 @@
  4009. +#ifndef _NET_DECT_DECT_H
  4010. +#define _NET_DECT_DECT_H
  4011. +
  4012. +#define DECT_FRAMES_PER_MULTIFRAME 16
  4013. +
  4014. +static inline u8 dect_next_framenum(u8 framenum)
  4015. +{
  4016. + if (++framenum == DECT_FRAMES_PER_MULTIFRAME)
  4017. + framenum = 0;
  4018. + return framenum;
  4019. +}
  4020. +
  4021. +static inline u8 dect_framenum_add(u8 f1, u8 f2)
  4022. +{
  4023. + return (f1 + f2) % DECT_FRAMES_PER_MULTIFRAME;
  4024. +}
  4025. +
  4026. +#define DECT_MULTIFRAME_MASK 0x00ffffff
  4027. +
  4028. +static inline u32 dect_next_mfn(u32 mfn)
  4029. +{
  4030. + if (++mfn == (1 << 24) - 1)
  4031. + mfn = 0;
  4032. + return mfn;
  4033. +}
  4034. +
  4035. +static inline u32 dect_mfn_add(u32 mfn1, u32 mfn2)
  4036. +{
  4037. + return (mfn1 + mfn2) & DECT_MULTIFRAME_MASK;
  4038. +}
  4039. +
  4040. +/* Compare multiframe numbers, considering overflows */
  4041. +static inline bool dect_mfn_before(u32 mfn1, u32 mfn2)
  4042. +{
  4043. + return (s32)((mfn2 << 8) - (mfn1 << 8)) > 0;
  4044. +}
  4045. +
  4046. +static inline bool dect_mfn_after(u32 mfn1, u32 mfn2)
  4047. +{
  4048. + return dect_mfn_before(mfn2, mfn1);
  4049. +}
  4050. +
  4051. +#include <linux/list.h>
  4052. +
  4053. +/**
  4054. + * enum dect_timer_bases - timer bases for DECT timers
  4055. + *
  4056. + * @DECT_TIMER_RX: receive time base
  4057. + * @DECT_TIMER_TX: send time base
  4058. + */
  4059. +enum dect_timer_bases {
  4060. + DECT_TIMER_RX,
  4061. + DECT_TIMER_TX,
  4062. + __DECT_TIMER_BASE_MAX
  4063. +};
  4064. +#define DECT_TIMER_BASE_MAX (__DECT_TIMER_BASE_MAX - 1)
  4065. +
  4066. +/**
  4067. + * struct dect_timer_base - timer base
  4068. + *
  4069. + * @timers: list of active timers
  4070. + * @slot: slot position
  4071. + * @framenum: frame number
  4072. + * @mfn: multiframe number
  4073. + */
  4074. +struct dect_timer_base {
  4075. + struct list_head timers;
  4076. + u8 base;
  4077. + u8 slot;
  4078. + u8 framenum;
  4079. + u32 mfn;
  4080. +};
  4081. +
  4082. +static inline void dect_timer_base_init(struct dect_timer_base base[],
  4083. + enum dect_timer_bases b)
  4084. +{
  4085. + INIT_LIST_HEAD(&base[b].timers);
  4086. + base->base = b;
  4087. +}
  4088. +
  4089. +static inline u8 __dect_slotnum(const struct dect_timer_base *base)
  4090. +{
  4091. + return base->slot;
  4092. +}
  4093. +
  4094. +static inline u8 __dect_framenum(const struct dect_timer_base *base)
  4095. +{
  4096. + return base->framenum;
  4097. +}
  4098. +
  4099. +static inline u32 __dect_mfn(const struct dect_timer_base *base)
  4100. +{
  4101. + return base->mfn;
  4102. +}
  4103. +
  4104. +extern void __dect_run_timers(const char *name, struct dect_timer_base *base);
  4105. +
  4106. +/**
  4107. + * struct dect_timer - DECT TDMA frame timer
  4108. + *
  4109. + * @list: timer list node
  4110. + * @base: timer base
  4111. + * @mfn: expiration time: multiframe number
  4112. + * @frame: expiration time: frame number
  4113. + * @slot: expiration time: slot number
  4114. + * @func: timer function
  4115. + * @data: timer data
  4116. + */
  4117. +struct dect_cell;
  4118. +struct dect_cluster;
  4119. +
  4120. +struct dect_timer {
  4121. + struct list_head list;
  4122. +
  4123. + enum dect_timer_bases base;
  4124. + u32 mfn;
  4125. + u8 frame;
  4126. + u8 slot;
  4127. +
  4128. + union {
  4129. + void (*cell)(struct dect_cell *, void *);
  4130. + void (*cluster)(struct dect_cluster *, void *);
  4131. + void (*cb)(void *, void *);
  4132. + } cb;
  4133. + union {
  4134. + struct dect_cell *cell;
  4135. + struct dect_cluster *cluster;
  4136. + void *obj;
  4137. + };
  4138. + void *data;
  4139. +};
  4140. +
  4141. +static inline void dect_timer_init(struct dect_timer *timer)
  4142. +{
  4143. + INIT_LIST_HEAD(&timer->list);
  4144. +}
  4145. +
  4146. +static inline void dect_timer_del(struct dect_timer *timer)
  4147. +{
  4148. + list_del_init(&timer->list);
  4149. +}
  4150. +
  4151. +extern void __dect_timer_add(const char *name, struct dect_timer_base *base,
  4152. + struct dect_timer *timer, u32 frame, u8 slot);
  4153. +
  4154. +#include <linux/dect.h>
  4155. +#include <net/dect/identities.h>
  4156. +#include <net/dect/mac_ccf.h>
  4157. +#include <net/dect/dlc.h>
  4158. +
  4159. +extern void __acquires(dect_cfg_mutex) dect_lock(void);
  4160. +extern void __releases(dect_cfg_mutex) dect_unlock(void);
  4161. +
  4162. +/**
  4163. + * struct dect_cluster - DECT cluster of up to 8/256 cells
  4164. + *
  4165. + * @list: device list node
  4166. + * @name: device identifier
  4167. + * @index: unique numeric cluster identifier
  4168. + * @mode: device mode (FP/PP/monitor)
  4169. + * @pari: primary access rights identifier
  4170. + * @si: system information
  4171. + * @bmc: Broadcast Message Control
  4172. + * @cmc: Connectionless Message Control
  4173. + * @mbcs: Multi-Bearer Controllers
  4174. + * @cells: DECT cells
  4175. + */
  4176. +struct dect_cluster {
  4177. + struct list_head list;
  4178. + char name[DECTNAMSIZ];
  4179. + int index;
  4180. +
  4181. + u32 tipc_id;
  4182. + u32 tipc_portref;
  4183. + struct dect_cluster_handle handle;
  4184. +
  4185. + enum dect_cluster_modes mode;
  4186. +
  4187. + spinlock_t lock;
  4188. +
  4189. + struct dect_ari pari;
  4190. + struct dect_si si;
  4191. + u8 rpn;
  4192. +
  4193. + u32 pmid;
  4194. +
  4195. + struct list_head cells;
  4196. + struct dect_bmc bmc;
  4197. + struct dect_cmc cmc;
  4198. + struct list_head mbcs;
  4199. +
  4200. + u32 mcei_rover;
  4201. + struct list_head mac_connections;
  4202. +
  4203. + struct dect_timer_base timer_base[DECT_TIMER_BASE_MAX + 1];
  4204. +};
  4205. +
  4206. +extern struct list_head dect_cluster_list;
  4207. +extern struct dect_cluster *dect_cluster_get_by_index(int index);
  4208. +
  4209. +struct dect_netlink_handler {
  4210. + int (*doit)(const struct sk_buff *, const struct nlmsghdr *,
  4211. + const struct nlattr *[]);
  4212. + int (*dump)(struct sk_buff *, struct netlink_callback *);
  4213. + int (*done)(struct netlink_callback *);
  4214. + const struct nla_policy *policy;
  4215. + unsigned int maxtype;
  4216. +};
  4217. +
  4218. +extern void dect_netlink_register_handlers(const struct dect_netlink_handler *handler,
  4219. + unsigned int base, unsigned int n);
  4220. +extern void dect_netlink_unregister_handlers(unsigned int base, unsigned int n);
  4221. +
  4222. +extern struct sock *dect_nlsk;
  4223. +
  4224. +/**
  4225. + * struct dect_llme_req - LLME netlink request
  4226. + *
  4227. + * @nlh: netlink header
  4228. + * @nlportid: netlink socket port id
  4229. + */
  4230. +struct dect_llme_req {
  4231. + struct nlmsghdr nlh;
  4232. + u32 nlportid;
  4233. +};
  4234. +
  4235. +#include <net/sock.h>
  4236. +
  4237. +extern const struct proto_ops dect_stream_ops;
  4238. +extern const struct proto_ops dect_dgram_ops;
  4239. +
  4240. +struct dect_proto {
  4241. + unsigned int type;
  4242. + unsigned int protocol;
  4243. + int capability;
  4244. + const struct proto_ops *ops;
  4245. + int (*getname)(struct sock *sk,
  4246. + struct sockaddr *uaddr, int *len,
  4247. + int peer);
  4248. + struct proto proto;
  4249. +};
  4250. +
  4251. +#include <net/tcp_states.h>
  4252. +
  4253. +enum {
  4254. + DECT_SK_ESTABLISHED = TCP_ESTABLISHED,
  4255. + DECT_SK_ESTABLISH_PENDING = TCP_SYN_SENT,
  4256. + DECT_SK_RELEASED = TCP_CLOSE,
  4257. + DECT_SK_RELEASE_PENDING = TCP_CLOSING,
  4258. + DECT_SK_LISTEN = TCP_LISTEN,
  4259. +};
  4260. +
  4261. +struct dect_csk {
  4262. + struct sock sk;
  4263. + struct hlist_head accept_queue;
  4264. +};
  4265. +
  4266. +static inline struct dect_csk *dect_csk(const struct sock *sk)
  4267. +{
  4268. + return (struct dect_csk *)sk;
  4269. +}
  4270. +
  4271. +extern int dect_proto_register(struct dect_proto *proto);
  4272. +extern void dect_proto_unregister(struct dect_proto *proto);
  4273. +
  4274. +struct dect_skb_sk_cb {
  4275. + //struct dect_skb_trx_cb cb;
  4276. + int index;
  4277. +};
  4278. +
  4279. +#define DECT_SK_CB(skb) ((struct dect_skb_sk_cb *)(skb)->cb)
  4280. +
  4281. +static inline int dect_sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
  4282. +{
  4283. + /*
  4284. + * Release the transceiver reference, it is only valid in IRQ and
  4285. + * softirq context.
  4286. + */
  4287. + //FIXME
  4288. + //DECT_SK_CB(skb)->index = DECT_CB(skb)->trx->dev->index;
  4289. + return sock_queue_rcv_skb(sk, skb);
  4290. +}
  4291. +
  4292. +struct dect_notification {
  4293. + u32 type;
  4294. +};
  4295. +
  4296. +#define DECT_NOTIFY_CB(skb) ((struct dect_notification *)(skb)->cb)
  4297. +
  4298. +extern struct sk_buff *dect_alloc_notification(u32 type, const void *data,
  4299. + unsigned int size);
  4300. +
  4301. +extern void (*dect_raw_rcv_hook)(struct sk_buff *skb);
  4302. +static inline void dect_raw_rcv(struct sk_buff *skb)
  4303. +{
  4304. + typeof(dect_raw_rcv_hook) dect_raw_rcv;
  4305. +
  4306. + rcu_read_lock();
  4307. + dect_raw_rcv = dect_raw_rcv_hook;
  4308. + if (dect_raw_rcv != NULL)
  4309. + dect_raw_rcv(skb);
  4310. + rcu_read_unlock();
  4311. +}
  4312. +
  4313. +extern int dect_af_module_init(void);
  4314. +extern void dect_af_module_exit(void);
  4315. +
  4316. +extern int dect_bsap_module_init(void);
  4317. +extern void dect_bsap_module_exit(void);
  4318. +extern int dect_ssap_module_init(void);
  4319. +extern void dect_ssap_module_exit(void);
  4320. +
  4321. +extern int dect_netlink_module_init(void);
  4322. +extern void dect_netlink_module_exit(void);
  4323. +
  4324. +extern struct sk_buff *skb_append_frag(struct sk_buff *head, struct sk_buff *skb);
  4325. +extern unsigned int skb_queue_pull(struct sk_buff_head *list, unsigned int len);
  4326. +
  4327. +#endif /* _NET_DECT_DECT_H */
  4328. diff --git a/include/net/dect/dlc.h b/include/net/dect/dlc.h
  4329. new file mode 100644
  4330. index 0000000..84d442c
  4331. --- /dev/null
  4332. +++ b/include/net/dect/dlc.h
  4333. @@ -0,0 +1,463 @@
  4334. +/*
  4335. + * DECT DLC Layer
  4336. + *
  4337. + * Copyright (c) 2009 Patrick McHardy <[email protected]>
  4338. + */
  4339. +
  4340. +#ifndef _NET_DECT_DLC_H
  4341. +#define _NET_DECT_DLC_H
  4342. +
  4343. +#include <linux/timer.h>
  4344. +
  4345. +/*
  4346. + * C-Plane data link service
  4347. + */
  4348. +
  4349. +/*
  4350. + * FA-Frame
  4351. + */
  4352. +
  4353. +#define DECT_FA_HDR_SIZE 3
  4354. +
  4355. +struct dect_fa_hdr {
  4356. + u8 addr;
  4357. + u8 ctrl;
  4358. + u8 li;
  4359. +};
  4360. +
  4361. +/*
  4362. + * Address field
  4363. + */
  4364. +
  4365. +#define DECT_FA_ADDR_OFF 0
  4366. +
  4367. +/* New link flag */
  4368. +#define DECT_FA_ADDR_NLF_FLAG 0x80
  4369. +
  4370. +/* Logical Link Number */
  4371. +#define DECT_FA_ADDR_LLN_MASK 0x70
  4372. +#define DECT_FA_ADDR_LLN_SHIFT 4
  4373. +
  4374. +/* Service Access Point Identifier */
  4375. +#define DECT_FA_ADDR_SAPI_MASK 0x0c
  4376. +#define DECT_FA_ADDR_SAPI_SHIFT 2
  4377. +
  4378. +/* Command/Response flag */
  4379. +#define DECT_FA_ADDR_CR_FLAG 0x02
  4380. +
  4381. +/* Reserved bit */
  4382. +#define DECT_FA_ADDR_RES_BIT 0x01
  4383. +
  4384. +/*
  4385. + * Control field
  4386. + */
  4387. +
  4388. +#define DECT_FA_CTRL_OFF 1
  4389. +
  4390. +/*
  4391. + * I-Format: numbered information
  4392. + */
  4393. +
  4394. +#define DECT_FA_CTRL_I_FMT_MASK 0x01
  4395. +#define DECT_FA_CTRL_I_FMT_ID 0x00
  4396. +
  4397. +/* Receive sequence number */
  4398. +#define DECT_FA_CTRL_I_NR_MASK 0xe0
  4399. +#define DECT_FA_CTRL_I_NR_SHIFT 5
  4400. +
  4401. +/* Poll bit */
  4402. +#define DECT_FA_CTRL_I_P_FLAG 0x10
  4403. +
  4404. +/* Send sequence number */
  4405. +#define DECT_FA_CTRL_I_NS_MASK 0x0e
  4406. +#define DECT_FA_CTRL_I_NS_SHIFT 1
  4407. +
  4408. +/* Command */
  4409. +#define DECT_FA_CTRL_I_CMD_I (0x0)
  4410. +
  4411. +/*
  4412. + * S-Format: supervisory functions
  4413. + */
  4414. +
  4415. +#define DECT_FA_CTRL_S_FMT_MASK 0x03
  4416. +#define DECT_FA_CTRL_S_FMT_ID 0x01
  4417. +
  4418. +/* Receive sequence number */
  4419. +#define DECT_FA_CTRL_S_NR_MASK 0xe0
  4420. +#define DECT_FA_CTRL_S_NR_SHIFT 5
  4421. +
  4422. +/* Poll/final bit */
  4423. +#define DECT_FA_CTRL_S_PF_FLAG 0x10
  4424. +
  4425. +/* Command/Response */
  4426. +#define DECT_FA_CTRL_S_CR_MASK 0x0c
  4427. +
  4428. +#define DECT_FA_CTRL_S_CR_RR 0x00
  4429. +#define DECT_FA_CTRL_S_CR_RNR 0x40
  4430. +#define DECT_FA_CTRL_S_CR_REJ 0x80
  4431. +
  4432. +/*
  4433. + * U-Format: unnumbered information
  4434. + */
  4435. +
  4436. +#define DECT_FA_CTRL_U_FMT_MASK 0x03
  4437. +#define DECT_FA_CTRL_U_FMT_ID 0x03
  4438. +
  4439. +/* Unnumbered function bits */
  4440. +#define DECT_FA_CTRL_U_U1_MASK 0xec
  4441. +
  4442. +/* Poll/final bit */
  4443. +#define DECT_FA_CTRL_U_PF_FLAG 0x10
  4444. +
  4445. +/* Command/Response */
  4446. +#define DECT_FA_CTRL_U_CR_MASK 0xef
  4447. +
  4448. +#define DECT_FA_CTRL_U_CR_SABM 0x2c
  4449. +#define DECT_FA_CTRL_U_CR_DM 0x0c
  4450. +#define DECT_FA_CTRL_U_CR_UI 0x00
  4451. +#define DECT_FA_CTRL_U_CR_DISC 0x40
  4452. +#define DECT_FA_CTRL_U_CR_UA 0x60
  4453. +
  4454. +/*
  4455. + * Length Indicator
  4456. + */
  4457. +
  4458. +#define DECT_FA_LI_OFF 2
  4459. +
  4460. +/* Length (octets) */
  4461. +#define DECT_FA_LI_LENGTH_MASK 0xfc
  4462. +#define DECT_FA_LI_LENGTH_SHIFT 2
  4463. +
  4464. +/* More data flag */
  4465. +#define DECT_FA_LI_M_FLAG 0x02
  4466. +
  4467. +/* Extended length indicator bit */
  4468. +#define DECT_FA_LI_EXT_FLAG 0x01
  4469. +
  4470. +/* maximum length value */
  4471. +#define DECT_FA_LI_MAX 63
  4472. +
  4473. +/*
  4474. + * Extended Length indicator
  4475. + */
  4476. +
  4477. +#define DECT_FA_ELI_OFF 3
  4478. +
  4479. +/* Length (octets) */
  4480. +#define DECT_FA_ELI_LENGTH_MASK 0xfc
  4481. +#define DECT_FA_ELI_LENGTH_SHIFT 2
  4482. +
  4483. +struct dect_fa_len {
  4484. + u8 len;
  4485. + bool more;
  4486. +};
  4487. +
  4488. +/*
  4489. + * Fill Field
  4490. + */
  4491. +
  4492. +#define DECT_FA_FILL_PATTERN 0xf0
  4493. +
  4494. +/*
  4495. + * Checksum field
  4496. + */
  4497. +
  4498. +#define DECT_FA_CSUM_SIZE 2
  4499. +
  4500. +/*
  4501. + * Information field
  4502. + */
  4503. +
  4504. +#define DECT_FA_I_MAX (DECT_FA_LI_MAX - DECT_FA_HDR_SIZE - DECT_FA_CSUM_SIZE)
  4505. +
  4506. +
  4507. +/**
  4508. + * struct dect_dli - DECT Data Link Identifier (DLI)
  4509. + *
  4510. + * @lln: Logical Link Number
  4511. + * @mci: Mac Connection Identifier
  4512. + */
  4513. +struct dect_dli {
  4514. + enum dect_llns lln;
  4515. + struct dect_mci mci;
  4516. +};
  4517. +
  4518. +/**
  4519. + * @DECT_LAPC_ULI: unassigned link identifier state (class U/A)
  4520. + * @DECT_LAPC_ALI: assigned link identifier state (class B established)
  4521. + * @DECT_LAPC_ASM: assigned Link Identifier/multiple frame state (class B suspended)
  4522. + */
  4523. +enum dect_lapc_states {
  4524. + DECT_LAPC_ULI,
  4525. + DECT_LAPC_ALI,
  4526. + DECT_LAPC_ASM,
  4527. +};
  4528. +
  4529. +/**
  4530. + * struct dect_lapc - DECT LAPC entity
  4531. + *
  4532. + * @lc: Associated Lc entity
  4533. + * @dli: Data Link Identifier
  4534. + * @sapi: Service Access Point Identifier
  4535. + * @cmd: CR bit setting for commands (PT: 1, FT: 0)
  4536. + * @nlf: New link flag
  4537. + * @v_s: Send state Variable V(S): sequence number of next I-frame
  4538. + * @v_a: Acknowledge state Variable V(A): last I-frame that has been acknowledged
  4539. + * @v_r: Receive state Variable V(R): next expected sequence number
  4540. + * busy: LAPC is in receiver busy condition
  4541. + * @peer_busy: Peer is in receiver busy condition
  4542. + * @window: maximum number of oustanding unacknowledged I-frames
  4543. + * @mod: modulus for sequence number calculations
  4544. + * @retransmit_cnt: Retransmission counter
  4545. + * @retransmit_queue: Retransmission queue
  4546. + * @timer: Retransmission timer (DL.04)
  4547. + */
  4548. +struct dect_lapc {
  4549. + struct sock *sk;
  4550. + struct dect_lc *lc;
  4551. + struct dect_dli dli;
  4552. + enum dect_sapis sapi;
  4553. +
  4554. + bool cmd;
  4555. +
  4556. + enum dect_lapc_states state;
  4557. + bool nlf;
  4558. + u8 v_s;
  4559. + u8 v_a;
  4560. + u8 v_r;
  4561. +
  4562. + bool busy;
  4563. + bool peer_busy;
  4564. +
  4565. + u8 window;
  4566. + u8 mod;
  4567. +
  4568. + u8 retransmit_cnt;
  4569. + struct sk_buff_head retransmit_queue;
  4570. + struct timer_list timer;
  4571. +
  4572. + struct sk_buff *rcv_head;
  4573. +};
  4574. +
  4575. +/* class A window size and sequence number modulus */
  4576. +#define DECT_LAPC_CLASS_A_WINDOW 1
  4577. +#define DECT_LAPC_CLASS_A_MOD 2
  4578. +
  4579. +/* class B window size and sequence number modulus */
  4580. +#define DECT_LAPC_CLASS_B_INITIAL_WINDOW 1
  4581. +#define DECT_LAPC_CLASS_B_WINDOW 3
  4582. +#define DECT_LAPC_CLASS_B_MOD 8
  4583. +
  4584. +/* maximum number of retransmissions */
  4585. +#define DECT_LAPC_RETRANSMIT_MAX 3
  4586. +
  4587. +/* various timer parameters specified in Annex A */
  4588. +#define DECT_LAPC_CLASS_A_ESTABLISH_TIMEOUT (2 * HZ)
  4589. +#define DECT_LAPC_CLASS_B_ESTABLISH_TIMEOUT (2 * HZ)
  4590. +#define DECT_LAPC_RETRANSMISSION_TIMEOUT (1 * HZ)
  4591. +#define DECT_LAPC_LINK_RELEASE_TIMEOUT (2 * HZ)
  4592. +#define DECT_LAPC_LINK_SUSPEND_TIMEOUT (2 * HZ)
  4593. +#define DECT_LAPC_LINK_RESUME_TIMEOUT (2 * HZ)
  4594. +#define DECT_LAPC_CONNECTION_HANDOVER_TIMEOUT (10 * HZ)
  4595. +#define DECT_LAPC_CONNECTION_HANDOVER_INTERVAL (4 * HZ)
  4596. +
  4597. +extern struct dect_lapc *dect_lapc_init(struct sock *sk, const struct dect_dli *dli,
  4598. + enum dect_sapis sapi, struct dect_lc *lc,
  4599. + gfp_t gfp);
  4600. +extern void dect_lapc_destroy(struct dect_lapc *lapc);
  4601. +
  4602. +extern int dect_lapc_establish(struct dect_lapc *lapc);
  4603. +extern void dect_lapc_release(struct dect_lapc *lapc, bool normal);
  4604. +extern int dect_lapc_transmit(struct dect_lapc *lapc);
  4605. +
  4606. +extern struct dect_lapc *dect_ssap_rcv_request(struct dect_lc *lc,
  4607. + const struct dect_dli *dli,
  4608. + enum dect_sapis sapi);
  4609. +
  4610. +/**
  4611. + * struct dect_lc - DECT Lc entity
  4612. + *
  4613. + * @mc: MAC connection
  4614. + * @lsig: link signature for checksumming (lower 16 bits of PMID or 0)
  4615. + * @rx_head: reassembly queue head
  4616. + * @rx_len: target length of current reassembly buffer
  4617. + * @txq: transmit queue
  4618. + * @tx_head: current TX LAPC frame
  4619. + * @tx_len: TX target fragment length
  4620. + * @use: usage count
  4621. + * @lapcs: LAPC entities associated with the Lc
  4622. + * @e_lapc: LAPC performing establishment procedures
  4623. + *
  4624. + * The Lc entity is responsible for framing, logical channel selection and
  4625. + * fragmenting of LAPC PDUs. There is one Lc entity per MAC connection.
  4626. + */
  4627. +struct dect_lc {
  4628. + struct dect_mac_conn *mc;
  4629. + u16 lsig;
  4630. +
  4631. + struct sk_buff *rx_head;
  4632. + u8 rx_len;
  4633. +
  4634. + struct sk_buff_head txq;
  4635. + struct sk_buff *tx_head;
  4636. + u8 tx_len;
  4637. +
  4638. + u8 use;
  4639. + struct dect_lapc *lapcs[DECT_LLN_UNASSIGNED + 1];
  4640. + struct dect_lapc *elapc;
  4641. +};
  4642. +
  4643. +#define DECT_LC_LSIG_MASK 0xffff
  4644. +
  4645. +extern struct dect_lc *dect_lc_init(struct dect_mac_conn *mc, gfp_t gfp);
  4646. +extern void dect_lc_destroy(struct dect_lc *lc);
  4647. +
  4648. +extern void dect_lc_bind(struct dect_lc *lc, struct dect_lapc *lapc);
  4649. +extern void dect_lc_unbind(struct dect_lc *lc, struct dect_lapc *lapc);
  4650. +
  4651. +/**
  4652. + * struct dect_lb - DECT Lb entity (C-plane broadcast service)
  4653. + *
  4654. + *
  4655. + */
  4656. +struct dect_lb {
  4657. +};
  4658. +
  4659. +#define DECT_LB_SHORT_FRAME_SIZE 3
  4660. +#define DECT_LB_LONG_FRAME_SIZE 5
  4661. +#define DECT_LB_EXTENDED_FRAME_SIZE_MAX (6 * DECT_LB_LONG_FRAME_SIZE)
  4662. +
  4663. +#include <net/sock.h>
  4664. +
  4665. +/**
  4666. + * struct dect_dlc_fbx_ops - DLC U-plane lower (FBx) entity ops
  4667. + *
  4668. + */
  4669. +struct dect_fbx;
  4670. +struct dect_fbx_ops {
  4671. + struct sk_buff *(*dequeue)(struct dect_fbx *fbx);
  4672. + void (*enqueue)(struct dect_fbx *fbx,
  4673. + struct sk_buff *skb);
  4674. +};
  4675. +
  4676. +struct dect_fbx {
  4677. + const struct dect_fbx_ops *ops;
  4678. +};
  4679. +
  4680. +extern const struct dect_fbx_ops dect_fbn_ops;
  4681. +
  4682. +struct dect_lux;
  4683. +struct dect_lux_ops {
  4684. + struct sk_buff *(*dequeue)(struct dect_lux *lux);
  4685. + void (*enqueue)(struct dect_lux *lux,
  4686. + struct sk_buff *skb);
  4687. + void (*disconnect)(struct dect_lux *lux);
  4688. +};
  4689. +
  4690. +/**
  4691. + * struct dect_lux - DLC U-plane upper (LUx) entity
  4692. + *
  4693. + * @fpx: FBx entity
  4694. + */
  4695. +struct dect_lux {
  4696. + const struct dect_lux_ops *ops;
  4697. + struct dect_fbx fbx;
  4698. +};
  4699. +
  4700. +/**
  4701. + * dect_mac_connection_states - DECT MAC connection states as viewed by the DLC
  4702. + *
  4703. + * @DECT_MAC_CONN_CLOSED:
  4704. + * @DECT_MAC_CONN_OPEN_PENDING:
  4705. + * @DECT_MAC_CONN_OPEN:
  4706. + */
  4707. +enum dect_mac_conn_states {
  4708. + DECT_MAC_CONN_CLOSED,
  4709. + DECT_MAC_CONN_OPEN_PENDING,
  4710. + DECT_MAC_CONN_OPEN,
  4711. +};
  4712. +
  4713. +/**
  4714. + * struct dect_mac_conn - DECT MAC connection as viewed by the DLC
  4715. + *
  4716. + * @list: Cluster connection list node
  4717. + * @cl: Cluster
  4718. + * @mcei: MAC Connection Endpoint Identification
  4719. + * @mci: MAC Connection Identifier (BMCI or AMCI)
  4720. + * @state: Connection state
  4721. + * @service: Service offered by the connection
  4722. + * @ck: cipher key
  4723. + */
  4724. +struct dect_mac_conn {
  4725. + struct list_head list;
  4726. + struct dect_cluster *cl;
  4727. +
  4728. + u32 mcei;
  4729. + struct dect_mci mci;
  4730. + struct dect_mac_conn_params mcp;
  4731. + enum dect_mac_conn_states state;
  4732. + u64 ck;
  4733. +
  4734. + u8 use;
  4735. + struct dect_lc *lc;
  4736. + struct dect_fbx *fbx;
  4737. +};
  4738. +
  4739. +extern struct dect_mac_conn *dect_mac_conn_init(struct dect_cluster *cl,
  4740. + const struct dect_mci *mci,
  4741. + const struct dect_mbc_id *id);
  4742. +extern void dect_dlc_mac_conn_destroy(struct dect_mac_conn *mc);
  4743. +extern struct dect_mac_conn *dect_mac_conn_get_by_mci(const struct dect_cluster *cl,
  4744. + const struct dect_mci *mci);
  4745. +
  4746. +extern void dect_dlc_mac_conn_bind(struct dect_mac_conn *mc);
  4747. +extern void dect_dlc_mac_conn_unbind(struct dect_mac_conn *mc);
  4748. +extern int dect_dlc_mac_conn_establish(struct dect_mac_conn *mc,
  4749. + const struct dect_mac_conn_params *mcp);
  4750. +
  4751. +extern int dect_mac_con_cfm(struct dect_cluster *cl, u32 mcei,
  4752. + const struct dect_mac_conn_params *mcp);
  4753. +extern int dect_mac_con_ind(struct dect_cluster *cl,
  4754. + const struct dect_mbc_id *id,
  4755. + const struct dect_mac_conn_params *mcp);
  4756. +
  4757. +extern int dect_dlc_mac_conn_enc_key_req(struct dect_mac_conn *mc, u64 key);
  4758. +extern int dect_dlc_mac_conn_enc_eks_req(struct dect_mac_conn *mc,
  4759. + enum dect_cipher_states status);
  4760. +extern void dect_mac_enc_eks_cfm(struct dect_cluster *cl, u32 mcei,
  4761. + enum dect_cipher_states status);
  4762. +extern void dect_mac_enc_eks_ind(struct dect_cluster *cl, u32 mcei,
  4763. + enum dect_cipher_states status);
  4764. +
  4765. +extern void dect_dlc_mac_dis_req(struct dect_mac_conn *mc);
  4766. +extern int dect_mac_dis_ind(struct dect_cluster *cl, u32 mcei,
  4767. + enum dect_release_reasons reason);
  4768. +
  4769. +extern void dect_cplane_notify_state_change(struct dect_mac_conn *mc);
  4770. +extern void dect_cplane_mac_dis_ind(const struct dect_mac_conn *mc,
  4771. + enum dect_release_reasons reason);
  4772. +extern void dect_cplane_mac_enc_eks_ind(const struct dect_mac_conn *mc,
  4773. + enum dect_cipher_states status);
  4774. +
  4775. +extern void dect_cplane_rcv(struct dect_mac_conn *mc,
  4776. + enum dect_data_channels chan,
  4777. + struct sk_buff *skb);
  4778. +extern struct sk_buff *dect_cplane_dtr(struct dect_mac_conn *mc,
  4779. + enum dect_data_channels chan);
  4780. +
  4781. +extern void dect_uplane_rcv(struct dect_mac_conn *mc,
  4782. + enum dect_data_channels chan,
  4783. + struct sk_buff *skb);
  4784. +extern struct sk_buff *dect_uplane_dtr(struct dect_mac_conn *mc,
  4785. + enum dect_data_channels chan);
  4786. +
  4787. +extern void dect_mac_co_data_ind(struct dect_cluster *cl, u32 mcei,
  4788. + enum dect_data_channels chan,
  4789. + struct sk_buff *skb);
  4790. +extern struct sk_buff *dect_mac_co_dtr_ind(struct dect_cluster *cl, u32 mcei,
  4791. + enum dect_data_channels chan);
  4792. +
  4793. +extern void dect_bsap_rcv(const struct dect_cluster *cl, struct sk_buff *skb);
  4794. +extern void dect_mac_page_ind(struct dect_cluster *cl, struct sk_buff *skb);
  4795. +
  4796. +#endif /* _NET_DECT_DLC_H */
  4797. diff --git a/include/net/dect/dsc.h b/include/net/dect/dsc.h
  4798. new file mode 100644
  4799. index 0000000..423a646
  4800. --- /dev/null
  4801. +++ b/include/net/dect/dsc.h
  4802. @@ -0,0 +1,12 @@
  4803. +#ifndef _NET_DECT_DSC_H
  4804. +#define _NET_DECT_DSC_H
  4805. +
  4806. +static inline __le64 dect_dsc_iv(u32 mfn, u8 framenum)
  4807. +{
  4808. + return cpu_to_le64((mfn << 4) + framenum);
  4809. +}
  4810. +
  4811. +extern void dect_dsc_keystream(uint64_t iv, const uint8_t *key,
  4812. + uint8_t *output, unsigned int len);
  4813. +
  4814. +#endif /* _NET_DECT_DSC_H */
  4815. diff --git a/include/net/dect/identities.h b/include/net/dect/identities.h
  4816. new file mode 100644
  4817. index 0000000..a924d35
  4818. --- /dev/null
  4819. +++ b/include/net/dect/identities.h
  4820. @@ -0,0 +1,194 @@
  4821. +#ifndef _NET_DECT_IDENTITIES_H
  4822. +#define _NET_DECT_IDENTITIES_H
  4823. +
  4824. +/*
  4825. + * Acess Rights Identity (ARI)
  4826. + */
  4827. +
  4828. +#define DECT_ARI_ARC_MASK 0xe000000000000000ULL
  4829. +#define DECT_ARI_ARC_SHIFT 61
  4830. +
  4831. +/* Class A */
  4832. +#define DECT_ARI_A_EMC_MASK 0x1fffe00000000000ULL
  4833. +#define DECT_ARI_A_EMC_SHIFT 45
  4834. +
  4835. +#define DECT_ARI_A_FPN_MASK 0x00001ffff0000000ULL
  4836. +#define DECT_ARI_A_FPN_SHIFT 28
  4837. +
  4838. +/* Class B */
  4839. +#define DECT_ARI_B_EIC_MASK 0x1fffe00000000000ULL
  4840. +#define DECT_ARI_B_EIC_SHIFT 45
  4841. +
  4842. +#define DECT_ARI_B_FPN_MASK 0x00001fe000000000ULL
  4843. +#define DECT_ARI_B_FPN_SHIFT 37
  4844. +
  4845. +#define DECT_ARI_B_FPS_MASK 0x0000001e00000000ULL
  4846. +#define DECT_ARI_B_FPS_SHIFT 33
  4847. +
  4848. +/* Class C */
  4849. +#define DECT_ARI_C_POC_MASK 0x1fffe00000000000ULL
  4850. +#define DECT_ARI_C_POC_SHIFT 45
  4851. +
  4852. +#define DECT_ARI_C_FPN_MASK 0x00001fe000000000ULL
  4853. +#define DECT_ARI_C_FPN_SHIFT 37
  4854. +
  4855. +#define DECT_ARI_C_FPS_MASK 0x0000001e00000000ULL
  4856. +#define DECT_ARI_C_FPS_SHIFT 33
  4857. +
  4858. +/* Class D */
  4859. +#define DECT_ARI_D_GOP_MASK 0x1ffffe0000000000ULL
  4860. +#define DECT_ARI_D_GOP_SHIFT 41
  4861. +
  4862. +#define DECT_ARI_D_FPN_MASK 0x000001fe00000000ULL
  4863. +#define DECT_ARI_D_FPN_SHIFT 33
  4864. +
  4865. +/* Class E */
  4866. +#define DECT_ARI_E_FIL_MASK 0x1fffe00000000000ULL
  4867. +#define DECT_ARI_E_FIL_SHIFT 45
  4868. +
  4869. +#define DECT_ARI_E_FPN_MASK 0x00001ffe00000000ULL
  4870. +#define DECT_ARI_E_FPN_SHIFT 33
  4871. +
  4872. +#include <linux/dect_netlink.h>
  4873. +
  4874. +struct dect_ari {
  4875. + enum dect_ari_classes arc;
  4876. + u32 fpn;
  4877. + u32 fps;
  4878. + union {
  4879. + u16 emc;
  4880. + u16 eic;
  4881. + u16 poc;
  4882. + u32 gop;
  4883. + u16 fil;
  4884. + };
  4885. +};
  4886. +
  4887. +enum dect_ari_lengths {
  4888. + DECT_ARC_A_LEN = 36,
  4889. + DECT_ARC_B_LEN = 31,
  4890. + DECT_ARC_C_LEN = 31,
  4891. + DECT_ARC_D_LEN = 31,
  4892. + DECT_ARC_E_LEN = 31,
  4893. +};
  4894. +
  4895. +extern bool dect_ari_masked_cmp(const struct dect_ari *a1,
  4896. + const struct dect_ari *a2,
  4897. + const struct dect_ari *m);
  4898. +extern bool dect_ari_cmp(const struct dect_ari *a1, const struct dect_ari *a2);
  4899. +extern u8 dect_parse_ari(struct dect_ari *ari, u64 a);
  4900. +extern u64 dect_build_ari(const struct dect_ari *ari);
  4901. +
  4902. +/*
  4903. + * RFPI
  4904. + */
  4905. +
  4906. +#define DECT_RFPI_E_FLAG 0x0080000000000000ULL
  4907. +#define DECT_RFPI_ARI_SHIFT 9
  4908. +#define DECT_RFPI_RPN_SHIFT 16
  4909. +
  4910. +struct dect_idi;
  4911. +extern bool dect_rfpi_cmp(const struct dect_idi *i1, const struct dect_idi *i2);
  4912. +extern u64 dect_build_rfpi(const struct dect_idi *idi);
  4913. +
  4914. +/*
  4915. + * FMID (Fixed MAC Identifier)
  4916. + */
  4917. +
  4918. +#define DECT_FMID_MASK 0x0fff
  4919. +#define DECT_FMID_SIZE 12
  4920. +
  4921. +extern u16 dect_build_fmid(const struct dect_idi *idi);
  4922. +
  4923. +/*
  4924. + * PMID (Portable MAC Identifier)
  4925. + */
  4926. +
  4927. +#define DECT_PMID_MASK 0x000fffff
  4928. +#define DECT_PMID_SIZE 20
  4929. +
  4930. +#define DECT_PMID_DEFAULT_ID_MASK 0x000f0000
  4931. +#define DECT_PMID_DEFAULT_ID 0x000e0000
  4932. +#define DECT_PMID_DEFAULT_NUM_MASK 0x0000ffff
  4933. +
  4934. +#define DECT_PMID_EMERGENCY_ID_MASK 0x000ff000
  4935. +#define DECT_PMID_EMERGENCY_ID 0x000f1000
  4936. +#define DECT_PMID_EMERGENCY_TPUI_MASK 0x00000fff
  4937. +
  4938. +#define DECT_PMID_ASSIGNED_TPUI_MASK 0x000fffff
  4939. +
  4940. +/**
  4941. + * @DECT_PMID_DEFAULT: 1110 + arbitrary number (16 bits)
  4942. + * @DECT_PMID_ASSIGNED: Assigned individual TPUI
  4943. + * @DECT_PMID_EMERGENCY: 1111 0001 + 12 bits of emergency TPUI
  4944. + */
  4945. +enum dect_pmid_types {
  4946. + DECT_PMID_DEFAULT,
  4947. + DECT_PMID_ASSIGNED,
  4948. + DECT_PMID_EMERGENCY,
  4949. +};
  4950. +
  4951. +struct dect_pmid {
  4952. + enum dect_pmid_types type;
  4953. + union {
  4954. + u32 tpui;
  4955. + u32 num;
  4956. + };
  4957. +};
  4958. +
  4959. +extern void dect_parse_pmid(struct dect_pmid *pmid, u32 p);
  4960. +extern u32 dect_build_pmid(const struct dect_pmid *pmid);
  4961. +extern bool dect_pmid_cmp(const struct dect_pmid *p1, const struct dect_pmid *p2);
  4962. +
  4963. +/*
  4964. + * ECN (Exchanged Connection Number)
  4965. + */
  4966. +
  4967. +#define DECT_ECN_MASK 0xf
  4968. +#define DECT_ECN_SIZE 4
  4969. +
  4970. +/*
  4971. + * LCN (Logical Connection Number)
  4972. + */
  4973. +
  4974. +#define DECT_LCN_MASK 0x7
  4975. +#define DECT_LCN_SIZE 3
  4976. +
  4977. +/**
  4978. + * struct dect_mci - MAC connection identifier
  4979. + *
  4980. + * @ari: DECT ARI
  4981. + * @pmid: Portable MAC Identity
  4982. + * @lcn: Logical Connection Number
  4983. + */
  4984. +struct dect_mci {
  4985. + struct dect_ari ari;
  4986. + struct dect_pmid pmid;
  4987. + u8 lcn;
  4988. +};
  4989. +
  4990. +extern int dect_parse_mci(struct dect_mci *mci, u64 m);
  4991. +extern u64 dect_build_mci(const struct dect_mci *mci);
  4992. +
  4993. +/*
  4994. + * Data Link Identifier
  4995. + */
  4996. +
  4997. +/**
  4998. + * struct dect_dlei - DECT Data Link Endpoint Identifier (DLEI)
  4999. + *
  5000. + */
  5001. +struct dect_dlei {
  5002. + struct dect_mci mci;
  5003. + enum dect_sapis sapi;
  5004. + enum dect_llns lln;
  5005. +};
  5006. +
  5007. +/**
  5008. + * struct dect_ulei - DECT U-Plane Link Endpoint Identifier
  5009. + */
  5010. +struct dect_ulei {
  5011. + struct dect_mci mci;
  5012. +};
  5013. +
  5014. +#endif /* _NET_DECT_IDENTITIES_H */
  5015. diff --git a/include/net/dect/mac.h b/include/net/dect/mac.h
  5016. new file mode 100644
  5017. index 0000000..74c0a9e
  5018. --- /dev/null
  5019. +++ b/include/net/dect/mac.h
  5020. @@ -0,0 +1,837 @@
  5021. +/*
  5022. + * DECT MAC Layer - Header and global definitions
  5023. + *
  5024. + * Copyright (c) 2009 Patrick McHardy <[email protected]>
  5025. + */
  5026. +
  5027. +#ifndef _NET_DECT_MAC_H
  5028. +#define _NET_DECT_MAC_H
  5029. +
  5030. +#include <net/dect/identities.h>
  5031. +
  5032. +/*
  5033. + * A-Field
  5034. + */
  5035. +
  5036. +#define DECT_A_FIELD_SIZE 8
  5037. +
  5038. +#define DECT_RA_FIELD_SIZE 2
  5039. +#define DECT_RA_FIELD_OFF 6
  5040. +
  5041. +/*
  5042. + * Header field
  5043. + */
  5044. +
  5045. +#define DECT_HDR_FIELD_SIZE 1
  5046. +#define DECT_HDR_FIELD_OFF 0
  5047. +
  5048. +#define DECT_HDR_TA_OFF 0
  5049. +#define DECT_HDR_TA_MASK 0xe0
  5050. +#define DECT_HDR_TA_SHIFT 5
  5051. +
  5052. +#define DECT_HDR_Q1_OFF 0
  5053. +#define DECT_HDR_Q1_FLAG 0x10
  5054. +
  5055. +#define DECT_HDR_BA_OFF 0
  5056. +#define DECT_HDR_BA_MASK 0x0e
  5057. +#define DECT_HDR_BA_SHIFT 1
  5058. +
  5059. +#define DECT_HDR_Q2_OFF 0
  5060. +#define DECT_HDR_Q2_FLAG 0x01
  5061. +
  5062. +/*
  5063. + * T-Field
  5064. + */
  5065. +
  5066. +#define DECT_T_FIELD_OFF 1
  5067. +#define DECT_T_FIELD_SIZE 5
  5068. +
  5069. +/**
  5070. + * dect_tail_identification - MAC layer T-Field identification
  5071. + *
  5072. + * @DECT_TI_CT_PKT_0: C_T data packet number 0
  5073. + * @DECT_TI_CT_PKT_1: C_T data packet number 1
  5074. + * @DECT_TI_NT_CL: Identities information on connectionless bearer
  5075. + * @DECT_TI_NT: Identities information
  5076. + * @DECT_TI_QT: Multiframe synchronisation und system information
  5077. + * @DECT_TI_RESERVED: Reserved
  5078. + * @DECT_TI_MT: MAC layer control
  5079. + * @DECT_TI_PT: Paging tail (RFP only)
  5080. + * @DECT_TI_MT_PKT_0: MAC layer control (first PP transmission, PP only)
  5081. + */
  5082. +enum dect_tail_identifications {
  5083. + DECT_TI_CT_PKT_0 = 0x0 << DECT_HDR_TA_SHIFT,
  5084. + DECT_TI_CT_PKT_1 = 0x1 << DECT_HDR_TA_SHIFT,
  5085. + DECT_TI_NT_CL = 0x2 << DECT_HDR_TA_SHIFT,
  5086. + DECT_TI_NT = 0x3 << DECT_HDR_TA_SHIFT,
  5087. + DECT_TI_QT = 0x4 << DECT_HDR_TA_SHIFT,
  5088. + DECT_TI_RESERVED = 0x5 << DECT_HDR_TA_SHIFT,
  5089. + DECT_TI_MT = 0x6 << DECT_HDR_TA_SHIFT,
  5090. + DECT_TI_PT = 0x7 << DECT_HDR_TA_SHIFT,
  5091. + DECT_TI_MT_PKT_0 = 0x7 << DECT_HDR_TA_SHIFT,
  5092. +};
  5093. +
  5094. +struct dect_skb_a_cb {
  5095. + enum dect_tail_identifications id;
  5096. +};
  5097. +
  5098. +#define DECT_A_CB(skb) ((struct dect_skb_a_cb *)(skb)->cb)
  5099. +
  5100. +/*
  5101. + * Identities channel (N-channel)
  5102. + */
  5103. +
  5104. +/* Identities information */
  5105. +#define DECT_NT_ID_RFPI_LEN 5
  5106. +
  5107. +/**
  5108. + * @e: indicates whether SARIs are available
  5109. + * @pari: primary access rights identifier
  5110. + * @rpn: radio part number
  5111. + */
  5112. +struct dect_idi {
  5113. + bool e;
  5114. + struct dect_ari pari;
  5115. + u8 rpn;
  5116. +};
  5117. +
  5118. +/*
  5119. + * System information and multiframe marker (Q-channel)
  5120. + */
  5121. +
  5122. +/* RFP Q-channel T-MUX rules: only frame 8 */
  5123. +#define DECT_Q_CHANNEL_FRAME 8
  5124. +
  5125. +/* System information header */
  5126. +#define DECT_QT_H_MASK 0x00f0000000000000ULL
  5127. +#define DECT_QT_H_SHIFT 52
  5128. +
  5129. +/**
  5130. + * dect_system_information_types - codes for system information messages
  5131. + *
  5132. + * @DECT_QT_SI_SSI: static system information
  5133. + * @DECT_QT_SI_ERFC: extended RF carriers
  5134. + * @DECT_QT_SI_FPC: fixed part capabilities
  5135. + * @DECT_QT_SI_EFPC: extended fixed part capabilities
  5136. + * @DECT_QT_SI_SARI: SARI list contents
  5137. + * @DECT_QT_SI_MFN: multi-frame number
  5138. + * @DECT_QT_SI_ESC: escape
  5139. + * @DECT_QT_SI_ERFC2: extended RF carriers part 2
  5140. + * @DECT_QT_SI_TXI transmit information
  5141. + * @DECT_QT_SI_EFPC2: extended fixed part capabilities part 2
  5142. + */
  5143. +enum dect_mac_system_information_types {
  5144. + DECT_QT_SI_SSI = 0x0ULL << DECT_QT_H_SHIFT,
  5145. + DECT_QT_SI_SSI2 = 0x1ULL << DECT_QT_H_SHIFT,
  5146. + DECT_QT_SI_ERFC = 0x2ULL << DECT_QT_H_SHIFT,
  5147. + DECT_QT_SI_FPC = 0x3ULL << DECT_QT_H_SHIFT,
  5148. + DECT_QT_SI_EFPC = 0x4ULL << DECT_QT_H_SHIFT,
  5149. + DECT_QT_SI_SARI = 0x5ULL << DECT_QT_H_SHIFT,
  5150. + DECT_QT_SI_MFN = 0x6ULL << DECT_QT_H_SHIFT,
  5151. + DECT_QT_SI_ESC = 0x7ULL << DECT_QT_H_SHIFT,
  5152. + DECT_QT_SI_ERFC2 = 0x9ULL << DECT_QT_H_SHIFT,
  5153. + DECT_QT_SI_TXI = 0xbULL << DECT_QT_H_SHIFT,
  5154. + DECT_QT_SI_EFPC2 = 0xcULL << DECT_QT_H_SHIFT,
  5155. +};
  5156. +
  5157. +/*
  5158. + * Static system information - repeated every 8 multiframes
  5159. + */
  5160. +
  5161. +#define DECT_QT_SSI_FREQ 8
  5162. +
  5163. +/* normal reverse */
  5164. +#define DECT_QT_SSI_NR_FLAG 0x0010000000000000ULL
  5165. +
  5166. +/* slot number */
  5167. +#define DECT_QT_SSI_SN_MASK 0x000f000000000000ULL
  5168. +#define DECT_QT_SSI_SN_SHIFT 48
  5169. +
  5170. +/* start position */
  5171. +#define DECT_QT_SSI_SP_MASK 0x0000c00000000000ULL
  5172. +#define DECT_QT_SSI_SP_SHIFT 46
  5173. +
  5174. +/* escape bit */
  5175. +#define DECT_QT_SSI_ESC_FLAG 0x0000200000000000ULL
  5176. +
  5177. +/* number of transceivers */
  5178. +#define DECT_QT_SSI_TXS_MASK 0x0000180000000000ULL
  5179. +#define DECT_QT_SSI_TXS_SHIFT 43
  5180. +
  5181. +/* extended RF carrier information available */
  5182. +#define DECT_QT_SSI_MC_FLAG 0x0000040000000000ULL
  5183. +
  5184. +/* RF carriers available */
  5185. +#define DECT_QT_SSI_RFCARS_MASK 0x000003ff00000000ULL
  5186. +#define DECT_QT_SSI_RFCARS_SHIFT 32
  5187. +
  5188. +/* carrier number */
  5189. +#define DECT_QT_SSI_CN_MASK 0x000000003f000000ULL
  5190. +#define DECT_QT_SSI_CN_SHIFT 24
  5191. +
  5192. +/* primary scan carrier number */
  5193. +#define DECT_QT_SSI_PSCN_MASK 0x00000000003f0000ULL
  5194. +#define DECT_QT_SSI_PSCN_SHIFT 16
  5195. +
  5196. +struct dect_ssi {
  5197. + bool nr;
  5198. + bool mc;
  5199. + u16 rfcars;
  5200. + u8 sn;
  5201. + u8 sp;
  5202. + u8 txs;
  5203. + u8 cn;
  5204. + u8 pscn;
  5205. +};
  5206. +
  5207. +/*
  5208. + * Extended RF carrier information
  5209. + */
  5210. +
  5211. +#define DECT_QT_ERFC_FREQ 8
  5212. +
  5213. +#define DECT_QT_ERFC_RFCARS_MASK 0x000fffffe0000000ULL
  5214. +#define DECT_QT_ERFC_RFCARS_SHIFT 1
  5215. +
  5216. +#define DECT_QT_ERFC_RFBAND_MASK 0x000000001f000000ULL
  5217. +#define DECT_QT_ERFC_RFBAND_SHIFT 24
  5218. +
  5219. +#define DECT_QT_ERFC_ERFC2_FLAG 0x0000000000800000ULL
  5220. +
  5221. +#define DECT_QT_ERFC_NUM_RFCARS_MASK 0x00000000003f0000ULL
  5222. +#define DECT_QT_ERFC_NUM_RFCARS_SHIFT 16
  5223. +
  5224. +struct dect_erfc {
  5225. + u32 rfcars;
  5226. + u8 band;
  5227. + u8 num_rfcars;
  5228. + bool erfc2;
  5229. +};
  5230. +
  5231. +/*
  5232. + * Fixed Part capabilities
  5233. + */
  5234. +
  5235. +#define DECT_QT_FPC_FREQ 8
  5236. +
  5237. +#define DECT_QT_FPC_CAPABILITY_MASK 0x000fffff00000000ULL
  5238. +#define DECT_QT_FPC_CAPABILITY_SHIFT 32
  5239. +
  5240. +#define DECT_QT_FPC_HLC_MASK 0x00000000ffff0000ULL
  5241. +#define DECT_QT_FPC_HLC_SHIFT 16
  5242. +
  5243. +struct dect_fpc {
  5244. + u32 fpc;
  5245. + u16 hlc;
  5246. +};
  5247. +
  5248. +/*
  5249. + * Extended Fixed Part capabilities
  5250. + */
  5251. +
  5252. +#define DECT_QT_EFPC_EFPC_MASK 0x000fff8000000000ULL
  5253. +#define DECT_QT_EFPC_EFPC_SHIFT 39
  5254. +
  5255. +#define DECT_QT_EFPC_EHLC_MASK 0x0000007fffff0000ULL
  5256. +#define DECT_QT_EFPC_EHLC_SHIFT 16
  5257. +
  5258. +struct dect_efpc {
  5259. + u16 fpc;
  5260. + u32 hlc;
  5261. +};
  5262. +
  5263. +#define DECT_QT_EFPC2_FPC_MASK 0x000fff0000000000ULL
  5264. +#define DECT_QT_EFPC2_FPC_SHIFT 40
  5265. +
  5266. +#define DECT_QT_EFPC2_HLC_MASK 0x000000ffffff0000ULL
  5267. +#define DECT_QT_EFPC2_HLC_SHIFT 16
  5268. +
  5269. +struct dect_efpc2 {
  5270. + u16 fpc;
  5271. + u32 hlc;
  5272. +};
  5273. +
  5274. +/*
  5275. + * SARI message
  5276. + */
  5277. +
  5278. +#define DECT_QT_SARI_FREQ 4
  5279. +
  5280. +#define DECT_QT_SARI_LIST_CYCLE_MASK 0x00000e0000000000ULL
  5281. +#define DECT_QT_SARI_LIST_CYCLE_SHIFT 41
  5282. +
  5283. +#define DECT_QT_SARI_TARI_FLAG 0x0000010000000000ULL
  5284. +
  5285. +#define DECT_QT_SARI_BLACK_FLAG 0x0000008000000000ULL
  5286. +
  5287. +#define DECT_QT_SARI_ARI_MASK 0x0000007fffffff00ULL
  5288. +#define DECT_QT_SARI_ARI_SHIFT 25
  5289. +
  5290. +struct dect_sari {
  5291. + u8 list_cycle;
  5292. + bool tari;
  5293. + bool black;
  5294. + struct dect_ari ari;
  5295. +};
  5296. +
  5297. +#define DECT_SARI_CYCLE_MAX 16
  5298. +
  5299. +/*
  5300. + * Multiframe number - repeated every 8 multiframes if supported
  5301. + */
  5302. +
  5303. +#define DECT_QT_MFN_FREQ 8
  5304. +
  5305. +#define DECT_QT_MFN_MASK 0x000000ffffff0000ULL
  5306. +#define DECT_QT_MFN_SHIFT 16
  5307. +
  5308. +struct dect_mfn {
  5309. + u32 num;
  5310. +};
  5311. +
  5312. +/*
  5313. + * Extended RF carrier information part 2
  5314. + */
  5315. +
  5316. +#define DECT_QT_TXI_ERFC2_FREQ 8
  5317. +
  5318. +#define DECT_QT_ERFC2_RFCARS_MASK 0x000fffffffe00000ULL
  5319. +#define DECT_QT_ERFC2_RFCARS_SHIFT 21
  5320. +
  5321. +struct dect_erfc2 {
  5322. + u32 rfcars;
  5323. +};
  5324. +
  5325. +/*
  5326. + * Transmit Information
  5327. + */
  5328. +
  5329. +#define DECT_QT_TXI_FREQ 8
  5330. +
  5331. +#define DECT_QT_TXI_TYPE_MASK 0x000f000000000000ULL
  5332. +#define DECT_QT_TXI_TYPE_SHIFT 48
  5333. +
  5334. +#define DECT_QT_TXI_PWL_MASK 0x0000ff0000000000ULL
  5335. +#define DECT_QT_TXI_PWL_SHIFT 40
  5336. +
  5337. +/*
  5338. + * Extended fixed part capabilitiees part 2
  5339. + */
  5340. +
  5341. +/*
  5342. + * Paging Tail (P-channel)
  5343. + */
  5344. +
  5345. +#define DECT_PT_HDR_EXTEND_FLAG 0x0080000000000000ULL
  5346. +
  5347. +#define DECT_PT_HDR_LENGTH_MASK 0x0070000000000000ULL
  5348. +#define DECT_PT_HDR_LENGTH_SHIFT 52
  5349. +
  5350. +/**
  5351. + * @DECT_PT_ZERO_PAGE: zero length page
  5352. + * @DECT_PT_SHORT_PAGE: short page
  5353. + * @DECT_PT_FULL_PAGE: full page
  5354. + * @DECT_PT_MAX_RESUME_PAGE: MAC resume and control page
  5355. + * @DECT_PT_LONG_PAGE: not the last 36 bits of a long page
  5356. + * @DECT_PT_LONG_PAGE_FIRST: the first 36 bits of a long page
  5357. + * @DECT_PT_LONG_PAGE_LAST: the last 36 bits of a long page
  5358. + * @DECT_PT_LONG_PAGE_ALL: all of a long page (first and last)
  5359. + *
  5360. + */
  5361. +enum dect_page_lengths {
  5362. + DECT_PT_ZERO_PAGE = 0x0ULL << DECT_PT_HDR_LENGTH_SHIFT,
  5363. + DECT_PT_SHORT_PAGE = 0x1ULL << DECT_PT_HDR_LENGTH_SHIFT,
  5364. + DECT_PT_FULL_PAGE = 0x2ULL << DECT_PT_HDR_LENGTH_SHIFT,
  5365. + DECT_PT_RESUME_PAGE = 0x3ULL << DECT_PT_HDR_LENGTH_SHIFT,
  5366. + DECT_PT_LONG_PAGE = 0x4ULL << DECT_PT_HDR_LENGTH_SHIFT,
  5367. + DECT_PT_LONG_PAGE_FIRST = 0x5ULL << DECT_PT_HDR_LENGTH_SHIFT,
  5368. + DECT_PT_LONG_PAGE_LAST = 0x6ULL << DECT_PT_HDR_LENGTH_SHIFT,
  5369. + DECT_PT_LONG_PAGE_ALL = 0x7ULL << DECT_PT_HDR_LENGTH_SHIFT,
  5370. +};
  5371. +
  5372. +/* zero length pages */
  5373. +#define DECT_PT_ZP_RFPI_MASK 0x000fffff00000000ULL
  5374. +#define DECT_PT_ZP_RFPI_SHIFT 32
  5375. +
  5376. +/* short page B_S channel data */
  5377. +#define DECT_PT_SP_BS_DATA_MASK 0x000fffff00000000ULL
  5378. +#define DECT_PT_SP_BS_DATA_SHIFT 32
  5379. +#define DECT_PT_SP_BS_DATA_SIZE 3
  5380. +
  5381. +/* long and full page B_S channel data */
  5382. +#define DECT_PT_LFP_BS_DATA_MASK 0x000fffffffff0000ULL
  5383. +#define DECT_PT_LFP_BS_DATA_SHIFT 16
  5384. +#define DECT_PT_LFP_BS_DATA_SIZE 5
  5385. +
  5386. +struct dect_page {
  5387. + bool extend;
  5388. + enum dect_page_lengths length;
  5389. + u32 rfpi;
  5390. +};
  5391. +
  5392. +/* MAC layer information */
  5393. +#define DECT_PT_INFO_TYPE_MASK 0x00000000f0000000ULL
  5394. +#define DECT_PT_INFO_TYPE_SHIFT 28
  5395. +#define DECT_PT_INFO_TYPE_SIZE 2
  5396. +
  5397. +/**
  5398. + * @DECT_PT_IT_FILL_BITS_OR_BLIND_LONG_SLOTS: fill bits/blind long slots if bit 47 set
  5399. + * @DECT_PT_IT_BLIND_FULL_SLOT: blind full slot information
  5400. + * @DECT_PT_IT_OTHER_BEARER:
  5401. + * @DECT_PT_IT_RECOMMENDED_OTHER_BEARER:
  5402. + * @DECT_PT_IT_GOOD_RFP_BEARER:
  5403. + * @DECT_PT_IT_DUMMY_OR_CL_BEARER_POSITION:
  5404. + * @DECT_PT_IT_RFP_IDENTITY:
  5405. + * @DECT_PT_IT_ESCAPE:
  5406. + * @DECT_PT_IT_DUMMY_OR_CL_BEARER_MARKER:
  5407. + * @DECT_PT_IT_BEARER_HANDOVER_INFO:
  5408. + * @DECT_PT_IT_RFP_STATUS:
  5409. + * @DECT_PT_IT_ACTIVE_CARRIERS:
  5410. + * @DECT_PT_IT_CL_BEARER_POSITION:
  5411. + * @DECT_PT_IT_RECOMMENDED_POWER_LEVEL:
  5412. + * @DECT_PT_IT_BLIND_DOUBLE_SLOT:
  5413. + * @DECT_PT_IT_BLIND_FULL_SLOT_PACKET_MODE:
  5414. + *
  5415. + */
  5416. +enum dect_pt_info_types {
  5417. + DECT_PT_IT_FILL_BITS_OR_BLIND_LONG_SLOTS= 0x0ULL << DECT_PT_INFO_TYPE_SHIFT,
  5418. + DECT_PT_IT_BLIND_FULL_SLOT = 0x1ULL << DECT_PT_INFO_TYPE_SHIFT,
  5419. + DECT_PT_IT_OTHER_BEARER = 0x2ULL << DECT_PT_INFO_TYPE_SHIFT,
  5420. + DECT_PT_IT_RECOMMENDED_OTHER_BEARER = 0x3ULL << DECT_PT_INFO_TYPE_SHIFT,
  5421. + DECT_PT_IT_GOOD_RFP_BEARER = 0x4ULL << DECT_PT_INFO_TYPE_SHIFT,
  5422. + DECT_PT_IT_DUMMY_OR_CL_BEARER_POSITION = 0x5ULL << DECT_PT_INFO_TYPE_SHIFT,
  5423. + DECT_PT_IT_RFP_IDENTITY = 0x6ULL << DECT_PT_INFO_TYPE_SHIFT,
  5424. + DECT_PT_IT_ESCAPE = 0x7ULL << DECT_PT_INFO_TYPE_SHIFT,
  5425. + DECT_PT_IT_DUMMY_OR_CL_BEARER_MARKER = 0x8ULL << DECT_PT_INFO_TYPE_SHIFT,
  5426. + DECT_PT_IT_BEARER_HANDOVER_INFO = 0x9ULL << DECT_PT_INFO_TYPE_SHIFT,
  5427. + DECT_PT_IT_RFP_STATUS = 0xaULL << DECT_PT_INFO_TYPE_SHIFT,
  5428. + DECT_PT_IT_ACTIVE_CARRIERS = 0xbULL << DECT_PT_INFO_TYPE_SHIFT,
  5429. + DECT_PT_IT_CL_BEARER_POSITION = 0xcULL << DECT_PT_INFO_TYPE_SHIFT,
  5430. + DECT_PT_IT_RECOMMENDED_POWER_LEVEL = 0xdULL << DECT_PT_INFO_TYPE_SHIFT,
  5431. + DECT_PT_IT_BLIND_DOUBLE_SLOT = 0xeULL << DECT_PT_INFO_TYPE_SHIFT,
  5432. + DECT_PT_IT_BLIND_FULL_SLOT_PACKET_MODE = 0xfULL << DECT_PT_INFO_TYPE_SHIFT,
  5433. +};
  5434. +
  5435. +/* blind full slot information */
  5436. +#define DECT_PT_BFS_MASK 0x000000000fff0000ULL
  5437. +#define DECT_PT_BFS_SHIFT 16
  5438. +
  5439. +struct dect_bfs {
  5440. + struct dect_page page;
  5441. + u16 mask;
  5442. +};
  5443. +
  5444. +/* Bearer description */
  5445. +#define DECT_PT_BEARER_SN_MASK 0x000000000f000000ULL
  5446. +#define DECT_PT_BEARER_SN_SHIFT 24
  5447. +
  5448. +#define DECT_PT_BEARER_SP_MASK 0x0000000000c00000ULL
  5449. +#define DECT_PT_BEARER_SP_SHIFT 22
  5450. +
  5451. +#define DECT_PT_BEARER_CN_MASK 0x00000000003f0000ULL
  5452. +#define DECT_PT_BEARER_CN_SHIFT 16
  5453. +
  5454. +struct dect_bearer_desc {
  5455. + struct dect_page page;
  5456. + enum dect_pt_info_types bt;
  5457. + u8 sn;
  5458. + u8 sp;
  5459. + u8 cn;
  5460. +};
  5461. +
  5462. +/* RFP identity */
  5463. +#define DECT_PT_RFP_ID_MASK 0x000000000fff0000ULL
  5464. +#define DECT_PT_RFP_ID_SHIFT 16
  5465. +
  5466. +struct dect_rfp_id {
  5467. + struct dect_page page;
  5468. + u16 id;
  5469. +};
  5470. +
  5471. +/* RFP status */
  5472. +#define DECT_PT_RFPS_RFP_BUSY_FLAG 0x0000000001000000ULL
  5473. +#define DECT_PT_RFPS_SYS_BUSY_FLAG 0x0000000002000000ULL
  5474. +
  5475. +struct dect_rfp_status {
  5476. + struct dect_page page;
  5477. + bool rfp_busy;
  5478. + bool sys_busy;
  5479. +};
  5480. +
  5481. +/* Active carriers */
  5482. +#define DECT_PT_ACTIVE_CARRIERS_MASK 0x000000000ffc0000ULL
  5483. +#define DECT_PT_ACTIVE_CARRIERS_SHIFT 18
  5484. +
  5485. +struct dect_active_carriers {
  5486. + struct dect_page page;
  5487. + u16 active;
  5488. +};
  5489. +
  5490. +/*
  5491. + * MAC control (M-channel)
  5492. + */
  5493. +
  5494. +#define DECT_MT_FRAME_RATE 2
  5495. +
  5496. +#define DECT_MT_HDR_MASK 0x00f0000000000000ULL
  5497. +#define DECT_MT_HDR_SHIFT 52
  5498. +
  5499. +#define DECT_MT_CMD_MASK 0x000f000000000000ULL
  5500. +#define DECT_MT_CMD_SHIFT 48
  5501. +
  5502. +/**
  5503. + * enum dect_mt_hdr_type - MAC tail header types
  5504. + */
  5505. +enum dect_mt_hdr_type {
  5506. + DECT_MT_BASIC_CCTRL = 0x0ULL << DECT_MT_HDR_SHIFT,
  5507. + DECT_MT_ADV_CCTRL = 0x1ULL << DECT_MT_HDR_SHIFT,
  5508. + DECT_MT_MAC_TEST = 0x2ULL << DECT_MT_HDR_SHIFT,
  5509. + DECT_MT_QUALITY_CTRL = 0x3ULL << DECT_MT_HDR_SHIFT,
  5510. + DECT_MT_BRD_CL_SERVICE = 0x4ULL << DECT_MT_HDR_SHIFT,
  5511. + DECT_MT_ENC_CTRL = 0x5ULL << DECT_MT_HDR_SHIFT,
  5512. + DECT_MT_XYZ = 0x6ULL << DECT_MT_HDR_SHIFT,
  5513. + DECT_MT_ESC = 0x7ULL << DECT_MT_HDR_SHIFT,
  5514. + DECT_MT_TARI = 0x8ULL << DECT_MT_HDR_SHIFT,
  5515. + DECT_MT_REP_CCTRL = 0x9ULL << DECT_MT_HDR_SHIFT,
  5516. +};
  5517. +
  5518. +/* advanced connection control */
  5519. +enum dect_cctrl_cmds {
  5520. + DECT_CCTRL_ACCESS_REQ = 0x0ULL << DECT_MT_CMD_SHIFT,
  5521. + DECT_CCTRL_BEARER_HANDOVER_REQ = 0x1ULL << DECT_MT_CMD_SHIFT,
  5522. + DECT_CCTRL_CONNECTION_HANDOVER_REQ = 0x2ULL << DECT_MT_CMD_SHIFT,
  5523. + DECT_CCTRL_UNCONFIRMED_ACCESS_REQ = 0x3ULL << DECT_MT_CMD_SHIFT,
  5524. + DECT_CCTRL_BEARER_CONFIRM = 0x4ULL << DECT_MT_CMD_SHIFT,
  5525. + DECT_CCTRL_WAIT = 0x5ULL << DECT_MT_CMD_SHIFT,
  5526. + DECT_CCTRL_ATTRIBUTES_T_REQUEST = 0x6ULL << DECT_MT_CMD_SHIFT,
  5527. + DECT_CCTRL_ATTRIBUTES_T_CONFIRM = 0x7ULL << DECT_MT_CMD_SHIFT,
  5528. + DECT_CCTRL_BANDWIDTH_T_REQUEST = 0x8ULL << DECT_MT_CMD_SHIFT,
  5529. + DECT_CCTRL_BANDWIDTH_T_CONFIRM = 0x9ULL << DECT_MT_CMD_SHIFT,
  5530. + DECT_CCTRL_CHANNEL_LIST = 0xaULL << DECT_MT_CMD_SHIFT,
  5531. + DECT_CCTRL_UNCONFIRMED_DUMMY = 0xbULL << DECT_MT_CMD_SHIFT,
  5532. + DECT_CCTRL_UNCONFIRMED_HANDOVER = 0xcULL << DECT_MT_CMD_SHIFT,
  5533. + DECT_CCTRL_RELEASE = 0xfULL << DECT_MT_CMD_SHIFT,
  5534. +};
  5535. +
  5536. +/* Most messages */
  5537. +#define DECT_CCTRL_FMID_MASK 0x0000fff000000000ULL
  5538. +#define DECT_CCTRL_FMID_SHIFT 36
  5539. +
  5540. +#define DECT_CCTRL_PMID_MASK 0x0000000fffff0000ULL
  5541. +#define DECT_CCTRL_PMID_SHIFT 16
  5542. +
  5543. +/* Attributes-T request/confirm */
  5544. +#define DECT_CCTRL_ATTR_ECN_MASK 0x0000f00000000000ULL
  5545. +#define DECT_CCTRL_ATTR_ECN_SHIFT 44
  5546. +
  5547. +#define DECT_CCTRL_ATTR_LBN_MASK 0x00000f0000000000ULL
  5548. +#define DECT_CCTRL_ATTR_LBN_SHIFT 40
  5549. +
  5550. +#define DECT_CCTRL_ATTR_TYPE_MASK 0x000000c000000000ULL
  5551. +#define DECT_CCTRL_ATTR_TYPE_SHIFT 38
  5552. +
  5553. +enum dect_cctrl_connection_types {
  5554. + DECT_CCTRL_TYPE_ASYMETRIC_UPLINK = 0x0,
  5555. + DECT_CCTRL_TYPE_ASYMETRIC_DOWNLINK = 0x1,
  5556. + DECT_CCTRL_TYPE_SYMETRIC_MULTIBEARER = 0x2,
  5557. + DECT_CCTRL_TYPE_SYMETRIC_BEARER = 0x3,
  5558. +};
  5559. +
  5560. +#define DECT_CCTRL_ATTR_SERVICE_MASK 0x0000003f00000000ULL
  5561. +#define DECT_CCTRL_ATTR_SERVICE_SHIFT 32
  5562. +
  5563. +#define DECT_CCTRL_ATTR_SLOT_MASK 0x00000000f0000000ULL
  5564. +#define DECT_CCTRL_ATTR_SLOT_SHIFT 28
  5565. +
  5566. +#define DECT_CCTRL_ATTR_CF_FLAG 0x0000000008000000ULL
  5567. +
  5568. +#define DECT_CCTRL_ATTR_BZ_EXT_MOD_MASK 0x0000000007000000ULL
  5569. +#define DECT_CCTRL_ATTR_BZ_EXT_MOD_SHIFT 24
  5570. +
  5571. +#define DECT_CCTRL_ATTR_ACR_MASK 0x0000000000f00000ULL
  5572. +#define DECT_CCTRL_ATTR_ACR_SHIFT 20
  5573. +
  5574. +enum dect_adaptive_code_rates {
  5575. + DECT_ACR_NONE = 0x0,
  5576. +};
  5577. +
  5578. +#define DECT_CCTRL_ATTR_A_MOD_MASK 0x00000000000c0000ULL
  5579. +#define DECT_CCTRL_ATTR_A_MOD_SHIFT 18
  5580. +
  5581. +#define DECT_CCTRL_ATTR_BZ_MOD_MASK 0x0000000000030000ULL
  5582. +#define DECT_CCTRL_ATTR_BZ_MOD_SHIFT 16
  5583. +
  5584. +enum dect_modulation_type {
  5585. + DECT_MODULATION_2_LEVEL = 0x3,
  5586. + DECT_MODULATION_4_LEVEL = 0x2,
  5587. + DECT_MODULATION_8_LEVEL = 0x1,
  5588. +};
  5589. +
  5590. +/* Release */
  5591. +
  5592. +#define DECT_CCTRL_RELEASE_INFO1_MASK 0x0000f00000000000ULL
  5593. +#define DECT_CCTRL_RELEASE_INFO1_SHIFT 44
  5594. +
  5595. +#define DECT_CCTRL_RELEASE_LBN_MASK 0x00000f0000000000ULL
  5596. +#define DECT_CCTRL_RELEASE_LBN_SHIFT 40
  5597. +
  5598. +#define DECT_CCTRL_RELEASE_REASON_MASK 0x000000f000000000ULL
  5599. +#define DECT_CCTRL_RELEASE_REASON_SHIFT 36
  5600. +
  5601. +enum dect_release_reasons {
  5602. + DECT_REASON_UNKNOWN = 0x0,
  5603. + DECT_REASON_BEARER_RELEASE = 0x1,
  5604. + DECT_REASON_CONNECTION_RELEASE = 0x2,
  5605. + DECT_REASON_BEARER_SETUP_OR_HANDOVER_FAILED = 0x3,
  5606. + DECT_REASON_BEARER_HANDOVER_COMPLETED = 0x4,
  5607. + DECT_REASON_BEARER_HANDOVER_CLUSTER = 0x5,
  5608. + DECT_REASON_TIMEOUT_LOST_SIGNAL = 0x6,
  5609. + DECT_REASON_TIMEOUT_LOST_HANDSHAKE = 0x7,
  5610. + DECT_REASON_REQUESTED_UNACCEPTABLE_SLOT_TYPE = 0x8,
  5611. + DECT_REASON_REQUESTED_UNACCEPTABLE_MAC_SERVICE = 0x9,
  5612. + DECT_REASON_BASE_STATION_BUSY = 0xa,
  5613. + DECT_REASON_REVERSE_DIRECTION = 0xb,
  5614. + DECT_REASON_DUPLICATE_PMID = 0xc,
  5615. + DECT_REASON_UNACCEPTABLE_PMID = 0xd,
  5616. + DECT_REASON_STAY_ON_LISTEN = 0xe,
  5617. +};
  5618. +
  5619. +#define DECT_CCTRL_RELEASE_PMID_MASK 0x0000000fffff0000ULL
  5620. +#define DECT_CCTRL_RELEASE_PMID_SHIFT 16
  5621. +
  5622. +struct dect_cctrl {
  5623. + enum dect_cctrl_cmds cmd;
  5624. + u16 fmid;
  5625. + u32 pmid;
  5626. + union {
  5627. + struct {
  5628. + u8 lbn;
  5629. + u8 ecn;
  5630. + u8 type;
  5631. + u8 service;
  5632. + u8 slot;
  5633. + bool cf;
  5634. + u8 a_mod;
  5635. + u8 bz_mod;
  5636. + u8 bz_ext_mod;
  5637. + u8 acr;
  5638. + } attr;
  5639. + struct {
  5640. + u8 lbn;
  5641. + u8 reason;
  5642. + } rel;
  5643. + };
  5644. +};
  5645. +
  5646. +/* Encryption Control */
  5647. +
  5648. +#define DECT_ENCCTRL_FILL_MASK 0x0050000000000000ULL
  5649. +
  5650. +#define DECT_ENCCTRL_CMD_MASK 0x000f000000000000ULL
  5651. +#define DECT_ENCCTRL_CMD_SHIFT 48
  5652. +
  5653. +enum dect_encctrl_cmds {
  5654. + DECT_ENCCTRL_START_REQUEST = 0x0,
  5655. + DECT_ENCCTRL_START_CONFIRM = 0x1,
  5656. + DECT_ENCCTRL_START_GRANT = 0x2,
  5657. + DECT_ENCCTRL_STOP_REQUEST = 0x4,
  5658. + DECT_ENCCTRL_STOP_CONFIRM = 0x5,
  5659. + DECT_ENCCTRL_STOP_GRANT = 0x6,
  5660. +};
  5661. +
  5662. +#define DECT_ENCCTRL_FMID_MASK 0x0000fff000000000ULL
  5663. +#define DECT_ENCCTRL_FMID_SHIFT 36
  5664. +
  5665. +#define DECT_ENCCTRL_PMID_MASK 0x0000000fffff0000ULL
  5666. +#define DECT_ENCCTRL_PMID_SHIFT 16
  5667. +
  5668. +struct dect_encctrl {
  5669. + enum dect_encctrl_cmds cmd;
  5670. + u32 pmid;
  5671. + u16 fmid;
  5672. +};
  5673. +
  5674. +/* marker for T-MUX exceptions */
  5675. +#define DECT_MT_HIGH_PRIORITY 0x1
  5676. +
  5677. +/*
  5678. + * C_T data
  5679. + */
  5680. +
  5681. +#define DECT_C_S_SDU_SIZE 5
  5682. +
  5683. +struct dect_ct_data {
  5684. + u8 seq;
  5685. +};
  5686. +
  5687. +/*
  5688. + * Flat representation of tail message contents
  5689. + */
  5690. +enum dect_tail_msg_types {
  5691. + DECT_TM_TYPE_INVALID,
  5692. + DECT_TM_TYPE_ID,
  5693. + DECT_TM_TYPE_SSI,
  5694. + DECT_TM_TYPE_ERFC,
  5695. + DECT_TM_TYPE_FPC,
  5696. + DECT_TM_TYPE_EFPC,
  5697. + DECT_TM_TYPE_EFPC2,
  5698. + DECT_TM_TYPE_SARI,
  5699. + DECT_TM_TYPE_MFN,
  5700. + DECT_TM_TYPE_PAGE,
  5701. + DECT_TM_TYPE_BFS,
  5702. + DECT_TM_TYPE_BD,
  5703. + DECT_TM_TYPE_RFP_ID,
  5704. + DECT_TM_TYPE_RFP_STATUS,
  5705. + DECT_TM_TYPE_ACTIVE_CARRIERS,
  5706. + DECT_TM_TYPE_BCCTRL,
  5707. + DECT_TM_TYPE_ACCTRL,
  5708. + DECT_TM_TYPE_ENCCTRL,
  5709. + DECT_TM_TYPE_CT,
  5710. +};
  5711. +
  5712. +struct dect_tail_msg {
  5713. + enum dect_tail_identifications ti;
  5714. + enum dect_tail_msg_types type;
  5715. + union {
  5716. + struct dect_idi idi;
  5717. + struct dect_ssi ssi;
  5718. + struct dect_erfc erfc;
  5719. + struct dect_fpc fpc;
  5720. + struct dect_efpc efpc;
  5721. + struct dect_efpc2 efpc2;
  5722. + struct dect_sari sari;
  5723. + struct dect_mfn mfn;
  5724. + struct dect_page page;
  5725. + struct dect_bfs bfs;
  5726. + struct dect_bearer_desc bd;
  5727. + struct dect_rfp_id rfp_id;
  5728. + struct dect_rfp_status rfp_status;
  5729. + struct dect_active_carriers active_carriers;
  5730. + struct dect_cctrl cctl;
  5731. + struct dect_encctrl encctl;
  5732. + struct dect_ct_data ctd;
  5733. + };
  5734. +};
  5735. +
  5736. +struct dect_si {
  5737. + u32 mask;
  5738. + struct dect_ssi ssi;
  5739. + struct dect_erfc erfc;
  5740. + struct dect_fpc fpc;
  5741. + struct dect_efpc efpc;
  5742. + struct dect_efpc2 efpc2;
  5743. + struct dect_sari sari[DECT_SARI_CYCLE_MAX];
  5744. + struct dect_mfn mfn;
  5745. + u8 num_saris;
  5746. +};
  5747. +
  5748. +/*
  5749. + * B-Field
  5750. + */
  5751. +
  5752. +/**
  5753. + * dect_b_identitifications - MAC layer B-Field Identification
  5754. + *
  5755. + * @DECT_BI_UTYPE_0: U-Type, I_N, SI_N, SI_P or I_P packet number 0
  5756. + * @DECT_BI_UTYPE_1: U-Type, I_P error detect or I_P packet number 1
  5757. + * @DECT_BI_ETYPE_CF_0: E-Type, all C_F or CL_F, packet number 0
  5758. + * @DECT_BI_ETYPE_CF_1: E-Type, all C_F, packet number 1
  5759. + * @DECT_BI_ETYPE_MAC: E-Type, all MAC control (unnumbered)
  5760. + * @DECT_BI_NONE: no B-Field
  5761. + */
  5762. +enum dect_b_identifications {
  5763. + DECT_BI_UTYPE_0 = 0x0 << DECT_HDR_BA_SHIFT,
  5764. + DECT_BI_UTYPE_1 = 0x1 << DECT_HDR_BA_SHIFT,
  5765. + DECT_BI_ETYPE_CF_0 = 0x2 << DECT_HDR_BA_SHIFT,
  5766. + DECT_BI_DOUBLE_SLOT_REQUIRED = DECT_BI_ETYPE_CF_0,
  5767. + DECT_BI_ETYPE_CF_1 = 0x3 << DECT_HDR_BA_SHIFT,
  5768. + DECT_BI_ETYPE_NOT_ALL_CF_0 = 0x4 << DECT_HDR_BA_SHIFT,
  5769. + DECT_BI_HALF_SLOT_REQUIRED = DECT_BI_ETYPE_NOT_ALL_CF_0,
  5770. + DECT_BI_ETYPE_NOT_ALL_CF_1 = 0x5 << DECT_HDR_BA_SHIFT,
  5771. + DECT_BI_LONG_SLOT_640_REQUIRED = DECT_BI_ETYPE_NOT_ALL_CF_1,
  5772. + DECT_BI_ETYPE_MAC = 0x6 << DECT_HDR_BA_SHIFT,
  5773. + DECT_BI_LONG_SLOT_672_REQUIRED = DECT_BI_ETYPE_MAC,
  5774. + DECT_BI_NONE = 0x7 << DECT_HDR_BA_SHIFT,
  5775. +};
  5776. +
  5777. +struct dect_skb_b_cb {
  5778. + enum dect_b_identifications id;
  5779. +};
  5780. +
  5781. +#define DECT_B_CB(skb) ((struct dect_skb_b_cb *)(skb)->cb)
  5782. +
  5783. +#define DECT_C_F_SDU_SIZE 8
  5784. +#define DECT_G_F_SDU_SIZE 8
  5785. +
  5786. +/**
  5787. + * enum dect_mac_channels - internal MAC control channels
  5788. + *
  5789. + * @DECT_MC_Q: System information and multiframe marker
  5790. + * @DECT_MC_N: Identities information
  5791. + * @DECT_MC_M: MAC control channel
  5792. + * @DECT_MC_P: MAC Paging channel
  5793. + */
  5794. +enum dect_mac_channels {
  5795. + DECT_MC_Q,
  5796. + DECT_MC_N,
  5797. + DECT_MC_M,
  5798. + DECT_MC_P,
  5799. +};
  5800. +
  5801. +/**
  5802. + * enum dect_data_channels - logical MAC data channels
  5803. + *
  5804. + * @DECT_MC_G_F:
  5805. + * @DECT_MC_C_S: Higher layer C-Plane channel (slow)
  5806. + * @DECT_MC_C_F: Higher layer C-Plane channel (fast)
  5807. + * @DECT_MC_I_N: Higher layer U-Plane channel (numbered)
  5808. + * @DECT_MC_I_P: Higher layer U-Plane channel (protected)
  5809. + * @DECT_MC_SI_N: Higher layer connectionless U-Plane channel (numbered)
  5810. + * @DECT_MC_SI_P: Higher layer connectionless U-Plane channel (protected)
  5811. + */
  5812. +enum dect_data_channels {
  5813. + DECT_MC_G_F,
  5814. + DECT_MC_C_S,
  5815. + DECT_MC_C_F,
  5816. + DECT_MC_I_N,
  5817. + DECT_MC_I_P,
  5818. + DECT_MC_SI_N,
  5819. + DECT_MC_SI_P,
  5820. + __DECT_MC_MAX
  5821. +};
  5822. +#define DECT_MC_MAX (__DECT_MC_MAX - 1)
  5823. +
  5824. +/**
  5825. + * struct dect_tbc_id
  5826. + *
  5827. + * @ari: FT identifier
  5828. + * @pmid: Portable MAC identity
  5829. + * @lbn: Logical Bearer Number
  5830. + * @enc: Exchanged connection number
  5831. + * @tbei: Traffic Bearer Endpoint Identifier
  5832. + */
  5833. +struct dect_tbc_id {
  5834. + struct dect_ari ari;
  5835. + struct dect_pmid pmid;
  5836. + u8 lbn;
  5837. + u8 ecn;
  5838. + u32 tbei;
  5839. +};
  5840. +
  5841. +/**
  5842. + * struct dect_mbc_id
  5843. + *
  5844. + * @mcei: MAC Connection Endpoint Identifier
  5845. + * @ari: FT identifier
  5846. + * @pmid: Portable MAC Identity
  5847. + * @ecn: Exchanged Connection Number
  5848. + * @service: Service type
  5849. + */
  5850. +struct dect_mbc_id {
  5851. + u32 mcei;
  5852. + struct dect_ari ari;
  5853. + struct dect_pmid pmid;
  5854. + u8 ecn;
  5855. +};
  5856. +
  5857. +#endif /* _NET_DECT_MAC_H */
  5858. diff --git a/include/net/dect/mac_ccf.h b/include/net/dect/mac_ccf.h
  5859. new file mode 100644
  5860. index 0000000..31ba6ab
  5861. --- /dev/null
  5862. +++ b/include/net/dect/mac_ccf.h
  5863. @@ -0,0 +1,251 @@
  5864. +/*
  5865. + * DECT MAC Layer - Cluster Control Functions (CCF)
  5866. + *
  5867. + * Copyright (c) 2009 Patrick McHardy <[email protected]>
  5868. + */
  5869. +
  5870. +#ifndef _NET_DECT_MAC_CCF_H
  5871. +#define _NET_DECT_MAC_CCF_H
  5872. +
  5873. +#include <linux/skbuff.h>
  5874. +#include <linux/timer.h>
  5875. +#include <net/dect/mac.h>
  5876. +
  5877. +/**
  5878. + * struct dect_bmc_skb_cb
  5879. + *
  5880. + * @fast_page: page message is a fast page
  5881. + * @long_page: page message is a long page
  5882. + * @stamp: multiframe number at time of TX request
  5883. + * @repetitions: number of page repetitions
  5884. + */
  5885. +struct dect_bmc_skb_cb {
  5886. + bool fast_page;
  5887. + bool long_page;
  5888. + u32 stamp;
  5889. + u8 repetitions;
  5890. +};
  5891. +#define DECT_BMC_CB(skb) ((struct dect_bmc_skb_cb *)(skb)->cb)
  5892. +
  5893. +#define DECT_PAGE_LIFETIME 6 /* multiframes */
  5894. +
  5895. +/**
  5896. + * struct dect_bmc - broadcast message control
  5897. + *
  5898. + * @bcs: broadcast controller list
  5899. + * @index: system information round robin index
  5900. + */
  5901. +struct dect_bmc {
  5902. + struct list_head bcs;
  5903. + unsigned int index;
  5904. +};
  5905. +
  5906. +struct dect_cmc {
  5907. +
  5908. +};
  5909. +
  5910. +struct dect_cs_skb_cb {
  5911. + u8 seq;
  5912. +};
  5913. +#define DECT_CS_CB(skb) ((struct dect_cs_skb_cb *)(skb)->cb)
  5914. +
  5915. +/**
  5916. + * struct dect_tb - DECT Traffic Bearer
  5917. + *
  5918. + * @list: MBC traffic bearer list node
  5919. + * @mbc: MBC controlling the traffic bearer
  5920. + * @ch: Cell handling the traffic bearer
  5921. + * @id: Traffic Bearer Controller ID
  5922. + * @handover: Handover yes/no
  5923. + * @handover_timer: Handover timer
  5924. + * @rx_slot: Receive slot
  5925. + * @tx_slot: Transmit slot
  5926. + * @slot_rx_timer: Receive slot timer
  5927. + * @slot_tx_timer: Transmit slot timer
  5928. + * @b_rx_skb: B-Field receive skb
  5929. + */
  5930. +struct dect_tb {
  5931. + struct list_head list;
  5932. + struct dect_mbc *mbc;
  5933. + const struct dect_cell_handle *ch;
  5934. + struct dect_tbc_id id;
  5935. + bool handover;
  5936. +
  5937. + /* FP: handover release timer */
  5938. + struct dect_timer handover_timer;
  5939. +
  5940. + /* Slot transmit/receive timers */
  5941. + u8 rx_slot;
  5942. + u8 tx_slot;
  5943. + struct dect_timer slot_rx_timer;
  5944. + struct dect_timer slot_tx_timer;
  5945. +
  5946. + /* I channel data */
  5947. + struct sk_buff *b_rx_skb;
  5948. +};
  5949. +
  5950. +struct dect_mbc_stats {
  5951. + unsigned int cs_rx_bytes;
  5952. + unsigned int cs_tx_bytes;
  5953. + unsigned int i_rx_bytes;
  5954. + unsigned int i_tx_bytes;
  5955. + unsigned int handovers;
  5956. +};
  5957. +
  5958. +/**
  5959. + * struct dect_mbc - DECT Multi-Bearer Control
  5960. + *
  5961. + * @list: Cluster connection list node
  5962. + * @cl: Cluster the MBC is contained in
  5963. + * @refcnt: Reference count
  5964. + * @id: MBC identity
  5965. + * @state: MBC state
  5966. + * @timer: Connection setup timer (T200)
  5967. + * @setup_cnt: number of setup attempts (N200)
  5968. + * @tbs: List of traffic bearers
  5969. + * @ho_stamp: Handover token bucket refill timestamp
  5970. + * @ho_tokens: Handover token bucket tokens
  5971. + * @normal_rx_timer: Normal receive half frame timer
  5972. + * @onrmal_tx_timer: Normal transmit half frame timer
  5973. + * @ck: Cipher key
  5974. + * @cipher_state: Ciphering state
  5975. + * @cs_rx_seq: C_S receive sequence number
  5976. + * @cs_tx_seq: C_S transmit sequence number
  5977. + * @cs_tx_ok: C_S segment transmit OK
  5978. + * @cs_rx_ok: C_S segment reception OK
  5979. + * @cs_tx_skb: C_S segment queued for transmission
  5980. + * @cs_tx_skb: C_S segment queued for delivery to DLC
  5981. + */
  5982. +struct dect_mbc {
  5983. + struct list_head list;
  5984. + struct dect_cluster *cl;
  5985. + unsigned int refcnt;
  5986. +
  5987. + struct dect_mbc_id id;
  5988. + struct dect_mac_conn_params mcp;
  5989. + enum dect_mbc_state state;
  5990. +
  5991. + struct timer_list timer;
  5992. + u8 setup_cnt;
  5993. +
  5994. + struct list_head tbs;
  5995. +
  5996. + /* Handover rate limiting */
  5997. + unsigned long ho_stamp;
  5998. + u8 ho_tokens;
  5999. +
  6000. + /* Normal transmit/receive timers */
  6001. + struct dect_timer normal_rx_timer;
  6002. + struct dect_timer normal_tx_timer;
  6003. +
  6004. + /* Encryption */
  6005. + u64 ck;
  6006. + enum dect_cipher_states cipher_state;
  6007. +
  6008. + /* C_S channel */
  6009. + u8 cs_rx_seq;
  6010. + u8 cs_tx_seq;
  6011. + bool cs_tx_ok;
  6012. + bool cs_rx_ok;
  6013. + struct sk_buff *cs_rx_skb;
  6014. + struct sk_buff *cs_tx_skb;
  6015. +
  6016. + struct dect_mbc_stats stats;
  6017. +};
  6018. +
  6019. +#define DECT_MBC_SETUP_TIMEOUT (5 * HZ) /* T200: 5 seconds */
  6020. +#define DECT_MBC_SETUP_MAX_ATTEMPTS 10 /* N200: 10 attempts */
  6021. +#define DECT_MBC_HANDOVER_TIMER (3 * HZ) /* T202: 3 seconds */
  6022. +#define DECT_MBC_TB_HANDOVER_TIMEOUT 16 /* T203: 16 frames */
  6023. +
  6024. +#define DECT_MBC_HANDOVER_LIMIT 2 /* per N202 seconds */
  6025. +#define DECT_MBC_HANDOVER_REATTEMPTS 15 /* N201: 15 */
  6026. +
  6027. +extern u32 dect_mbc_alloc_mcei(struct dect_cluster *cl);
  6028. +extern int dect_mac_con_req(struct dect_cluster *cl,
  6029. + const struct dect_mbc_id *id,
  6030. + const struct dect_mac_conn_params *mcp);
  6031. +extern void dect_mac_dis_req(struct dect_cluster *cl, u32 mcei);
  6032. +
  6033. +extern int dect_mac_enc_key_req(const struct dect_cluster *cl, u32 mcei, u64 ck);
  6034. +extern int dect_mac_enc_eks_req(const struct dect_cluster *cl, u32 mcei,
  6035. + enum dect_cipher_states status);
  6036. +
  6037. +extern void dect_bmc_mac_page_req(struct dect_cluster *cl, struct sk_buff *skb);
  6038. +
  6039. +extern u8 dect_b_field_size(enum dect_slot_types slot);
  6040. +
  6041. +struct dect_llme_req;
  6042. +
  6043. +/**
  6044. + * struct dect_ccf_ops - Cluster Control Ops
  6045. + *
  6046. + * @bind: bind cell to cluster
  6047. + * @unbind: unbind cell from cluster
  6048. + * @mac_info_indicate: indicate FP mac layer information (PP only)
  6049. + * @mbc_conn_indicate: indicate a new TBC connection
  6050. + * @mbc_conn_notify: notify MBC of TBC events
  6051. + * @mbc_data_indicate: indicate new data to MBC
  6052. + * @bmc_page_indicate: indicate reception of a page message to the BMC
  6053. + */
  6054. +struct dect_cluster_handle;
  6055. +struct dect_scan_result;
  6056. +enum dect_tbc_event;
  6057. +struct dect_ccf_ops {
  6058. + int (*bind)(struct dect_cluster_handle *,
  6059. + struct dect_cell_handle *);
  6060. + void (*unbind)(struct dect_cluster_handle *,
  6061. + struct dect_cell_handle *);
  6062. +
  6063. + void (*time_ind)(struct dect_cluster_handle *,
  6064. + enum dect_timer_bases, u32, u8, u8);
  6065. +
  6066. + void (*scan_report)(const struct dect_cluster_handle *,
  6067. + const struct dect_scan_result *);
  6068. +
  6069. + void (*mac_info_ind)(const struct dect_cluster_handle *,
  6070. + const struct dect_idi *,
  6071. + const struct dect_si *);
  6072. +
  6073. + int (*tbc_establish_ind)(const struct dect_cluster_handle *,
  6074. + const struct dect_cell_handle *,
  6075. + const struct dect_tbc_id *,
  6076. + const struct dect_mac_conn_params *, bool);
  6077. + int (*tbc_establish_cfm)(const struct dect_cluster_handle *,
  6078. + const struct dect_tbc_id *, bool, u8);
  6079. + void (*tbc_dis_ind)(const struct dect_cluster_handle *,
  6080. + const struct dect_tbc_id *,
  6081. + enum dect_release_reasons);
  6082. + int (*tbc_event_ind)(const struct dect_cluster_handle *,
  6083. + const struct dect_tbc_id *,
  6084. + enum dect_tbc_event);
  6085. + void (*tbc_data_ind)(const struct dect_cluster_handle *,
  6086. + const struct dect_tbc_id *,
  6087. + enum dect_data_channels chan,
  6088. + struct sk_buff *);
  6089. + int (*tbc_handover_req)(const struct dect_cluster_handle *,
  6090. + const struct dect_tbc_id *);
  6091. +
  6092. + void (*bmc_page_ind)(const struct dect_cluster_handle *,
  6093. + struct sk_buff *);
  6094. +};
  6095. +
  6096. +/**
  6097. + * struct dect_cluster_handle - Cell's view of a cluster
  6098. + *
  6099. + * @ops: Cluster Control Function ops
  6100. + * @index: Cluster index
  6101. + * @tipc_id: Cluster TIPC user ID
  6102. + * @tportref: Topology Service port reference (remote cluster only)
  6103. + * @portref: Cell Control Protocol port reference (remote cluster only)
  6104. + */
  6105. +struct dect_cluster_handle {
  6106. + const struct dect_ccf_ops *ops;
  6107. + u8 index;
  6108. +
  6109. + u32 tipc_id;
  6110. + u32 tportref;
  6111. + u32 portref;
  6112. +};
  6113. +
  6114. +#endif /* _NET_DECT_MAC_CCF_H */
  6115. diff --git a/include/net/dect/mac_csf.h b/include/net/dect/mac_csf.h
  6116. new file mode 100644
  6117. index 0000000..301fdc1
  6118. --- /dev/null
  6119. +++ b/include/net/dect/mac_csf.h
  6120. @@ -0,0 +1,604 @@
  6121. +/*
  6122. + * DECT MAC Layer - Cell Site Functions (CSF)
  6123. + *
  6124. + * Copyright (c) 2009 Patrick McHardy <[email protected]>
  6125. + */
  6126. +
  6127. +#ifndef _NET_DECT_MAC_CSF_H
  6128. +#define _NET_DECT_MAC_CSF_H
  6129. +
  6130. +#include <net/dect/mac.h>
  6131. +#include <net/dect/transceiver.h>
  6132. +#define DECT_CHANNEL_LIST_DBM_RES 6
  6133. +#define DECT_CHANNEL_LIST_BINS (DECT_RSSI_DBM_RANGE / DECT_CHANNEL_LIST_DBM_RES)
  6134. +
  6135. +/**
  6136. + * struct dect_channel_list_entry
  6137. + *
  6138. + * @list: channel list bin node
  6139. + * @slot: slot number
  6140. + * @carrier: RF-carrier
  6141. + * @rssi: measured RSSI value
  6142. + */
  6143. +struct dect_channel_list_entry {
  6144. + struct list_head list;
  6145. + u8 slot;
  6146. + u8 carrier;
  6147. + u8 rssi;
  6148. +};
  6149. +
  6150. +/**
  6151. + * struct dect_channel_list - Basic channel list
  6152. + *
  6153. + * @list: cell's channel lists list node
  6154. + * @pkt: packet type used for RSSI measurement
  6155. + * @status: bitmask of completed carriers
  6156. + * @timer: update timer
  6157. + * @available: number of available entries
  6158. + * @bins: channels ordered by RSSI value
  6159. + * @entries: channel list entries
  6160. + *
  6161. + * A channel list contains channel descriptions of all physical channels
  6162. + * able to carry the packet type, sorted into multiple bins based on the
  6163. + * maximum RSSI value of the TDD slot pair.
  6164. + */
  6165. +struct dect_channel_list {
  6166. + struct list_head list;
  6167. + enum dect_packet_types pkt;
  6168. + u64 status;
  6169. +
  6170. + struct dect_timer timer;
  6171. + u16 available;
  6172. + struct list_head bins[DECT_CHANNEL_LIST_BINS];
  6173. + struct dect_channel_list_entry entries[];
  6174. +};
  6175. +
  6176. +#define DECT_CHANNEL_LIST_MAX_AGE 30 /* T209: 30 seconds */
  6177. +#define DECT_CHANNEL_LIST_MAX_DBM -50 /* dBm */
  6178. +#define DECT_CHANNEL_LIST_LOW_WATERMARK 20 /* channels */
  6179. +
  6180. +#define DECT_CHANNEL_MIN_DELAY 2 /* frames */
  6181. +
  6182. +enum dect_bearer_states {
  6183. + DECT_DUMMY_BEARER,
  6184. + DECT_TRAFFIC_BEARER,
  6185. + DECT_CL_BEARER,
  6186. + DECT_MONITOR_BEARER,
  6187. +};
  6188. +
  6189. +enum dect_bearer_modes {
  6190. + DECT_BEARER_RX,
  6191. + DECT_BEARER_TX,
  6192. +};
  6193. +
  6194. +/**
  6195. + * enum dect_bearer_state - DECT MAC bearer states
  6196. + *
  6197. + * @DECT_BEARER_INACTIVE: bearer inactive
  6198. + * @DECT_BEARER_SCHEDULED: bearer is scheduled for activation
  6199. + * @DECT_BEARER_RSSI_CONFIRM: bearer is scheduled for RSSI confirmation
  6200. + * @DECT_BEARER_RSSI_CONFIRMED: RSSI is confirmed, bearer is scheduled for e
  6201. + * @DECT_BEARER_ENABLED: bearer is enabled
  6202. + */
  6203. +enum dect_bearer_state {
  6204. + DECT_BEARER_INACTIVE,
  6205. + DECT_BEARER_SCHEDULED,
  6206. + DECT_BEARER_RSSI_CONFIRM,
  6207. + DECT_BEARER_RSSI_CONFIRMED,
  6208. + DECT_BEARER_ENABLED,
  6209. +};
  6210. +
  6211. +struct dect_bearer;
  6212. +struct dect_bearer_ops {
  6213. + enum dect_bearer_states state;
  6214. + void (*enable)(struct dect_cell *, struct dect_bearer *);
  6215. + void (*report_rssi)(struct dect_cell *, struct dect_bearer *,
  6216. + u8 slot, u8 rssi);
  6217. + void (*rcv)(struct dect_cell *cell, struct dect_bearer *,
  6218. + struct sk_buff *);
  6219. +};
  6220. +
  6221. +/**
  6222. + * struct dect_bearer - DECT MAC Bearer
  6223. + *
  6224. + * @type: bearer type
  6225. + * @state: operational state
  6226. + * @trx: DECT transceiver
  6227. + * @chd: channel description
  6228. + * @mode: bearer mode (RX/TX)
  6229. + * @tx_timer: TX enable timer
  6230. + * @rssi: last measured RSSI of selected channel
  6231. + * @m_tx_queue: M-channel TX queue
  6232. + * @q: Hdr-field MUX for Q1/Q2 bit settings
  6233. + * @union: bearer type specific data
  6234. + */
  6235. +struct dect_bearer {
  6236. + const struct dect_bearer_ops *ops;
  6237. + struct dect_transceiver *trx;
  6238. + struct dect_channel_desc chd;
  6239. + enum dect_bearer_modes mode;
  6240. + enum dect_bearer_state state;
  6241. + struct dect_timer tx_timer;
  6242. + u8 rssi;
  6243. +
  6244. + struct sk_buff_head m_tx_queue;
  6245. + u8 q;
  6246. +
  6247. + union {
  6248. + struct dect_dbc *dbc;
  6249. + struct dect_cbc *cbc;
  6250. + struct dect_tbc *tbc;
  6251. + struct dect_dmb *dmb;
  6252. + struct dect_irc *irc;
  6253. + void *data;
  6254. + };
  6255. +};
  6256. +
  6257. +/**
  6258. + * struct dect_bc - broadcast controller
  6259. + *
  6260. + * @list: broadcast message control BC list node
  6261. + * @p_rx_skb: current RX P-channel message
  6262. + * @p_tx_mask: bitmask of scheduled mac layer pages
  6263. + */
  6264. +struct dect_bc {
  6265. + struct list_head list;
  6266. + struct sk_buff *p_rx_skb;
  6267. + u32 p_tx_mask;
  6268. +};
  6269. +
  6270. +/*
  6271. + * enum dect_bearer_qctrl_state - DECT bearer quality control state
  6272. + *
  6273. + * @DECT_BEARER_QCTRL_WAIT: waiting for next quality control event
  6274. + * @DECT_BEARER_QCTRL_CONFIRM: performing quality control
  6275. + */
  6276. +enum dect_bearer_qctrl_state {
  6277. + DECT_BEARER_QCTRL_WAIT,
  6278. + DECT_BEARER_QCTRL_CONFIRM,
  6279. +};
  6280. +
  6281. +#define DECT_BEARER_QCTRL_FRAMENUM 15 /* must not affect paging */
  6282. +#define DECT_BEARER_QCTRL_PERIOD 256 /* frames */
  6283. +
  6284. +/**
  6285. + * struct dect_dbc - dummy bearer control
  6286. + *
  6287. + * @list: cell dbc list node
  6288. + * @cell: DECT cell
  6289. + * @bearer: dummy bearer
  6290. + * @qctrl_timer: quality control timer
  6291. + * @qctrl_state: qaulity control state
  6292. + * @bc: broadcast controller
  6293. + */
  6294. +struct dect_dbc {
  6295. + struct list_head list;
  6296. + struct dect_cell *cell;
  6297. + struct dect_bearer bearer;
  6298. + struct dect_timer qctrl_timer;
  6299. + enum dect_bearer_qctrl_state qctrl;
  6300. + struct dect_bc bc;
  6301. +};
  6302. +
  6303. +/*
  6304. + * struct dect_cbc - connectionless bearer control
  6305. + *
  6306. + * @cell: DECT cell
  6307. + * @dl_bearer: connectionless downlink bearer
  6308. + * @ul_bearer: connectionless uplink bearer, if present
  6309. + * @bc: broadcast controller
  6310. + */
  6311. +struct dect_cbc {
  6312. + struct dect_cell *cell;
  6313. + struct dect_bearer dl_bearer;
  6314. + struct dect_bearer ul_bearer;
  6315. + struct dect_bc bc;
  6316. +};
  6317. +
  6318. +/**
  6319. + * enum dect_tbc_state - DECT Traffic Bearer Controller state
  6320. + *
  6321. + * @DECT_TBC_NONE: Initial state
  6322. + * @DECT_TBC_REQ_SENT: Initiator: bearer request sent
  6323. + * @DECT_TBC_WAIT_RCVD: Initiator: intermediate state
  6324. + * @DECT_TBC_REQ_RCVD: Responder: request received
  6325. + * @DECT_TBC_RESPONSE_SENT: Responder: immediate response to request sent
  6326. + * @DECT_TBC_ATTRIBUTES_SENT: Initiator: attributes-T request sent
  6327. + * @DECT_TBC_OTHER_WAIT: Waiting for "other" message
  6328. + * @DECT_TBC_ESTABLISHED Established
  6329. + * @DECT_TBC_RELEASING First RELEASE message sent
  6330. + * @DECT_TBC_RELEASED: Second RELEASE message sent
  6331. + */
  6332. +enum dect_tbc_state {
  6333. + DECT_TBC_NONE,
  6334. + DECT_TBC_REQ_SENT,
  6335. + DECT_TBC_WAIT_RCVD,
  6336. + DECT_TBC_REQ_RCVD,
  6337. + DECT_TBC_RESPONSE_SENT,
  6338. + DECT_TBC_ATTRIBUTES_SENT,
  6339. + DECT_TBC_OTHER_WAIT,
  6340. + DECT_TBC_ESTABLISHED,
  6341. + DECT_TBC_RELEASING,
  6342. + DECT_TBC_RELEASED,
  6343. +};
  6344. +
  6345. +/**
  6346. + * enum dect_tbc_enc_state - DECT Traffic Bearer encryption state
  6347. + *
  6348. + * @DECT_TBC_ENC_DISABLED: Encryption is disabled
  6349. + * @DECT_TBC_ENC_START_REQ_RCVD: Start request received (FP)
  6350. + * @DECT_TBC_ENC_START_REQ_SENT: Start request sent (PP)
  6351. + * @DECT_TBC_ENC_START_CFM_RCVD: Start confirm received (PP)
  6352. + * @DECT_TBC_ENC_START_CFM_SENT: Start confirm sent (FP)
  6353. + * @DECT_TBC_ENC_STOP_REQ_RCVD: Stop request received (FP)
  6354. + * @DECT_TBC_ENC_STOP_REQ_SENT: Stop request sent (PP)
  6355. + * @DECT_TBC_ENC_STOP_CFM_RCVD: Stop confirm received (PP)
  6356. + * @DECT_TBC_ENC_STOP_CFM_SENT: Stop confirm sent (FP)
  6357. + * @DECT_TBC_ENC_ENABLED: Encryption is enabled
  6358. + */
  6359. +enum dect_tbc_enc_state {
  6360. + DECT_TBC_ENC_DISABLED,
  6361. + DECT_TBC_ENC_START_REQ_RCVD,
  6362. + DECT_TBC_ENC_START_REQ_SENT,
  6363. + DECT_TBC_ENC_START_CFM_RCVD,
  6364. + DECT_TBC_ENC_START_CFM_SENT,
  6365. + DECT_TBC_ENC_STOP_REQ_RCVD,
  6366. + DECT_TBC_ENC_STOP_REQ_SENT,
  6367. + DECT_TBC_ENC_STOP_CFM_RCVD,
  6368. + DECT_TBC_ENC_STOP_CFM_SENT,
  6369. + DECT_TBC_ENC_ENABLED,
  6370. +};
  6371. +
  6372. +/**
  6373. + * enum dect_tbc_event - DECT Traffic Bearer events
  6374. + *
  6375. + * @DECT_TBC_ACK_RECEIVED: Acknowledgement for C_S data received
  6376. + * @DECT_TBC_CIPHER_ENABLED: Ciphering enabled
  6377. + * @DECT_TBC_CIPHER_DISABLED: Ciphering disabled
  6378. + */
  6379. +enum dect_tbc_event {
  6380. + DECT_TBC_ACK_RECEIVED,
  6381. + DECT_TBC_CIPHER_ENABLED,
  6382. + DECT_TBC_CIPHER_DISABLED,
  6383. +};
  6384. +
  6385. +/**
  6386. + * struct dect_tbc - DECT Traffic Bearer Control
  6387. + *
  6388. + * @list: Cell TBC list node
  6389. + * @cell: DECT cell
  6390. + * @id: Traffic Bearer ID
  6391. + * @txb: TX bearer
  6392. + * @rxb: RX bearer
  6393. + * @state: Bearer establishment state
  6394. + * @tx_timer: Transmit activation timer
  6395. + * @wd_timer: Receive watchdog timer
  6396. + * @release_timer: Release timer for unacknowledged release procedure
  6397. + * @release_reason: release reason
  6398. + * @normal_tx_timer: Normal transmit timer for C-channel/I_N normal delay transmission
  6399. + * @normal_rx_timer: Normal receive timer for C-channel/I_N normal delay delivery
  6400. + * @rx_timer: Mimimum delay receive timer
  6401. + * @tx_timer: Minimum delay transmit timer
  6402. + * @ck: Cipher key
  6403. + * @enc_timer: Encryption TX timer
  6404. + * @enc_state: Encryption state
  6405. + * @enc_msg_cnt: Encryption message retransmit counter
  6406. + * @c_rx_skb: C_S segment for delivery to DLC
  6407. + * @c_tx_skb: C_S segment for transmission in next TDMA frame
  6408. + * @c_tx_ok: C_S segment was successfully transmitted
  6409. + * @b_rx_skb: B-field data segment for delivery to DLC
  6410. + * @b_tx_skb: B-field data segment for transmission in next TDMA frame
  6411. + * @bc: Broadcast Control
  6412. + */
  6413. +struct dect_tbc {
  6414. + struct list_head list;
  6415. + struct dect_cell *cell;
  6416. + struct dect_tbc_id id;
  6417. + struct dect_mac_conn_params mcp;
  6418. + bool handover;
  6419. +
  6420. + struct dect_bearer txb;
  6421. + struct dect_bearer rxb;
  6422. +
  6423. + enum dect_tbc_state state;
  6424. + struct dect_timer wait_timer;
  6425. + struct dect_timer wd_timer;
  6426. +
  6427. + struct dect_timer release_timer;
  6428. + enum dect_release_reasons release_reason;
  6429. +
  6430. + /* PP handover trigger */
  6431. + s8 handover_tokens;
  6432. +
  6433. + /* Encryption */
  6434. + u64 ck;
  6435. + struct dect_timer enc_timer;
  6436. + enum dect_tbc_enc_state enc_state:8;
  6437. + u8 enc_msg_cnt;
  6438. +
  6439. + /* C_S channel */
  6440. + struct sk_buff *cs_tx_skb;
  6441. + bool cs_tx_ok;
  6442. +
  6443. + /* I channel */
  6444. + struct sk_buff *b_tx_skb;
  6445. +
  6446. + struct dect_bc bc;
  6447. +};
  6448. +
  6449. +#define DECT_TBC_RFPI_TIMEOUT (5 * DECT_FRAMES_PER_SECOND)
  6450. +
  6451. +#define DECT_TBC_HO_TOKENS_INITIAL 16
  6452. +#define DECT_TBC_HO_TOKENS_OK 1 /* Correct slot adds one token */
  6453. +#define DECT_TBC_HO_TOKENS_ERROR 8 /* Error slot subtracts eight tokens */
  6454. +#define DECT_TBC_HO_TOKENS_MAX 32
  6455. +
  6456. +enum dect_scan_status {
  6457. + DECT_SCAN_FAIL,
  6458. + DECT_SCAN_TIMEOUT,
  6459. + DECT_SCAN_COMPLETE,
  6460. +};
  6461. +
  6462. +/**
  6463. + * struct dect_dmb - Monitor Bearer
  6464. + *
  6465. + * @list: cell dmbs list node
  6466. + * @cell: DECT cell
  6467. + * @rxb1: receive bearer 1
  6468. + * @rxb2: receive bearer 2
  6469. + */
  6470. +struct dect_dmb {
  6471. + struct list_head list;
  6472. + struct dect_cell *cell;
  6473. +
  6474. + struct dect_timer wd_timer;
  6475. + struct dect_bearer rxb1;
  6476. + struct dect_bearer rxb2;
  6477. + struct dect_bc bc;
  6478. +};
  6479. +
  6480. +/**
  6481. + * struct dect_irc - Idle receiver control
  6482. + *
  6483. + * @cell: DECT cell
  6484. + * @trx: DECT transceiver
  6485. + * @ari: ARI filter
  6486. + * @ari_mask: ARI filter mask
  6487. + * @idi: identities information
  6488. + * @si: system information
  6489. + * @notify: notification callback
  6490. + * @rx_scn: Scan carrier number (RX time base)
  6491. + * @tx_scn: Scan carrier number (TX time base)
  6492. + * @rx_frame_timer: rx_scn update timer
  6493. + * @tx_frame_timer: tx_scn update timer
  6494. + */
  6495. +struct dect_irc {
  6496. + struct dect_cell *cell;
  6497. + struct dect_transceiver *trx;
  6498. +
  6499. + struct dect_llme_req lreq;
  6500. +
  6501. + struct dect_ari ari;
  6502. + struct dect_ari ari_mask;
  6503. +
  6504. + u16 timeout;
  6505. + u16 rssi;
  6506. + struct dect_idi idi;
  6507. + struct dect_si si;
  6508. +
  6509. + void (*notify)(struct dect_cell *,
  6510. + struct dect_transceiver *,
  6511. + enum dect_scan_status);
  6512. +
  6513. + u8 rx_scn;
  6514. + u8 tx_scn;
  6515. + struct dect_timer rx_frame_timer;
  6516. + struct dect_timer tx_frame_timer;
  6517. + struct dect_bearer scan_bearer;
  6518. +};
  6519. +
  6520. +#define DECT_IRC_SCN_OFF 3
  6521. +
  6522. +struct dect_scan_result {
  6523. + struct dect_llme_req lreq;
  6524. + struct dect_idi idi;
  6525. + struct dect_si si;
  6526. + u16 rssi;
  6527. +};
  6528. +
  6529. +/**
  6530. + * struct dect_csf_ops - Cell Site Function ops
  6531. + *
  6532. + * @set_mode: set cell to PP/FP mode
  6533. + * @scan: initiate scan for pari/pari_mask
  6534. + * @preload: preload system information
  6535. + * @enable: enable cell
  6536. + * @page_request: deliver paging message
  6537. + * @tbc_initiate: initiate a new connection
  6538. + * @tbc_confirm: confirm an incoming connection
  6539. + * @tbc_release: release a TBC
  6540. + * @tbc_enc_key_request: set encryption key
  6541. + * @tbc_enc_eks_request: enable/disable encryption
  6542. + *
  6543. + * The CSF ops define the interface in the direction CCF -> CSF.
  6544. + */
  6545. +struct dect_cell_handle;
  6546. +struct dect_csf_ops {
  6547. + int (*set_mode)(const struct dect_cell_handle *,
  6548. + enum dect_cluster_modes);
  6549. + int (*scan)(const struct dect_cell_handle *,
  6550. + const struct dect_llme_req *lreq,
  6551. + const struct dect_ari *, const struct dect_ari *);
  6552. + int (*preload)(const struct dect_cell_handle *,
  6553. + const struct dect_ari *, u8,
  6554. + const struct dect_si *);
  6555. + int (*enable)(const struct dect_cell_handle *);
  6556. +
  6557. + void (*page_req)(const struct dect_cell_handle *, struct sk_buff *);
  6558. +
  6559. + int (*tbc_establish_req)(const struct dect_cell_handle *,
  6560. + const struct dect_tbc_id *,
  6561. + const struct dect_mac_conn_params *, bool);
  6562. + int (*tbc_establish_res)(const struct dect_cell_handle *,
  6563. + const struct dect_tbc_id *);
  6564. + void (*tbc_dis_req)(const struct dect_cell_handle *,
  6565. + const struct dect_tbc_id *,
  6566. + enum dect_release_reasons);
  6567. + int (*tbc_enc_key_req)(const struct dect_cell_handle *,
  6568. + const struct dect_tbc_id *, u64 ck);
  6569. + int (*tbc_enc_eks_req)(const struct dect_cell_handle *,
  6570. + const struct dect_tbc_id *,
  6571. + enum dect_cipher_states status);
  6572. + int (*tbc_enc_req)(const struct dect_cell_handle *,
  6573. + const struct dect_tbc_id *, u64 ck);
  6574. + void (*tbc_data_req)(const struct dect_cell_handle *,
  6575. + const struct dect_tbc_id *,
  6576. + enum dect_data_channels chan,
  6577. + struct sk_buff *);
  6578. +
  6579. +};
  6580. +
  6581. +/**
  6582. + * struct dect_cell_handle - DECT cluster view of a cell
  6583. + *
  6584. + * @list: cluster cell list node
  6585. + * @clh: bound cluster handle
  6586. + * @ops: cell site function ops
  6587. + * @rpn: assigned radio part number
  6588. + * @portref: cell control protocol port reference (remote cells)
  6589. + */
  6590. +struct dect_cell_handle {
  6591. + struct list_head list;
  6592. + struct dect_cluster_handle *clh;
  6593. + const struct dect_csf_ops *ops;
  6594. + u8 rpn;
  6595. +
  6596. + u32 portref;
  6597. +};
  6598. +
  6599. +enum dect_cell_states {
  6600. + DECT_CELL_ENABLED = 1 << 0,
  6601. +};
  6602. +
  6603. +/**
  6604. + * struct dect_cell - DECT cell: one radio system
  6605. + *
  6606. + * @list: cell list node
  6607. + * @name: cells' name
  6608. + * @index: unique numeric cell identifier
  6609. + * @flags: operational and status flags
  6610. + * @handle: cell handle
  6611. + * @lock: lock
  6612. + * @mode: operational mode (FP/PP)
  6613. + * @state: bitmask of enum dect_cell_states
  6614. + * @idi: FP System Identity
  6615. + * @fmid: FMID (Fixed MAC IDentity)
  6616. + * @si: FP System Information
  6617. + * @timer_sync_stamp: Time (multiframe number) of last multiframe number sync
  6618. + * @a_rcv_stamp: Time (jiffies) of last received A-Field with correct CRC
  6619. + * @nt_rcv_stamp: Time (jiffies) of last received Nt-Tail containing the PARI
  6620. + * @bcs: Broadcast Controllers
  6621. + * @cbc: Connectionless Bearer Controller
  6622. + * @dbcs: Dummy Bearer Controllers
  6623. + * @tbcs: list of Traffic Bearer Controllers
  6624. + * @tbc_num_est: Number of TBCs in ESTABLISHED state
  6625. + * @tbc_last_chd: Channel description of last TBC leaving ESTABLISHED state
  6626. + * @dmbs: list of Monitor Bearers
  6627. + * @chanlists: list of channel lists for different channel types
  6628. + * @timer_base: RX/TX timer bases
  6629. + * @trg: DECT transceiver group
  6630. + */
  6631. +struct dect_cell {
  6632. + struct list_head list;
  6633. + char name[DECTNAMSIZ];
  6634. + u32 index;
  6635. + u32 flags;
  6636. +
  6637. + struct dect_cell_handle handle;
  6638. +
  6639. + spinlock_t lock;
  6640. + enum dect_cluster_modes mode;
  6641. + u32 state;
  6642. +
  6643. + /* identities */
  6644. + struct dect_idi idi;
  6645. + u16 fmid;
  6646. +
  6647. + /* system information */
  6648. + struct dect_si si;
  6649. + u32 blind_full_slots;
  6650. +
  6651. + /* PP state maintenance */
  6652. + u32 timer_sync_stamp;
  6653. + unsigned long a_rcv_stamp;
  6654. + unsigned long nt_rcv_stamp;
  6655. +
  6656. + /* Broadcast controllers and related data */
  6657. + struct dect_timer page_timer;
  6658. + struct sk_buff_head page_queue;
  6659. + struct sk_buff_head page_fast_queue;
  6660. +
  6661. + struct sk_buff *page_sdu;
  6662. + struct sk_buff_head page_tx_queue;
  6663. +
  6664. + struct list_head bcs;
  6665. + unsigned int si_idx;
  6666. + unsigned long bfs_xmit_stamp;
  6667. +
  6668. + struct dect_cbc cbc;
  6669. + struct list_head dbcs;
  6670. +
  6671. + u32 tbei_rover;
  6672. + struct list_head tbcs;
  6673. + unsigned int tbc_num_est;
  6674. + struct dect_channel_desc tbc_last_chd;
  6675. +
  6676. + struct list_head dmbs;
  6677. +
  6678. + /* channel lists */
  6679. + struct list_head chl_pending;
  6680. + struct list_head chanlists;
  6681. + struct dect_channel_list *chl_next;
  6682. + struct dect_channel_list *chl;
  6683. +
  6684. + /* raw transmission queue */
  6685. + struct sk_buff_head raw_tx_queue;
  6686. +
  6687. + struct dect_timer_base timer_base[DECT_TIMER_BASE_MAX + 1];
  6688. + struct dect_transceiver_group trg;
  6689. + u32 trg_blind_full_slots;
  6690. +};
  6691. +
  6692. +#define DECT_CELL_TIMER_RESYNC_TIMEOUT 8 /* T216: 8 multiframes */
  6693. +#define DECT_CELL_A_RCV_TIMEOUT (5 * HZ) /* T207: 5 seconds */
  6694. +#define DECT_CELL_NT_RCV_TIMEOUT (20 * HZ) /* T208: 20 seconds */
  6695. +
  6696. +#define dect_foreach_transmit_slot(slot, end, cell) \
  6697. + for ((slot) = dect_normal_transmit_base((cell)->mode), \
  6698. + (end) = (slot) + DECT_HALF_FRAME_SIZE; \
  6699. + (slot) < (end); (slot)++)
  6700. +
  6701. +#define dect_foreach_receive_slot(slot, end, cell) \
  6702. + for ((slot) = dect_normal_receive_base((cell)->mode), \
  6703. + (end) = (slot) + DECT_HALF_FRAME_SIZE; \
  6704. + (slot) < (end); (slot)++)
  6705. +
  6706. +extern struct dect_cell *dect_cell_get_by_index(u32 index);
  6707. +
  6708. +extern int dect_cell_attach_transceiver(struct dect_cell *cell,
  6709. + struct dect_transceiver *trx);
  6710. +extern void dect_cell_detach_transceiver(struct dect_cell *cell,
  6711. + struct dect_transceiver *trx);
  6712. +
  6713. +extern void dect_mac_rcv(struct dect_transceiver *trx,
  6714. + struct dect_transceiver_slot *ts,
  6715. + struct sk_buff *skb);
  6716. +extern void dect_mac_report_rssi(struct dect_transceiver *trx,
  6717. + struct dect_transceiver_slot *ts, u8 rssi);
  6718. +extern void dect_mac_rx_tick(struct dect_transceiver_group *grp, u8 slot);
  6719. +extern void dect_mac_tx_tick(struct dect_transceiver_group *grp, u8 slot);
  6720. +
  6721. +extern void dect_mac_irc_rcv(struct dect_transceiver *trx, struct sk_buff *skb);
  6722. +extern void dect_mac_irc_tick(struct dect_transceiver *trx);
  6723. +
  6724. +#endif /* _NET_DECT_MAC_CSF_H */
  6725. diff --git a/include/net/dect/transceiver.h b/include/net/dect/transceiver.h
  6726. new file mode 100644
  6727. index 0000000..2af1f86
  6728. --- /dev/null
  6729. +++ b/include/net/dect/transceiver.h
  6730. @@ -0,0 +1,711 @@
  6731. +/*
  6732. + * DECT Transceiver Layer
  6733. + *
  6734. + * Copyright (c) 2009 Patrick McHardy <[email protected]>
  6735. + */
  6736. +
  6737. +#ifndef _NET_DECT_TRANSCEIVER_H
  6738. +#define _NET_DECT_TRANSCEIVER_H
  6739. +
  6740. +#include <linux/interrupt.h>
  6741. +#include <linux/list.h>
  6742. +#include <linux/skbuff.h>
  6743. +#include <linux/dect.h>
  6744. +#include <linux/dect_netlink.h>
  6745. +
  6746. +#define DECT_RSSI_RANGE 255
  6747. +#define DECT_RSSI_DBM_LOW -93
  6748. +#define DECT_RSSI_DBM_RANGE 60
  6749. +
  6750. +static inline u8 dect_dbm_to_rssi_rel(s8 dbm)
  6751. +{
  6752. + return dbm * DECT_RSSI_RANGE / DECT_RSSI_DBM_RANGE;
  6753. +}
  6754. +
  6755. +static inline u8 dect_dbm_to_rssi(s8 dbm)
  6756. +{
  6757. + return dect_dbm_to_rssi_rel(dbm - DECT_RSSI_DBM_LOW);
  6758. +}
  6759. +
  6760. +#define DECT_RSSI_AVG_SCALE 3
  6761. +
  6762. +static inline u16 dect_average_rssi(u16 cur, u16 sample)
  6763. +{
  6764. + if (cur == 0)
  6765. + cur = sample << DECT_RSSI_AVG_SCALE;
  6766. + else {
  6767. + cur -= cur >> DECT_RSSI_AVG_SCALE;
  6768. + cur += sample;
  6769. + }
  6770. + return cur;
  6771. +}
  6772. +
  6773. +#define DECT_CARRIER_NUM 64
  6774. +
  6775. +static inline u8 dect_next_carrier(u64 rfcars, u8 carrier)
  6776. +{
  6777. + u64 tmp;
  6778. +
  6779. + if (WARN_ON(rfcars == 0))
  6780. + return 0;
  6781. + tmp = rfcars & ~((1ULL << (carrier + 1)) - 1);
  6782. + if (tmp == 0)
  6783. + tmp = rfcars;
  6784. + return ffs(tmp) - 1;
  6785. +}
  6786. +
  6787. +static inline u8 dect_prev_carrier(u64 rfcars, u8 carrier)
  6788. +{
  6789. + u64 tmp;
  6790. +
  6791. + if (WARN_ON(rfcars == 0))
  6792. + return 0;
  6793. + tmp = rfcars & ((1ULL << carrier) - 1);
  6794. + if (tmp == 0)
  6795. + tmp = rfcars;
  6796. + return fls(tmp) - 1;
  6797. +}
  6798. +
  6799. +static inline u8 dect_carrier_sub(u64 rfcars, u8 carrier, u8 n)
  6800. +{
  6801. + while (n != 0) {
  6802. + carrier = dect_prev_carrier(rfcars, carrier);
  6803. + n--;
  6804. + }
  6805. + return carrier;
  6806. +}
  6807. +
  6808. +static inline u8 dect_carrier_distance(u64 rfcars, u8 from, u8 to)
  6809. +{
  6810. + if (from >= to) {
  6811. + /* clear bits between to and from */
  6812. + rfcars &= ~(((1ULL << (from - to)) - 1) << to);
  6813. + } else {
  6814. + /* clear bits not between from and to */
  6815. + rfcars &= ((1ULL << (to - from)) - 1) << from;
  6816. + }
  6817. + return hweight64(rfcars);
  6818. +}
  6819. +
  6820. +#define DECT_PHASE_OFFSET_EWMA_LOG (DECT_PHASE_OFFSET_SCALE / 4)
  6821. +
  6822. +static inline s32 dect_average_phase_offset(s32 cur, s32 phaseoff)
  6823. +{
  6824. + cur -= cur / DECT_PHASE_OFFSET_EWMA_LOG;
  6825. + cur += phaseoff / DECT_PHASE_OFFSET_EWMA_LOG;
  6826. + return cur;
  6827. +}
  6828. +
  6829. +#define DECT_BAND_NUM 32
  6830. +#define DECT_DEFAULT_BAND 0
  6831. +
  6832. +#define DECT_FREQUENCY_F0 1897344 /* kHz */
  6833. +#define DECT_CARRIER_WIDTH 1728 /* kHz */
  6834. +
  6835. +/**
  6836. + * struct dect_band - DECT RF-band
  6837. + *
  6838. + * @band: RF-band number
  6839. + * @carriers: number of defined carriers
  6840. + * @frequency: frequency of each carrier in kHz
  6841. + */
  6842. +struct dect_band {
  6843. + u8 band;
  6844. + u8 carriers;
  6845. + u32 frequency[];
  6846. +};
  6847. +
  6848. +#define DECT_FRAME_SIZE 24
  6849. +#define DECT_HALF_FRAME_SIZE (DECT_FRAME_SIZE / 2)
  6850. +#define DECT_FRAMES_PER_SECOND 100
  6851. +
  6852. +#define DECT_SCAN_SLOT 0
  6853. +#define DECT_SLOT_MASK 0x00ffffff
  6854. +
  6855. +static inline u8 dect_next_slotnum(u8 slot)
  6856. +{
  6857. + if (++slot == DECT_FRAME_SIZE)
  6858. + slot = 0;
  6859. + return slot;
  6860. +}
  6861. +
  6862. +static inline u8 dect_prev_slotnum(u8 slot)
  6863. +{
  6864. + if (slot == 0)
  6865. + slot = DECT_FRAME_SIZE;
  6866. + return slot - 1;
  6867. +}
  6868. +
  6869. +static inline u8 dect_slot_add(u8 s1, u8 s2)
  6870. +{
  6871. + return (s1 + s2) % DECT_FRAME_SIZE;
  6872. +}
  6873. +
  6874. +static inline u8 dect_slot_sub(u8 s1, u8 s2)
  6875. +{
  6876. + return s1 >= s2 ? s1 - s2 : DECT_FRAME_SIZE + s1 - s2;
  6877. +}
  6878. +
  6879. +static inline u8 dect_slot_distance(u8 s1, u8 s2)
  6880. +{
  6881. + return s2 >= s1 ? s2 - s1 : DECT_FRAME_SIZE + s2 - s1;
  6882. +}
  6883. +
  6884. +#define dect_foreach_slot(slot) \
  6885. + for ((slot) = 0; (slot) < DECT_FRAME_SIZE; (slot)++)
  6886. +
  6887. +static inline u8 dect_normal_transmit_base(enum dect_cluster_modes mode)
  6888. +{
  6889. + return mode == DECT_MODE_FP ? 0 : DECT_HALF_FRAME_SIZE;
  6890. +}
  6891. +
  6892. +static inline u8 dect_normal_receive_base(enum dect_cluster_modes mode)
  6893. +{
  6894. + return mode == DECT_MODE_FP ? DECT_HALF_FRAME_SIZE : 0;
  6895. +}
  6896. +
  6897. +static inline u8 dect_normal_receive_end(enum dect_cluster_modes mode)
  6898. +{
  6899. + return mode == DECT_MODE_FP ? DECT_FRAME_SIZE - 1 :
  6900. + DECT_HALF_FRAME_SIZE - 1;
  6901. +}
  6902. +
  6903. +static inline u8 dect_tdd_slot(u8 slot)
  6904. +{
  6905. + return slot < DECT_HALF_FRAME_SIZE ? slot + DECT_HALF_FRAME_SIZE :
  6906. + slot - DECT_HALF_FRAME_SIZE;
  6907. +}
  6908. +
  6909. +enum dect_packet_sizes {
  6910. + DECT_P00_SIZE = 12,
  6911. + DECT_P08_SIZE = 23,
  6912. + DECT_P32_SIZE = 53,
  6913. + DECT_P640j_SIZE = 89,
  6914. + DECT_P672j_SIZE = 93,
  6915. + DECT_P80_SIZE = 113,
  6916. +};
  6917. +
  6918. +#define DECT_PREAMBLE_SIZE 4
  6919. +
  6920. +/**
  6921. + * enum dect_checksum - DECT hardware checksum results
  6922. + *
  6923. + * @DECT_CHECKSUM_A_CRC_OK: A-field R-CRC OK
  6924. + * @DECT_CHECKSUM_X_CRC_OK: Unprotected B-field X-CRC OK
  6925. + * @DECT_CHECKSUM_Z_CRC_OK: Z-field OK
  6926. + */
  6927. +enum dect_checksum {
  6928. + DECT_CHECKSUM_A_CRC_OK = 0x1,
  6929. + DECT_CHECKSUM_X_CRC_OK = 0x2,
  6930. + DECT_CHECKSUM_Z_CRC_OK = 0x4,
  6931. +};
  6932. +
  6933. +/**
  6934. + * enum dect_b_formats - DECT B-Field formats
  6935. + *
  6936. + * @DECT_B_NONE: No B-field
  6937. + * @DECT_B_UNPROTECTED: Unprotected B-field format
  6938. + * @DECT_B_PROTECTED: Protected B-field format
  6939. + *
  6940. + * The B-Field format can be used by a transceiver for offloading X-CRC
  6941. + * calculation.
  6942. + */
  6943. +enum dect_b_formats {
  6944. + DECT_B_NONE,
  6945. + DECT_B_UNPROTECTED,
  6946. + DECT_B_PROTECTED,
  6947. + __DECT_B_MAX
  6948. +};
  6949. +#define DECT_B_MAX (__DECT_B_MAX - 1)
  6950. +
  6951. +/**
  6952. + * struct dect_channel_desc - DECT physical channel description
  6953. + *
  6954. + * @pkt: Packet type in use
  6955. + * @b_fmt: B-Field format for checksum offloading
  6956. + * @slot: Slot number
  6957. + * @carrier: RF-carrier number
  6958. + */
  6959. +struct dect_channel_desc {
  6960. + enum dect_packet_types pkt:8;
  6961. + enum dect_b_formats b_fmt:8;
  6962. + u8 slot;
  6963. + u8 carrier;
  6964. +};
  6965. +
  6966. +enum dect_channel_priv_flags {
  6967. + DECT_SLOT_RAW_TX = 0x1,
  6968. +};
  6969. +
  6970. +/**
  6971. + * struct dect_transceiver_slot - Transceiver TDMA slot
  6972. + *
  6973. + * @flags: slot flags
  6974. + * @priv_flags: internally used flags
  6975. + * @state: current state
  6976. + * @desc: channel description
  6977. + * @bearer: associated bearer
  6978. + * @ck: cipher key
  6979. + * @phaseoff: measured phase offset
  6980. + * @rssi: averaged RSSI
  6981. + * @rx_bytes: RX byte count
  6982. + * @rx_packets: RX packet count
  6983. + * @rx_a_crc_errors: RX A-field CRC errors
  6984. + * @tx_bytes: TX byte count
  6985. + * @tx_packets: TX packet count
  6986. + */
  6987. +struct dect_transceiver_slot {
  6988. + u8 flags;
  6989. + u8 priv_flags;
  6990. + u8 blinded;
  6991. + enum dect_slot_states state:8;
  6992. + struct dect_channel_desc chd;
  6993. + struct dect_bearer *bearer;
  6994. + u64 ck;
  6995. +
  6996. + s32 phaseoff;
  6997. + u16 rssi;
  6998. + u32 rx_bytes;
  6999. + u32 rx_packets;
  7000. + u32 rx_a_crc_errors;
  7001. + u32 rx_x_crc_errors;
  7002. + u32 rx_z_crc_errors;
  7003. + u32 tx_bytes;
  7004. + u32 tx_packets;
  7005. +};
  7006. +
  7007. +/**
  7008. + * struct dect_transceiver_event - one atomic unit of work for the MAC layer
  7009. + *
  7010. + * @trx: transceiver
  7011. + * @busy: synchronizer
  7012. + * @list: transceiver group events list node
  7013. + * @rx_queue: received packets
  7014. + * @rssi: RSSI measurement in scanning slots
  7015. + * @rssi_mask: RSSI measurement positions
  7016. + * @slotpos: transceiver slot position in TDMA frame
  7017. + *
  7018. + * A transceiver operates asynchronously to the MAC layer, but the MAC layer's
  7019. + * timing needs to be strictly synchronized to the receiver.
  7020. + *
  7021. + * This structure contains the packets from multiple consequitive slots received
  7022. + * by the receiver in one unit (up to ops->eventrate frames). Slotpos specifies
  7023. + * the transceivers current position in the TDMA frame (== the minimum current
  7024. + * time) and is used for timing purposes and slot maintenance operations of the
  7025. + * upcoming slots. A transceiver uses a fixed amount of these structure and
  7026. + * synchronizes with BH processing through the busy marker. When BH processing
  7027. + * is too slow, frames are dropped.
  7028. + */
  7029. +struct dect_transceiver_event {
  7030. + struct dect_transceiver *trx;
  7031. + atomic_t busy;
  7032. + struct list_head list;
  7033. + struct sk_buff_head rx_queue;
  7034. + u8 rssi[DECT_HALF_FRAME_SIZE / 2];
  7035. + u8 rssi_mask;
  7036. + u8 slotpos;
  7037. +};
  7038. +
  7039. +/**
  7040. + * struct dect_skb_trx_cb - DECT Transceiver skb control block
  7041. + *
  7042. + * @trx: transceiver
  7043. + * @mfn: multiframe number
  7044. + * @frame: frame number
  7045. + * @slot: slot number
  7046. + * @lbn: logical bearer number
  7047. + * @csum: checksum results
  7048. + * @rssi: RSSI measurement
  7049. + */
  7050. +struct dect_skb_trx_cb {
  7051. + struct dect_transceiver *trx;
  7052. + u32 mfn;
  7053. + u8 frame;
  7054. + u8 slot;
  7055. + u8 lbn;
  7056. + u8 csum;
  7057. + u8 rssi;
  7058. +};
  7059. +
  7060. +static inline struct dect_skb_trx_cb *DECT_TRX_CB(const struct sk_buff *skb)
  7061. +{
  7062. + BUILD_BUG_ON(sizeof(struct dect_skb_trx_cb) > sizeof(skb->cb));
  7063. + return (struct dect_skb_trx_cb *)skb->cb;
  7064. +}
  7065. +
  7066. +/**
  7067. + * struct dect_transceiver_ops - DECT transceiver operations
  7068. + *
  7069. + * @disable: shut the transceiver down
  7070. + * @enable: bring the transceiver to operational state
  7071. + * @confirm: confirm a received signal in slave mode
  7072. + * @unlock: release a confirmed signal again
  7073. + * @lock: lock to a signal
  7074. + * @set_mode: set the mode (RX/TX/SCANNING) for a slot
  7075. + * @set_carrier: set the RF-carrier for a slot
  7076. + * @set_band: set the RF-band
  7077. + * @destructor: destructor
  7078. + * @name transceiver driver name
  7079. + * @features: transceiver features
  7080. + * @eventrate: rate at which slot events are generated, must be integral
  7081. + * divisor of the number of slots per TDMA half frame
  7082. + * @latency: latency in slots until updates for a slot take effect
  7083. + *
  7084. + * A transceiver provides frame reception and transmission, signal strength
  7085. + * measurement as well as a reference clock for the MAC layer. It can exist
  7086. + * in two basic states:
  7087. + *
  7088. + * - master: doesn't need initial synchronization to a radio signal
  7089. + * - slave: needs to synchronize timing with a signal
  7090. + *
  7091. + * Only the first transceiver of a FP is a master, PPs are always slaves to
  7092. + * a FPs timing. Secondary and further transceivers of a FP also start as
  7093. + * slaves until they have synchronized to one of the already running
  7094. + * transceivers.
  7095. + *
  7096. + * Locking to a new signal works in multiple phases:
  7097. + *
  7098. + * 1) The ->enable() callback is invoked. The driver is expected to initiate a
  7099. + * scan for a signal, during which it will pass on any received frame to the
  7100. + * transceiver layer. As no framing has been established, all packets should
  7101. + * indicate a slot number of zero.
  7102. + *
  7103. + * 2) While scanning for a signal, the ->set_carrier() callback may be invoked
  7104. + * with a slot number of zero. The driver is expected to adjust the carrier
  7105. + * on which it is scanning for a signal.
  7106. + *
  7107. + * 3) When the MAC layer determines interest in a received signal, the ->confirm()
  7108. + * callback is invoked. The driver is expected to continue to pass frames from
  7109. + * this signal to the MAC layer to establish framing.
  7110. + *
  7111. + * 3a) When the MAC layer is only collecting information for a scan, it may call
  7112. + * the ->unlock callback to release a previously confirmed signal.
  7113. + *
  7114. + * 4) Once the MAC layer has determined framing relative to the slot timing, the
  7115. + * ->lock() callback is invoked. At this point, only a single physical channel
  7116. + * is received. The driver should synchronize the hardware to the framing to
  7117. + * make it interrupt at the appropriate times.
  7118. + *
  7119. + */
  7120. +struct dect_transceiver;
  7121. +struct dect_transceiver_ops {
  7122. + void (*disable)(const struct dect_transceiver *trx);
  7123. + void (*enable)(const struct dect_transceiver *trx);
  7124. +
  7125. + void (*confirm)(const struct dect_transceiver *trx);
  7126. + void (*unlock)(const struct dect_transceiver *trx);
  7127. + void (*lock)(const struct dect_transceiver *trx, u8 slot);
  7128. +
  7129. + void (*set_mode)(const struct dect_transceiver *trx,
  7130. + const struct dect_channel_desc *chd,
  7131. + enum dect_slot_states mode);
  7132. + void (*set_carrier)(const struct dect_transceiver *trx,
  7133. + u8 slot, u8 carrier);
  7134. + void (*tx)(const struct dect_transceiver *trx,
  7135. + struct sk_buff *skb);
  7136. +
  7137. + u64 (*set_band)(const struct dect_transceiver *trx,
  7138. + const struct dect_band *band);
  7139. + void (*destructor)(struct dect_transceiver *trx);
  7140. + const char *name;
  7141. +
  7142. + u32 features;
  7143. + u8 eventrate;
  7144. + u8 latency;
  7145. +};
  7146. +
  7147. +/**
  7148. + * enum dect_transceiver_modes - Transceiver synchronization modes
  7149. + *
  7150. + * @DECT_TRANSCEIVER_MASTER: Transceiver determines reference time (FP)
  7151. + * @DECT_TRANSCEIVER_SLAVE: Transceiver is slave to foreign reference timing
  7152. + */
  7153. +enum dect_transceiver_modes {
  7154. + DECT_TRANSCEIVER_MASTER,
  7155. + DECT_TRANSCEIVER_SLAVE,
  7156. +};
  7157. +
  7158. +/**
  7159. + * enum dect_transceiver_states - transceiver synchronization states
  7160. + *
  7161. + * @DECT_TRANSCEIVER_STOPPED: transceiver is inactive
  7162. + * @DECT_TRANSCEIVER_UNLOCKED: transceiver is not synchronized to any RFP
  7163. + * @DECT_TRANSCEIVER_LOCK_PENDING: transceiver is receiving RFP transmissions,
  7164. + * but has not obtained frame synchonization
  7165. + * @DECT_TRANSCEIVER_LOCKED: the transceiver has achieved frame and
  7166. + * multiframe lock to an RFP
  7167. + *
  7168. + * These correspond to the ETS 300 175-3 Annex D PT MAC layer states, but are
  7169. + * per transceiver as we also need to synchronize secondary transceivers.
  7170. + */
  7171. +enum dect_transceiver_states {
  7172. + DECT_TRANSCEIVER_STOPPED,
  7173. + DECT_TRANSCEIVER_UNLOCKED,
  7174. + DECT_TRANSCEIVER_LOCK_PENDING,
  7175. + DECT_TRANSCEIVER_LOCKED,
  7176. +};
  7177. +
  7178. +/**
  7179. + * struct dect_transceiver_stats - transceiver statistics
  7180. + *
  7181. + * @event_busy: events lost due to MAC layer busy
  7182. + * @event_late: events lost due to transceiver late
  7183. + */
  7184. +struct dect_transceiver_stats {
  7185. + u32 event_busy;
  7186. + u32 event_late;
  7187. +};
  7188. +
  7189. +/**
  7190. + * struct dect_transceiver - DECT transceiver
  7191. + *
  7192. + * @list: transceiver list node
  7193. + * @ops: transceiver ops
  7194. + * @name: transceiver identity
  7195. + * @stats: transceiver statistics
  7196. + * @mode: synchronization mode
  7197. + * @state: synchronization state
  7198. + * @band: current RF-band
  7199. + * @carriers: bitmask of supported carriers in the current band
  7200. + * @slots: transceiver slot state
  7201. + * @index: cell transceiver index
  7202. + * @segno: transceiver receive sequence number
  7203. + * @cell: cell the transceiver is assigned to
  7204. + * @irc: idle receiver control
  7205. + * @event: dynamic amount of transceiver event structures
  7206. + *
  7207. + * Following the event structures is the private driver data.
  7208. + */
  7209. +struct dect_transceiver {
  7210. + struct list_head list;
  7211. + const struct dect_transceiver_ops *ops;
  7212. + char name[DECTNAMSIZ];
  7213. +
  7214. + struct dect_transceiver_stats stats;
  7215. + enum dect_transceiver_modes mode;
  7216. + enum dect_transceiver_states state;
  7217. +
  7218. + const struct dect_band *band;
  7219. + u64 carriers;
  7220. +
  7221. + struct dect_transceiver_slot slots[DECT_FRAME_SIZE];
  7222. + u32 blind_full_slots;
  7223. +
  7224. + u8 index;
  7225. + u32 seqno;
  7226. + struct dect_cell *cell;
  7227. + struct dect_irc *irc;
  7228. + struct dect_transceiver_event event[];
  7229. +};
  7230. +
  7231. +static inline void *dect_transceiver_priv(const struct dect_transceiver *trx)
  7232. +{
  7233. + return (void *)&trx->event[DECT_HALF_FRAME_SIZE / trx->ops->eventrate];
  7234. +}
  7235. +
  7236. +extern struct dect_transceiver *dect_transceiver_alloc(const struct dect_transceiver_ops *ops,
  7237. + unsigned int priv);
  7238. +extern void dect_transceiver_free(struct dect_transceiver *trx);
  7239. +extern int dect_register_transceiver(struct dect_transceiver *trx);
  7240. +extern void dect_unregister_transceiver(struct dect_transceiver *trx);
  7241. +
  7242. +extern void dect_transceiver_enable(struct dect_transceiver *trx);
  7243. +extern void dect_transceiver_disable(struct dect_transceiver *trx);
  7244. +
  7245. +extern void dect_transceiver_confirm(struct dect_transceiver *trx);
  7246. +extern void dect_transceiver_unlock(struct dect_transceiver *trx);
  7247. +extern void dect_transceiver_lock(struct dect_transceiver *trx, u8 slot);
  7248. +
  7249. +extern int dect_transceiver_set_band(struct dect_transceiver *trx, u8 bandnum);
  7250. +
  7251. +static inline void dect_set_channel_mode(struct dect_transceiver *trx,
  7252. + const struct dect_channel_desc *chd,
  7253. + enum dect_slot_states mode)
  7254. +{
  7255. + trx->ops->set_mode(trx, chd, mode);
  7256. + trx->slots[chd->slot].state = mode;
  7257. + trx->slots[chd->slot].chd.pkt = chd->pkt;
  7258. + trx->slots[chd->slot].chd.b_fmt = chd->b_fmt;
  7259. +}
  7260. +
  7261. +static inline void dect_set_carrier(struct dect_transceiver *trx,
  7262. + u8 slot, u8 carrier)
  7263. +{
  7264. + trx->slots[slot].chd.carrier = carrier;
  7265. + trx->slots[slot].rssi = 0;
  7266. + trx->slots[slot].phaseoff = 0;
  7267. + trx->ops->set_carrier(trx, slot, carrier);
  7268. +}
  7269. +
  7270. +static inline void dect_set_flags(struct dect_transceiver *trx, u8 slot, u32 flags)
  7271. +{
  7272. + trx->slots[slot].flags |= flags;
  7273. + trx->ops->set_mode(trx, &trx->slots[slot].chd, trx->slots[slot].state);
  7274. +}
  7275. +
  7276. +static inline void dect_clear_flags(struct dect_transceiver *trx, u8 slot, u32 flags)
  7277. +{
  7278. + trx->slots[slot].flags &= ~flags;
  7279. + trx->ops->set_mode(trx, &trx->slots[slot].chd, trx->slots[slot].state);
  7280. +}
  7281. +
  7282. +static inline void dect_enable_cipher(struct dect_transceiver *trx,
  7283. + const struct dect_channel_desc *chd,
  7284. + u64 ck)
  7285. +{
  7286. + trx->slots[chd->slot].ck = ck;
  7287. + dect_set_flags(trx, chd->slot, DECT_SLOT_CIPHER);
  7288. +}
  7289. +
  7290. +static inline void dect_disable_cipher(struct dect_transceiver *trx,
  7291. + const struct dect_channel_desc *chd)
  7292. +{
  7293. + dect_clear_flags(trx, chd->slot, DECT_SLOT_CIPHER);
  7294. + trx->slots[chd->slot].ck = 0;
  7295. +}
  7296. +
  7297. +static inline void dect_transceiver_tx(struct dect_transceiver *trx,
  7298. + struct sk_buff *skb)
  7299. +{
  7300. + u8 slot = DECT_TRX_CB(skb)->slot;
  7301. +
  7302. + trx->slots[slot].tx_bytes += skb->len;
  7303. + trx->slots[slot].tx_packets++;
  7304. + trx->ops->tx(trx, skb);
  7305. +}
  7306. +
  7307. +extern struct sk_buff *dect_transceiver_alloc_skb(struct dect_transceiver *trx, u8 slot);
  7308. +
  7309. +static inline struct dect_transceiver_event *
  7310. +dect_transceiver_event(struct dect_transceiver *trx, u8 n, u8 slotpos)
  7311. +{
  7312. + struct dect_transceiver_event *event;
  7313. +
  7314. + event = &trx->event[n];
  7315. + if (unlikely(!atomic_add_unless(&event->busy, 1, 1))) {
  7316. + trx->stats.event_busy++;
  7317. + return NULL;
  7318. + }
  7319. + event->slotpos = slotpos;
  7320. + return event;
  7321. +}
  7322. +
  7323. +static inline void dect_transceiver_record_rssi(struct dect_transceiver_event *event,
  7324. + u8 slot, u8 rssi)
  7325. +{
  7326. + u8 idx;
  7327. +
  7328. + idx = slot % event->trx->ops->eventrate;
  7329. + event->rssi[idx] = rssi;
  7330. + event->rssi_mask |= 1 << idx;
  7331. +}
  7332. +
  7333. +static inline void dect_release_transceiver_event(struct dect_transceiver_event *event)
  7334. +{
  7335. + event->rssi_mask = 0;
  7336. + smp_mb();
  7337. + atomic_dec(&event->busy);
  7338. +}
  7339. +
  7340. +enum dect_transceiver_events {
  7341. + DECT_TRANSCEIVER_REGISTER,
  7342. + DECT_TRANSCEIVER_UNREGISTER,
  7343. +};
  7344. +
  7345. +#define DECT_TRX_GROUP_MAX 16
  7346. +
  7347. +/**
  7348. + * struct dect_transceiver_group
  7349. + *
  7350. + * @trx: Transceiver array
  7351. + * @trxmask: Mask of present transceivers
  7352. + * @latency: Maximum latency of all transceivers
  7353. + * @features: Combined features of all transceivers
  7354. + * @blind_full_slots: combined blind full slots state of all transceivers
  7355. + * @tasklet: Event processing tasklet
  7356. + * @lock: Event list lock
  7357. + * @events: List of queued events
  7358. + * @seqno: Transceiver event loss detection
  7359. + * @slot_low: First unhandled slot
  7360. + * @slot_high: First slot after slot window
  7361. + * @slots: merged events for window slot_low - slot_high
  7362. + */
  7363. +struct dect_transceiver_group {
  7364. + struct dect_transceiver *trx[DECT_TRX_GROUP_MAX];
  7365. + u16 trxmask;
  7366. + u8 latency;
  7367. + u32 features;
  7368. + u32 blind_full_slots;
  7369. +
  7370. + struct tasklet_struct tasklet;
  7371. + spinlock_t lock;
  7372. + struct list_head events;
  7373. +
  7374. + u32 seqno;
  7375. + u8 slot_low;
  7376. + u8 slot_high;
  7377. + struct {
  7378. + struct sk_buff_head queue;
  7379. + u16 mask;
  7380. + u8 rssi[DECT_TRX_GROUP_MAX];
  7381. + } slots[DECT_HALF_FRAME_SIZE];
  7382. +};
  7383. +
  7384. +extern void dect_transceiver_group_init(struct dect_transceiver_group *trg);
  7385. +extern int dect_transceiver_group_add(struct dect_transceiver_group *trg,
  7386. + struct dect_transceiver *trx);
  7387. +extern void dect_transceiver_group_remove(struct dect_transceiver_group *trg,
  7388. + struct dect_transceiver *trx);
  7389. +
  7390. +extern bool dect_transceiver_channel_available(const struct dect_transceiver *trx,
  7391. + const struct dect_channel_desc *chd);
  7392. +extern bool dect_transceiver_reserve(struct dect_transceiver_group *trg,
  7393. + struct dect_transceiver *trx,
  7394. + const struct dect_channel_desc *chd);
  7395. +extern bool dect_transceiver_release(struct dect_transceiver_group *trg,
  7396. + struct dect_transceiver *trx,
  7397. + const struct dect_channel_desc *chd);
  7398. +
  7399. +extern void dect_transceiver_queue_event(struct dect_transceiver *trx,
  7400. + struct dect_transceiver_event *ev);
  7401. +
  7402. +#define dect_first_transceiver(trg) \
  7403. +({ \
  7404. + struct dect_transceiver_group *_trg = (void *)(trg); \
  7405. + u32 mask = _trg->trxmask; \
  7406. + mask ? (_trg)->trx[ffs(mask) - 1] : NULL; })
  7407. +
  7408. +#define dect_next_transceiver(trx, trg) \
  7409. +({ \
  7410. + struct dect_transceiver_group *_trg = (void *)(trg); \
  7411. + u32 mask = _trg->trxmask; \
  7412. + mask &= ~((1 << ((trx)->index + 1)) - 1); \
  7413. + mask ? (_trg)->trx[ffs(mask) - 1] : NULL; })
  7414. +
  7415. +#define dect_foreach_transceiver(trx, trg) \
  7416. + for ((trx) = dect_first_transceiver(trg); \
  7417. + (trx) != NULL; \
  7418. + (trx) = dect_next_transceiver(trx, trg))
  7419. +
  7420. +#define dect_last_transceiver(trg) \
  7421. +({ \
  7422. + struct dect_transceiver_group *_trg = (void *)(trg); \
  7423. + u32 mask = _trg->trxmask; \
  7424. + mask ? (_trg)->trx[fls(mask) - 1] : NULL; })
  7425. +
  7426. +#define dect_prev_transceiver(trx, trg) \
  7427. +({ \
  7428. + struct dect_transceiver_group *_trg = (void *)(trg); \
  7429. + u32 mask = _trg->trxmask; \
  7430. + mask &= (1 << (trx)->index) - 1; \
  7431. + mask ? (_trg)->trx[fls(mask) - 1] : NULL; })
  7432. +
  7433. +#define dect_foreach_transceiver_reverse(trx, trg) \
  7434. + for ((trx) = dect_last_transceiver(trg); \
  7435. + (trx) != NULL; \
  7436. + (trx) = dect_prev_transceiver(trx, trg))
  7437. +
  7438. +extern int dect_transceiver_module_init(void);
  7439. +extern void dect_transceiver_module_exit(void);
  7440. +
  7441. +#endif /* _NET_DECT_TRANSCEIVER_H */
  7442. diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild
  7443. index 855908e..517038d 100644
  7444. --- a/include/uapi/linux/Kbuild
  7445. +++ b/include/uapi/linux/Kbuild
  7446. @@ -100,6 +100,8 @@ header-y += cyclades.h
  7447. header-y += cycx_cfm.h
  7448. header-y += dcbnl.h
  7449. header-y += dccp.h
  7450. +header-y += dect.h
  7451. +header-y += dect_netlink.h
  7452. header-y += devlink.h
  7453. header-y += dlmconstants.h
  7454. header-y += dlm_device.h
  7455. diff --git a/include/uapi/linux/dect.h b/include/uapi/linux/dect.h
  7456. new file mode 100644
  7457. index 0000000..e458a9c
  7458. --- /dev/null
  7459. +++ b/include/uapi/linux/dect.h
  7460. @@ -0,0 +1,206 @@
  7461. +#ifndef _LINUX_DECT_H
  7462. +#define _LINUX_DECT_H
  7463. +
  7464. +#define DECTNAMSIZ 16
  7465. +
  7466. +#include <linux/types.h>
  7467. +#include <linux/socket.h>
  7468. +
  7469. +/* these have to be macros in order to be usable for module aliases */
  7470. +#define DECT_RAW 0 /* raw frames */
  7471. +#define DECT_B_SAP 1 /* DLC Broadcast Service */
  7472. +#define DECT_S_SAP 2 /* DLC Data Link Service */
  7473. +#define DECT_LU1_SAP 3 /* LU1 sockets */
  7474. +#define DECT_PROTO_NUM 4
  7475. +
  7476. +/**
  7477. + * struct sockaddr_dect
  7478. + *
  7479. + * @dect_family: address family (AF_DECT)
  7480. + * @dect_index: cluster index
  7481. + */
  7482. +struct sockaddr_dect {
  7483. + sa_family_t dect_family;
  7484. + int dect_index;
  7485. +};
  7486. +
  7487. +/* raw sockets */
  7488. +
  7489. +#define DECT_RAW_AUXDATA 0
  7490. +
  7491. +/**
  7492. + * struct dect_raw_auxdata - raw socket auxiliary frame data
  7493. + *
  7494. + * @mfn: multi-frame number
  7495. + * @frame: frame number
  7496. + * @slot: slot numer
  7497. + * @rssi: receive signal strength indicator
  7498. + */
  7499. +struct dect_raw_auxdata {
  7500. + __u32 mfn;
  7501. + __u8 frame;
  7502. + __u8 slot;
  7503. + __u8 rssi;
  7504. +};
  7505. +
  7506. +#define DECT_BSAP_AUXDATA 0
  7507. +
  7508. +/**
  7509. + * struct dect_bsap_auxdata
  7510. + *
  7511. + * @long_page: message contains a long page
  7512. + */
  7513. +struct dect_bsap_auxdata {
  7514. + __u8 long_page;
  7515. +};
  7516. +
  7517. +/**
  7518. + * enum dect_sapis - S SAP Identifier
  7519. + *
  7520. + * @DECT_SAPI_CO_SIGNALLING: connection oriented signalling
  7521. + * @DECT_SAPI_CL_SIGNALLING: connectionless signalling
  7522. + * @DECT_SAPI_ANY: wildcard
  7523. + */
  7524. +enum dect_sapis {
  7525. + DECT_SAPI_CO_SIGNALLING = 0,
  7526. + DECT_SAPI_CL_SIGNALLING = 3,
  7527. + DECT_SAPI_ANY = 7,
  7528. +};
  7529. +
  7530. +/**
  7531. + * enum dect_llns - Logical Link Numbers
  7532. + *
  7533. + * @DECT_LLN_CLASS_U: Class U operation
  7534. + * @DECT_LLN_CLASS_A: Class A operation
  7535. + * @DECT_LLN_ASSIGNABLE*: Assignable LLN (class B operation)
  7536. + * @DECT_LLN_UNASSIGNED: LLN unassigned (class B operation
  7537. + * @DECT_LLN_ANY: wildcard
  7538. + */
  7539. +enum dect_llns {
  7540. + DECT_LLN_CLASS_U = 0,
  7541. + DECT_LLN_CLASS_A = 1,
  7542. + DECT_LLN_ASSIGNABLE_MIN = 2,
  7543. + DECT_LLN_ASSIGNABLE_MAX = 6,
  7544. + DECT_LLN_UNASSIGNED = 7,
  7545. + DECT_LLN_ANY = 15,
  7546. +};
  7547. +
  7548. +/**
  7549. + * struct sockaddr_dect_ssap
  7550. + *
  7551. + * @dect_family: family (AF_DECT)
  7552. + * @dect_lln: logical link number
  7553. + * @dect_sapi: service access point identifier
  7554. + * @dect_class: class A/B
  7555. + * @dect_index: cluster index
  7556. + * @dect_ari: ARI
  7557. + * @dect_pmid: PMID
  7558. + * @dect_lcn: logical connection number
  7559. + */
  7560. +struct sockaddr_dect_ssap {
  7561. + sa_family_t dect_family;
  7562. + __u8 dect_lln:4,
  7563. + dect_sapi:3;
  7564. + __u8 dect_class;
  7565. + int dect_index;
  7566. + __u64 dect_ari:40,
  7567. + dect_pmid:20,
  7568. + dect_lcn:3;
  7569. +};
  7570. +
  7571. +/* S-SAP primitives */
  7572. +#define DECT_DL_ENC_KEY 1
  7573. +#define DECT_DL_ENCRYPT 2
  7574. +#define DECT_DL_MAC_CONN_PARAMS 3
  7575. +
  7576. +enum dect_cipher_states {
  7577. + DECT_CIPHER_DISABLED,
  7578. + DECT_CIPHER_ENABLED,
  7579. +};
  7580. +
  7581. +/**
  7582. + * enum dect_mac_connection_types - MAC Connection types
  7583. + *
  7584. + * @DECT_MAC_CONN_BASIC: Basic connection, always I_N_min_delay service
  7585. + * @DECT_MAC_CONN_ADVANCED: Advanced connection
  7586. + * @DECT_MAC_CONN_COMPLEMENT: Complementary connection
  7587. + */
  7588. +enum dect_mac_connection_types {
  7589. + DECT_MAC_CONN_BASIC,
  7590. + DECT_MAC_CONN_ADVANCED,
  7591. + DECT_MAC_CONN_COMPLEMENT,
  7592. +};
  7593. +
  7594. +enum dect_mac_service_types {
  7595. + DECT_SERVICE_IN_MIN_DELAY = 0x0,
  7596. + DECT_SERVICE_IPX_ENCODED_PROTECTED = 0x1,
  7597. + DECT_SERVICE_IN_NORMAL_DELAY = 0x2,
  7598. + DECT_SERVICE_UNKNOWN = 0x4,
  7599. + DECT_SERVICE_C_CHANNEL_ONLY = 0x5,
  7600. + DECT_SERVICE_IP_ERROR_DETECTION = 0x10,
  7601. + DECT_SERVICE_IPQ_ERROR_DETECTION = 0x14,
  7602. + /* Lifetime encoded in low three bits */
  7603. + DECT_SERVICE_IP_ERROR_CORRECTION = 0x18,
  7604. + DECT_SERVICE_IPQ_ERROR_CORRECTION = 0x38,
  7605. +};
  7606. +
  7607. +/**
  7608. + * enum dect_slot_types - DECT slot types
  7609. + *
  7610. + * @DECT_FULL_SLOT: Full-slot format (480 bits)
  7611. + * @DECT_HALF_SLOT: Half-slot format (240 bits)
  7612. + * @DECT_DOUBLE_SLOT: Double-slot format (960 bits)
  7613. + * @DECT_LONG_SLOT_j640: Long slot format j=640 (800 bits)
  7614. + * @DECT_LONG_SLOT_j672: Long slot format j=672 (832 bits)
  7615. + *
  7616. + * The numeric values must match the MAC-layer attributes-T coding.
  7617. + */
  7618. +enum dect_slot_types {
  7619. + DECT_FULL_SLOT = 0x0,
  7620. + DECT_HALF_SLOT = 0x1,
  7621. + DECT_DOUBLE_SLOT = 0x2,
  7622. + DECT_LONG_SLOT_640 = 0x3,
  7623. + DECT_LONG_SLOT_672 = 0x4,
  7624. +};
  7625. +
  7626. +struct dect_mac_conn_params {
  7627. + enum dect_mac_connection_types type;
  7628. + enum dect_mac_service_types service;
  7629. + enum dect_slot_types slot;
  7630. +};
  7631. +
  7632. +/**
  7633. + * struct dect_dl_encrypt - DL_ENCRYPT primitive arguments
  7634. + *
  7635. + * @status: desired/achieved encryption status
  7636. + */
  7637. +struct dect_dl_encrypt {
  7638. + enum dect_cipher_states status;
  7639. +};
  7640. +
  7641. +/**
  7642. + * struct sockaddr_dect_lu - DLC U-plane LUx service instance address
  7643. + *
  7644. + * @dect_family: address family (AF_DECT)
  7645. + * @dect_mci: MAC Connection Identifier
  7646. + */
  7647. +struct sockaddr_dect_lu {
  7648. + sa_family_t dect_family;
  7649. + int dect_index;
  7650. + __u64 dect_ari:40,
  7651. + dect_pmid:20,
  7652. + dect_lcn:3;
  7653. +};
  7654. +
  7655. +/* LU1 SAP */
  7656. +
  7657. +#define DECT_LU1_QUEUE_STATS 0
  7658. +
  7659. +struct dect_lu1_queue_stats {
  7660. + __u32 rx_bytes;
  7661. + __u32 rx_underflow;
  7662. + __u32 tx_bytes;
  7663. + __u32 tx_underflow;
  7664. +};
  7665. +
  7666. +#endif /* _LINUX_DECT_H */
  7667. diff --git a/include/uapi/linux/dect_netlink.h b/include/uapi/linux/dect_netlink.h
  7668. new file mode 100644
  7669. index 0000000..7c01aca
  7670. --- /dev/null
  7671. +++ b/include/uapi/linux/dect_netlink.h
  7672. @@ -0,0 +1,397 @@
  7673. +#ifndef _LINUX_DECT_NETLINK_H
  7674. +#define _LINUX_DECT_NETLINK_H
  7675. +
  7676. +struct dectmsg {
  7677. + int dm_index;
  7678. +};
  7679. +
  7680. +enum dect_nlgroups {
  7681. + DECTNLGRP_NONE,
  7682. + DECTNLGRP_TRANSCEIVER,
  7683. + DECTNLGRP_CELL,
  7684. + DECTNLGRP_CLUSTER,
  7685. + DECTNLGRP_LLME,
  7686. + __DECTNLGRP_MAX
  7687. +};
  7688. +#define DECTNLGRP_MAX (__DECTNLGRP_MAX - 1)
  7689. +
  7690. +enum dect_netlink_msg_types {
  7691. + DECT_MSG_BASE = 0x10,
  7692. + DECT_NEW_TRANSCEIVER,
  7693. + DECT_DEL_TRANSCEIVER,
  7694. + DECT_GET_TRANSCEIVER,
  7695. + DECT_NEW_CELL,
  7696. + DECT_DEL_CELL,
  7697. + DECT_GET_CELL,
  7698. + DECT_NEW_CLUSTER,
  7699. + DECT_DEL_CLUSTER,
  7700. + DECT_GET_CLUSTER,
  7701. + DECT_LLME_MSG,
  7702. + __DECT_MSG_MAX
  7703. +};
  7704. +#define DECT_MSG_MAX (__DECT_MSG_MAX - 1)
  7705. +
  7706. +#define DECT_NR_MSGTYPES (DECT_MSG_MAX + 1 - DECT_MSG_BASE)
  7707. +
  7708. +enum dect_list_attrs {
  7709. + DECTA_LIST_UNSPEC,
  7710. + DECTA_LIST_ELEM,
  7711. + __DECTA_LIST_MAX
  7712. +};
  7713. +#define DECTA_LIST_MAX (__DECTA_LIST_MAX - 1)
  7714. +
  7715. +enum dect_slot_states {
  7716. + DECT_SLOT_IDLE,
  7717. + DECT_SLOT_SCANNING,
  7718. + DECT_SLOT_RX,
  7719. + DECT_SLOT_TX,
  7720. +};
  7721. +
  7722. +enum dect_slot_flags {
  7723. + DECT_SLOT_SYNC = 0x1,
  7724. + DECT_SLOT_CIPHER = 0x2,
  7725. +};
  7726. +
  7727. +/**
  7728. + * enum dect_packet_types - DECT Physical Packet Types
  7729. + *
  7730. + * @DECT_PACKET_P00: short physical packet P00, 96 bits, A-field only
  7731. + * @DECT_PACKET_P08: low capacity physical packet P08j, 180 bits
  7732. + * @DECT_PACKET_P32: basic physical packet P32, 420 bits
  7733. + * @DECT_PACKET_P80: high capacity physical packet P80, 900 bits
  7734. + * @DECT_PACKET_P640j: variable capacity packet P640j, 712 bits
  7735. + * @DECT_PACKET_P672j: variable capacity packet P640j, 744 bits
  7736. + */
  7737. +enum dect_packet_types {
  7738. + DECT_PACKET_P00,
  7739. + DECT_PACKET_P08,
  7740. + DECT_PACKET_P32,
  7741. + DECT_PACKET_P80,
  7742. + DECT_PACKET_P640j,
  7743. + DECT_PACKET_P672j,
  7744. + __DECT_PACKET_MAX
  7745. +};
  7746. +#define DECT_PACKET_MAX (__DECT_PACKET_MAX - 1)
  7747. +
  7748. +#define DECT_PHASE_OFFSET_SCALE 1024
  7749. +
  7750. +enum dect_slot_attrs {
  7751. + DECTA_SLOT_UNSPEC,
  7752. + DECTA_SLOT_NUM,
  7753. + DECTA_SLOT_STATE,
  7754. + DECTA_SLOT_FLAGS,
  7755. + DECTA_SLOT_PACKET,
  7756. + DECTA_SLOT_CARRIER,
  7757. + DECTA_SLOT_FREQUENCY,
  7758. + DECTA_SLOT_PHASEOFF,
  7759. + DECTA_SLOT_RSSI,
  7760. + DECTA_SLOT_RX_PACKETS,
  7761. + DECTA_SLOT_RX_BYTES,
  7762. + DECTA_SLOT_RX_A_CRC_ERRORS,
  7763. + DECTA_SLOT_RX_X_CRC_ERRORS,
  7764. + DECTA_SLOT_RX_Z_CRC_ERRORS,
  7765. + DECTA_SLOT_TX_PACKETS,
  7766. + DECTA_SLOT_TX_BYTES,
  7767. + __DECTA_SLOT_MAX
  7768. +};
  7769. +#define DECTA_SLOT_MAX (__DECTA_SLOT_MAX - 1)
  7770. +
  7771. +enum dect_transceiver_stats_attrs {
  7772. + DECTA_TRANSCEIVER_STATS_UNSPEC,
  7773. + DECTA_TRANSCEIVER_STATS_EVENT_BUSY,
  7774. + DECTA_TRANSCEIVER_STATS_EVENT_LATE,
  7775. + __DECTA_TRANSCEIVER_STATS_MAX
  7776. +};
  7777. +#define DECTA_TRANSCEIVER_STATS_MAX (__DECTA_TRANSCEIVER_STATS_MAX - 1)
  7778. +
  7779. +/**
  7780. + * @DECT_TRANSCEIVER_SLOW_HOPPING: transceiver has slow hopping radio
  7781. + * @DECT_TRANSCEIVER_PACKET_P64: transceiver supports packet P640j
  7782. + */
  7783. +enum dect_transceiver_features {
  7784. + DECT_TRANSCEIVER_SLOW_HOPPING = 0x1,
  7785. + DECT_TRANSCEIVER_PACKET_P64 = 0x2,
  7786. +};
  7787. +
  7788. +enum dect_transceiver_attrs {
  7789. + DECTA_TRANSCEIVER_UNSPEC,
  7790. + DECTA_TRANSCEIVER_NAME,
  7791. + DECTA_TRANSCEIVER_TYPE,
  7792. + DECTA_TRANSCEIVER_FEATURES,
  7793. + DECTA_TRANSCEIVER_LINK,
  7794. + DECTA_TRANSCEIVER_STATS,
  7795. + DECTA_TRANSCEIVER_BAND,
  7796. + DECTA_TRANSCEIVER_SLOTS,
  7797. + __DECTA_TRANSCEIVER_MAX
  7798. +};
  7799. +#define DECTA_TRANSCEIVER_MAX (__DECTA_TRANSCEIVER_MAX - 1)
  7800. +
  7801. +enum dect_cell_flags {
  7802. + DECT_CELL_CCP = (1 << 0),
  7803. + DECT_CELL_SLAVE = (1 << 1),
  7804. + DECT_CELL_MONITOR = (1 << 2),
  7805. +};
  7806. +
  7807. +enum dect_cell_attrs {
  7808. + DECTA_CELL_UNSPEC,
  7809. + DECTA_CELL_NAME,
  7810. + DECTA_CELL_FLAGS,
  7811. + DECTA_CELL_TRANSCEIVERS,
  7812. + DECTA_CELL_CLUSTER,
  7813. + __DECTA_CELL_MAX
  7814. +};
  7815. +#define DECTA_CELL_MAX (__DECTA_CELL_MAX - 1)
  7816. +
  7817. +enum dect_mbc_state {
  7818. + DECT_MBC_NONE,
  7819. + DECT_MBC_INITIATED,
  7820. + DECT_MBC_ESTABLISHED,
  7821. + DECT_MBC_RELEASED,
  7822. +};
  7823. +
  7824. +enum dect_mbc_tb_attrs {
  7825. + DECTA_MBC_TB_UNSPEC,
  7826. + DECTA_MBC_TB_LBN,
  7827. + DECTA_MBC_TB_ECN,
  7828. + DECTA_MBC_TB_CELL,
  7829. + DECTA_MBC_TB_RX_SLOT,
  7830. + DECTA_MBC_TB_TX_SLOT,
  7831. + __DECTA_MBC_TB_MAX,
  7832. +};
  7833. +#define DECTA_MBC_TB_MAX (__DECTA_MBC_TB_MAX - 1)
  7834. +
  7835. +enum dect_mbc_stats_attrs {
  7836. + DECTA_MBC_STATS_UNSPEC,
  7837. + DECTA_MBC_STATS_CS_RX_BYTES,
  7838. + DECTA_MBC_STATS_CS_TX_BYTES,
  7839. + DECTA_MBC_STATS_I_RX_BYTES,
  7840. + DECTA_MBC_STATS_I_TX_BYTES,
  7841. + DECTA_MBC_STATS_HANDOVERS,
  7842. + __DECTA_MBC_STATS_MAX,
  7843. +};
  7844. +#define DECTA_MBC_STATS_MAX (__DECTA_MBC_STATS_MAX - 1)
  7845. +
  7846. +enum dect_mbc_attrs {
  7847. + DECTA_MBC_UNSPEC,
  7848. + DECTA_MBC_MCEI,
  7849. + DECTA_MBC_SERVICE,
  7850. + DECTA_MBC_STATE,
  7851. + DECTA_MBC_CIPHER_STATE,
  7852. + DECTA_MBC_STATS,
  7853. + DECTA_MBC_TBS,
  7854. + __DECTA_MBC_MAX,
  7855. +};
  7856. +#define DECTA_MBC_MAX (__DECTA_MBC_MAX - 1)
  7857. +
  7858. +enum dect_cluster_attrs {
  7859. + DECTA_CLUSTER_UNSPEC,
  7860. + DECTA_CLUSTER_NAME,
  7861. + DECTA_CLUSTER_MODE,
  7862. + DECTA_CLUSTER_PARI,
  7863. + DECTA_CLUSTER_CELLS,
  7864. + DECTA_CLUSTER_MBCS,
  7865. + __DECTA_CLUSTER_MAX
  7866. +};
  7867. +#define DECTA_CLUSTER_MAX (__DECTA_CLUSTER_MAX - 1)
  7868. +
  7869. +enum dect_cluster_modes {
  7870. + DECT_MODE_FP,
  7871. + DECT_MODE_PP,
  7872. +};
  7873. +
  7874. +/**
  7875. + * DECT ARI classes
  7876. + *
  7877. + * @DECT_ARC_A: Residential and private (PBX) single- and small multiple cell systems
  7878. + * @DECT_ARC_B: Private (PABXs) multiple cell
  7879. + * @DECT_ARC_C: Public single and multiple cell systems
  7880. + * @DECT_ARC_D: Public DECT access to a GSM network
  7881. + * @DECT_ARC_E: PP to PP direct communication (private)
  7882. + */
  7883. +enum dect_ari_classes {
  7884. + DECT_ARC_A,
  7885. + DECT_ARC_B,
  7886. + DECT_ARC_C,
  7887. + DECT_ARC_D,
  7888. + DECT_ARC_E,
  7889. +};
  7890. +
  7891. +enum dect_ari_attrs {
  7892. + DECTA_ARI_UNSPEC,
  7893. + DECTA_ARI_CLASS,
  7894. + DECTA_ARI_FPN,
  7895. + DECTA_ARI_FPS,
  7896. + DECTA_ARI_EMC,
  7897. + DECTA_ARI_EIC,
  7898. + DECTA_ARI_POC,
  7899. + DECTA_ARI_GOP,
  7900. + DECTA_ARI_FIL,
  7901. + __DECTA_ARI_MAX
  7902. +};
  7903. +#define DECTA_ARI_MAX (__DECTA_ARI_MAX - 1)
  7904. +
  7905. +enum decta_sari_attrs {
  7906. + DECTA_SARI_UNSPEC,
  7907. + DECTA_SARI_ARI,
  7908. + DECTA_SARI_BLACK,
  7909. + DECTA_SARI_TARI,
  7910. + __DECTA_SARI_MAX
  7911. +};
  7912. +#define DECTA_SARI_MAX (__DECTA_SARI_MAX - 1)
  7913. +
  7914. +enum dect_fixed_part_capabilities {
  7915. + DECT_FPC_EXTENDED_FP_INFO = 0x80000,
  7916. + DECT_FPC_DOUBLE_DUPLEX_BEARER_CONNECTION= 0x40000,
  7917. + DECT_FPC_RESERVED = 0x20000,
  7918. + DECT_FPC_DOUBLE_SLOT = 0x10000,
  7919. + DECT_FPC_HALF_SLOT = 0x08000,
  7920. + DECT_FPC_FULL_SLOT = 0x04000,
  7921. + DECT_FPC_FREQ_CONTROL = 0x02000,
  7922. + DECT_FPC_PAGE_REPETITION = 0x01000,
  7923. + DECT_FPC_CO_SETUP_ON_DUMMY = 0x00800,
  7924. + DECT_FPC_CL_UPLINK = 0x00400,
  7925. + DECT_FPC_CL_DOWNLINK = 0x00200,
  7926. + DECT_FPC_BASIC_A_FIELD_SETUP = 0x00100,
  7927. + DECT_FPC_ADV_A_FIELD_SETUP = 0x00080,
  7928. + DECT_FPC_B_FIELD_SETUP = 0x00040,
  7929. + DECT_FPC_CF_MESSAGES = 0x00020,
  7930. + DECT_FPC_IN_MIN_DELAY = 0x00010,
  7931. + DECT_FPC_IN_NORM_DELAY = 0x00008,
  7932. + DECT_FPC_IP_ERROR_DETECTION = 0x00004,
  7933. + DECT_FPC_IP_ERROR_CORRECTION = 0x00002,
  7934. + DECT_FPC_MULTIBEARER_CONNECTIONS = 0x00001,
  7935. +};
  7936. +
  7937. +enum dect_higher_layer_capabilities {
  7938. + DECT_HLC_ADPCM_G721_VOICE = 0x8000,
  7939. + DECT_HLC_GAP_PAP_BASIC_SPEECH = 0x4000,
  7940. + DECT_HLC_NON_VOICE_CIRCUIT_SWITCHED = 0x2000,
  7941. + DECT_HLC_NON_VOICE_PACKET_SWITCHED = 0x1000,
  7942. + DECT_HLC_STANDARD_AUTHENTICATION = 0x0800,
  7943. + DECT_HLC_STANDARD_CIPHERING = 0x0400,
  7944. + DECT_HLC_LOCATION_REGISTRATION = 0x0200,
  7945. + DECT_HLC_SIM_SERVICES = 0x0100,
  7946. + DECT_HLC_NON_STATIC_FIXED_PART = 0x0080,
  7947. + DECT_HLC_CISS_SERVICE = 0x0040,
  7948. + DECT_HLC_CLMS_SERVICE = 0x0020,
  7949. + DECT_HLC_COMS_SERVICE = 0x0010,
  7950. + DECT_HLC_ACCESS_RIGHTS_REQUESTS = 0x0008,
  7951. + DECT_HLC_EXTERNAL_HANDOVER = 0x0004,
  7952. + DECT_HLC_CONNECTION_HANDOVER = 0x0002,
  7953. + DECT_HLC_RESERVED = 0x0001,
  7954. +};
  7955. +
  7956. +enum dect_extended_fixed_part_capabilities {
  7957. + DECT_EFPC_WRS_MASK = 0x1f80,
  7958. + DECT_EFPC_WRS_CRFP_HOPS_MASK = 0x1800,
  7959. + DECT_EFPC_WRS_CRFP_HOPS_1 = 0x0000,
  7960. + DECT_EFPC_WRS_CRFP_HOPS_2 = 0x0800,
  7961. + DECT_EFPC_WRS_CRFP_HOPS_3 = 0x1000,
  7962. + DECT_EFPC_WRS_CRFP_HOPS_NONE = 0x1800,
  7963. + DECT_EFPC_WRS_CRFP_ENCRYPTION = 0x0400,
  7964. + DECT_EFPC_WRS_REP_HOPS_MASK = 0x0300,
  7965. + DECT_EFPC_WRS_REP_HOPS_NONE = 0x0000,
  7966. + DECT_EFPC_WRS_REP_HOPS_1 = 0x0100,
  7967. + DECT_EFPC_WRS_REP_HOPS_2 = 0x0200,
  7968. + DECT_EFPC_WRS_REP_HOPS_3 = 0x0300,
  7969. + DECT_EFPC_WRS_REP_INTERLACING = 0x0080,
  7970. + DECT_EFPC_SYNC_MASK = 0x0060,
  7971. + DECT_EFPC_SYNC_PROLONGED_PREAMBLE = 0x0020,
  7972. + DECT_EFPC_SYNC_RESERVED1 = 0x0010,
  7973. + DECT_EFPC_MAC_SUSPEND_RESUME = 0x0008,
  7974. + DECT_EFPC_MAC_IP_Q_SERVICE = 0x0004,
  7975. + DECT_EFPC_EXTENDED_FP_INFO2 = 0x0002,
  7976. + DECT_EFPC_RESERVED2 = 0x0001,
  7977. +};
  7978. +
  7979. +enum dect_extended_higher_layer_capabilities {
  7980. + DECT_EHLC_ISDN_DATA_SERVICE = 0x000001,
  7981. + DECT_EHLC_DPRS_FREL = 0x000002,
  7982. + DECT_EHLC_DPRS_STREAM = 0x000004,
  7983. + DECT_EHLC_DATA_SERVICE_PROFILE_D = 0x000008,
  7984. + DECT_EHLC_LRMS = 0x000010,
  7985. + DECT_EHLC_ASYMETRIC_BEARERS = 0x000040,
  7986. + DECT_EHLC_EMERGENCY_CALLS = 0x000080,
  7987. + DECT_EHLC_TPUI_LOCATION_REGISTRATION = 0x000100,
  7988. + DECT_EHLC_GPS_SYNCHRONIZED = 0x000200,
  7989. + DECT_EHLC_ISDN_INTERMEDIATE_SYSTEM = 0x000400,
  7990. + DECT_EHLC_RAP_PART_1_PROFILE = 0x000800,
  7991. + DECT_EHLC_V_24 = 0x004000,
  7992. + DECT_EHLC_PPP = 0x008000,
  7993. + DECT_EHLC_IP = 0x010000,
  7994. + DECT_EHLC_TOKEN_RING = 0x020000,
  7995. + DECT_EHLC_ETHERNET = 0x040000,
  7996. + DECT_EHLC_IP_ROAMING = 0x080000,
  7997. + DECT_EHLC_GENERIC_MEDIA_ENCAPSULATION = 0x100000,
  7998. + DECT_EHLC_BASIC_ODAP = 0x200000,
  7999. + DECT_EHLC_F_MMS_INTERWORKING_PROFILE = 0x400000,
  8000. +};
  8001. +
  8002. +enum dect_extended_fixed_part_capabilities2 {
  8003. + DECT_EFPC2_LONG_SLOT_J640 = 0x800,
  8004. + DECT_EFPC2_LONG_SLOT_J672 = 0x400,
  8005. + DECT_EFPC2_IP_F = 0x200,
  8006. + DECT_EFPC2_SI_PF = 0x100,
  8007. + DECT_EFPC2_GF = 0x080,
  8008. + DECT_EFPC2_NO_EMISSION_CARRIER = 0x001,
  8009. +};
  8010. +
  8011. +enum dect_extended_higher_layer_capabilities2 {
  8012. + DECT_EHLC2_NG_DECT_PERMANENT_CLIR = 0x000100,
  8013. + DECT_EHLC2_NG_DECT_MULTIPLE_CALLS = 0x000200,
  8014. + DECT_EHLC2_NG_DECT_MULTIPLE_LINES = 0x000400,
  8015. + DECT_EHLC2_EASY_PAIRING = 0x000800,
  8016. + DECT_EHLC2_LIST_ACCESS_FEATURES = 0x001000,
  8017. + DECT_EHLC2_NO_EMISSION_MODE = 0x002000,
  8018. + DECT_EHLC2_NG_DECT_CALL_DEFLECTION = 0x004000,
  8019. + DECT_EHLC2_NG_DECT_INTRUSION_CALL = 0x008000,
  8020. + DECT_EHLC2_NG_DECT_CONFERENCE_CALL = 0x010000,
  8021. + DECT_EHLC2_NG_DECT_PARALLEL_CALLS = 0x020000,
  8022. + DECT_EHLC2_NG_DECT_CALL_TRANSFER = 0x040000,
  8023. + DECT_EHLC2_NG_DECT_EXTENDED_WIDEBAND = 0x080000,
  8024. + DECT_EHLC2_PACKET_DATA_CATEGORY_MASK = 0x700000,
  8025. + DECT_EHLC2_NG_DECT_WIDEBAND = 0x800000,
  8026. +};
  8027. +
  8028. +enum dect_mac_info_attrs {
  8029. + DECTA_MAC_INFO_UNSPEC,
  8030. + DECTA_MAC_INFO_PARI,
  8031. + DECTA_MAC_INFO_RPN,
  8032. + DECTA_MAC_INFO_RSSI,
  8033. + DECTA_MAC_INFO_SARI_LIST,
  8034. + DECTA_MAC_INFO_FPC,
  8035. + DECTA_MAC_INFO_HLC,
  8036. + DECTA_MAC_INFO_EFPC,
  8037. + DECTA_MAC_INFO_EHLC,
  8038. + DECTA_MAC_INFO_EFPC2,
  8039. + DECTA_MAC_INFO_EHLC2,
  8040. + DECTA_MAC_INFO_MFN,
  8041. + __DECTA_MAC_INFO_MAX
  8042. +};
  8043. +#define DECTA_MAC_INFO_MAX (__DECTA_MAC_INFO_MAX - 1)
  8044. +
  8045. +enum dect_llme_ops {
  8046. + DECT_LLME_REQUEST,
  8047. + DECT_LLME_INDICATE,
  8048. + DECT_LLME_RESPONSE,
  8049. + DECT_LLME_CONFIRM,
  8050. +};
  8051. +
  8052. +enum dect_llme_msg_types {
  8053. + DECT_LLME_SCAN,
  8054. + DECT_LLME_MAC_INFO,
  8055. + DECT_LLME_MAC_RFP_PRELOAD,
  8056. + __DECT_LLME_MAX
  8057. +};
  8058. +#define DECT_LLME_MAX (__DECT_LLME_MAX - 1)
  8059. +
  8060. +enum dect_llme_msg_attrs {
  8061. + DECTA_LLME_UNSPEC,
  8062. + DECTA_LLME_OP,
  8063. + DECTA_LLME_TYPE,
  8064. + DECTA_LLME_DATA,
  8065. + __DECTA_LLME_MAX
  8066. +};
  8067. +#define DECTA_LLME_MAX (__DECTA_LLME_MAX - 1)
  8068. +
  8069. +#endif /* _LINUX_DECT_NETLINK_H */
  8070. diff --git a/include/uapi/linux/netlink.h b/include/uapi/linux/netlink.h
  8071. index 0dba4e4..fc9183e 100644
  8072. --- a/include/uapi/linux/netlink.h
  8073. +++ b/include/uapi/linux/netlink.h
  8074. @@ -27,6 +27,7 @@
  8075. #define NETLINK_ECRYPTFS 19
  8076. #define NETLINK_RDMA 20
  8077. #define NETLINK_CRYPTO 21 /* Crypto layer */
  8078. +#define NETLINK_DECT 22 /* DECT */
  8079. #define NETLINK_INET_DIAG NETLINK_SOCK_DIAG
  8080. diff --git a/net/Kconfig b/net/Kconfig
  8081. index 7b6cd34..7aee66b 100644
  8082. --- a/net/Kconfig
  8083. +++ b/net/Kconfig
  8084. @@ -367,6 +367,7 @@ source "net/ax25/Kconfig"
  8085. source "net/can/Kconfig"
  8086. source "net/irda/Kconfig"
  8087. source "net/bluetooth/Kconfig"
  8088. +source "net/dect/Kconfig"
  8089. source "net/rxrpc/Kconfig"
  8090. source "net/kcm/Kconfig"
  8091. source "net/strparser/Kconfig"
  8092. diff --git a/net/Makefile b/net/Makefile
  8093. index 4cafaa2..986de8b 100644
  8094. --- a/net/Makefile
  8095. +++ b/net/Makefile
  8096. @@ -32,6 +32,7 @@ obj-$(CONFIG_AX25) += ax25/
  8097. obj-$(CONFIG_CAN) += can/
  8098. obj-$(CONFIG_IRDA) += irda/
  8099. obj-$(CONFIG_BT) += bluetooth/
  8100. +obj-$(CONFIG_DECT) += dect/
  8101. obj-$(CONFIG_SUNRPC) += sunrpc/
  8102. obj-$(CONFIG_AF_RXRPC) += rxrpc/
  8103. obj-$(CONFIG_AF_KCM) += kcm/
  8104. diff --git a/net/core/sock.c b/net/core/sock.c
  8105. index 5e3ca41..f984e6c 100644
  8106. --- a/net/core/sock.c
  8107. +++ b/net/core/sock.c
  8108. @@ -222,7 +222,7 @@ static const char *const af_family_key_strings[AF_MAX+1] = {
  8109. "sk_lock-AF_RXRPC" , "sk_lock-AF_ISDN" , "sk_lock-AF_PHONET" ,
  8110. "sk_lock-AF_IEEE802154", "sk_lock-AF_CAIF" , "sk_lock-AF_ALG" ,
  8111. "sk_lock-AF_NFC" , "sk_lock-AF_VSOCK" , "sk_lock-AF_KCM" ,
  8112. - "sk_lock-AF_MAX"
  8113. + "sk_lock-AF_DECT" , "sk_lock-AF_MAX"
  8114. };
  8115. static const char *const af_family_slock_key_strings[AF_MAX+1] = {
  8116. "slock-AF_UNSPEC", "slock-AF_UNIX" , "slock-AF_INET" ,
  8117. @@ -239,7 +239,7 @@ static const char *const af_family_slock_key_strings[AF_MAX+1] = {
  8118. "slock-AF_RXRPC" , "slock-AF_ISDN" , "slock-AF_PHONET" ,
  8119. "slock-AF_IEEE802154", "slock-AF_CAIF" , "slock-AF_ALG" ,
  8120. "slock-AF_NFC" , "slock-AF_VSOCK" ,"slock-AF_KCM" ,
  8121. - "slock-AF_MAX"
  8122. + "slock-AF_DECT" , "slock-AF_MAX"
  8123. };
  8124. static const char *const af_family_clock_key_strings[AF_MAX+1] = {
  8125. "clock-AF_UNSPEC", "clock-AF_UNIX" , "clock-AF_INET" ,
  8126. @@ -256,7 +256,7 @@ static const char *const af_family_clock_key_strings[AF_MAX+1] = {
  8127. "clock-AF_RXRPC" , "clock-AF_ISDN" , "clock-AF_PHONET" ,
  8128. "clock-AF_IEEE802154", "clock-AF_CAIF" , "clock-AF_ALG" ,
  8129. "clock-AF_NFC" , "clock-AF_VSOCK" , "clock-AF_KCM" ,
  8130. - "clock-AF_MAX"
  8131. + "clock-AF_DECT" , "clock-AF_MAX"
  8132. };
  8133. /*
  8134. diff --git a/net/core/sock.c.rej b/net/core/sock.c.rej
  8135. new file mode 100644
  8136. index 0000000..1a51eb7
  8137. --- /dev/null
  8138. +++ b/net/core/sock.c.rej
  8139. @@ -0,0 +1,32 @@
  8140. +--- net/core/sock.c
  8141. ++++ net/core/sock.c
  8142. +@@ -221,7 +221,8 @@ static const char *const af_family_key_strings[AF_MAX+1] = {
  8143. + "sk_lock-AF_TIPC" , "sk_lock-AF_BLUETOOTH", "sk_lock-IUCV" ,
  8144. + "sk_lock-AF_RXRPC" , "sk_lock-AF_ISDN" , "sk_lock-AF_PHONET" ,
  8145. + "sk_lock-AF_IEEE802154", "sk_lock-AF_CAIF" , "sk_lock-AF_ALG" ,
  8146. +- "sk_lock-AF_NFC" , "sk_lock-AF_VSOCK" , "sk_lock-AF_MAX"
  8147. ++ "sk_lock-AF_NFC" , "sk_lock-AF_VSOCK" , "sk_lock-AF_DECT" ,
  8148. ++ "sk_lock-AF_MAX"
  8149. + };
  8150. + static const char *const af_family_slock_key_strings[AF_MAX+1] = {
  8151. + "slock-AF_UNSPEC", "slock-AF_UNIX" , "slock-AF_INET" ,
  8152. +@@ -237,7 +238,8 @@ static const char *const af_family_slock_key_strings[AF_MAX+1] = {
  8153. + "slock-AF_TIPC" , "slock-AF_BLUETOOTH", "slock-AF_IUCV" ,
  8154. + "slock-AF_RXRPC" , "slock-AF_ISDN" , "slock-AF_PHONET" ,
  8155. + "slock-AF_IEEE802154", "slock-AF_CAIF" , "slock-AF_ALG" ,
  8156. +- "slock-AF_NFC" , "slock-AF_VSOCK" ,"slock-AF_MAX"
  8157. ++ "slock-AF_NFC" , "slock-AF_VSOCK" , "slock-AF_DECT" ,
  8158. ++ "slock-AF_MAX"
  8159. + };
  8160. + static const char *const af_family_clock_key_strings[AF_MAX+1] = {
  8161. + "clock-AF_UNSPEC", "clock-AF_UNIX" , "clock-AF_INET" ,
  8162. +@@ -253,7 +255,8 @@ static const char *const af_family_clock_key_strings[AF_MAX+1] = {
  8163. + "clock-AF_TIPC" , "clock-AF_BLUETOOTH", "clock-AF_IUCV" ,
  8164. + "clock-AF_RXRPC" , "clock-AF_ISDN" , "clock-AF_PHONET" ,
  8165. + "clock-AF_IEEE802154", "clock-AF_CAIF" , "clock-AF_ALG" ,
  8166. +- "clock-AF_NFC" , "clock-AF_VSOCK" , "clock-AF_MAX"
  8167. ++ "clock-AF_NFC" , "clock-AF_VSOCK" , "clock-AF_DECT" ,
  8168. ++ "clock-AF_MAX"
  8169. + };
  8170. +
  8171. + /*
  8172. diff --git a/net/dect/Kconfig b/net/dect/Kconfig
  8173. new file mode 100644
  8174. index 0000000..873500d
  8175. --- /dev/null
  8176. +++ b/net/dect/Kconfig
  8177. @@ -0,0 +1,66 @@
  8178. +menuconfig DECT
  8179. + tristate "DECT protocol support"
  8180. + help
  8181. + This option enables support for the DECT protocol.
  8182. +
  8183. + If unsure, say N.
  8184. +
  8185. +if DECT
  8186. +
  8187. +config DECT_DEBUG
  8188. + bool "DECT debugging"
  8189. + help
  8190. + This option enables support for debugging in the DECT modules.
  8191. +
  8192. + If unsure, say N.
  8193. +
  8194. +config DECT_CSF
  8195. + tristate "DECT Cell Site Functions (CSF) support"
  8196. + help
  8197. + This option enables support for DECT Cell Site Functions. A DECT
  8198. + cell is a radio endpoint containing one or more transceivers.
  8199. +
  8200. + If unsure, say N.
  8201. +
  8202. +config DECT_RAW
  8203. + tristate "DECT raw sockets"
  8204. + depends on DECT_CSF
  8205. + help
  8206. + This option enables support for PF_DECT raw sockets. DECT raw
  8207. + sockets are used to receive raw frames from DECT devices.
  8208. +
  8209. + If unsure, say N.
  8210. +
  8211. +config DECT_CCF
  8212. + tristate "DECT Cluster Control Functions (CCF) support"
  8213. + help
  8214. + This option enables support for the DECT Cluster Control Functions.
  8215. +
  8216. + A DECT cluster is a Portable radio Termination (PT), containing a
  8217. + single cell, or a Fixed radio Termination (FT), containing up to
  8218. + 8 cells.
  8219. +
  8220. + If unsure, say N.
  8221. +
  8222. +config DECT_LU1_SAP
  8223. + tristate "DECT DLC LU1 SAP sockets"
  8224. + select DECT_CCF
  8225. + help
  8226. + This option enables support for PF_DECT DLC LU1 SAP sockets. DECT
  8227. + DLC LU1 SAP sockets are used for the TRUP (TRansparent UnProtected)
  8228. + service, most commonly used for audio.
  8229. +
  8230. + If unsure, say N.
  8231. +
  8232. +config DECT_CCP
  8233. + bool "DECT Cell Control Protocol support"
  8234. + depends on DECT_CSF || DECT_CCF
  8235. + select TIPC
  8236. + help
  8237. + This option enables support for the DECT Cell Control Protocol.
  8238. + This can be used to remotely control one or multiple DECT cells
  8239. + by the DECT cluster control functions.
  8240. +
  8241. + If unsure, say N.
  8242. +
  8243. +endif
  8244. diff --git a/net/dect/Makefile b/net/dect/Makefile
  8245. new file mode 100644
  8246. index 0000000..7d7bb14
  8247. --- /dev/null
  8248. +++ b/net/dect/Makefile
  8249. @@ -0,0 +1,17 @@
  8250. +dect-y += core.o identities.o dect_netlink.o af_dect.o
  8251. +
  8252. +dect_csf-y += mac_csf.o transceiver.o
  8253. +
  8254. +dect_ccf-y += mac_ccf.o dsc.o
  8255. +dect_ccf-y += dlc.o
  8256. +dect_ccf-y += dlc_cplane.o dlc_b_sap.o dlc_s_sap.o
  8257. +dect_ccf-y += dlc_uplane.o
  8258. +dect_ccf-$(CONFIG_DECT_CCP) += ccp.o
  8259. +
  8260. +dect_raw-y += raw.o
  8261. +
  8262. +obj-$(CONFIG_DECT) += dect.o
  8263. +obj-$(CONFIG_DECT_CSF) += dect_csf.o
  8264. +obj-$(CONFIG_DECT_RAW) += dect_raw.o
  8265. +obj-$(CONFIG_DECT_CCF) += dect_ccf.o
  8266. +obj-$(CONFIG_DECT_LU1_SAP) += dlc_lu1_sap.o
  8267. diff --git a/net/dect/af_dect.c b/net/dect/af_dect.c
  8268. new file mode 100644
  8269. index 0000000..a6dd709
  8270. --- /dev/null
  8271. +++ b/net/dect/af_dect.c
  8272. @@ -0,0 +1,456 @@
  8273. +/*
  8274. + * DECT sockets
  8275. + *
  8276. + * Copyright (c) 2009 Patrick McHardy <[email protected]>
  8277. + *
  8278. + * This program is free software; you can redistribute it and/or modify
  8279. + * it under the terms of the GNU General Public License version 2 as
  8280. + * published by the Free Software Foundation.
  8281. + */
  8282. +
  8283. +#include <linux/kernel.h>
  8284. +#include <linux/module.h>
  8285. +#include <linux/init.h>
  8286. +#include <linux/spinlock.h>
  8287. +#include <linux/socket.h>
  8288. +#include <linux/net.h>
  8289. +#include <linux/poll.h>
  8290. +#include <linux/dect.h>
  8291. +#include <net/sock.h>
  8292. +#include <net/dect/dect.h>
  8293. +
  8294. +static struct dect_proto *dect_protos[DECT_PROTO_NUM];
  8295. +static DEFINE_SPINLOCK(dect_proto_lock);
  8296. +
  8297. +void (*dect_raw_rcv_hook)(struct sk_buff *skb);
  8298. +EXPORT_SYMBOL_GPL(dect_raw_rcv_hook);
  8299. +
  8300. +int dect_proto_register(struct dect_proto *proto)
  8301. +{
  8302. + int err;
  8303. +
  8304. + err = proto_register(&proto->proto, true);
  8305. + if (err < 0)
  8306. + return err;
  8307. +
  8308. + spin_lock(&dect_proto_lock);
  8309. + dect_protos[proto->protocol] = proto;
  8310. + spin_unlock(&dect_proto_lock);
  8311. + return 0;
  8312. +}
  8313. +EXPORT_SYMBOL_GPL(dect_proto_register);
  8314. +
  8315. +void dect_proto_unregister(struct dect_proto *proto)
  8316. +{
  8317. + spin_lock(&dect_proto_lock);
  8318. + dect_protos[proto->protocol] = NULL;
  8319. + spin_unlock(&dect_proto_lock);
  8320. + proto_unregister(&proto->proto);
  8321. +}
  8322. +EXPORT_SYMBOL_GPL(dect_proto_unregister);
  8323. +
  8324. +struct sk_buff *dect_alloc_notification(u32 type, const void *data,
  8325. + unsigned int size)
  8326. +{
  8327. + struct sk_buff *skb;
  8328. +
  8329. + skb = alloc_skb(size, GFP_ATOMIC);
  8330. + if (skb == NULL)
  8331. + return NULL;
  8332. + DECT_NOTIFY_CB(skb)->type = type;
  8333. + memcpy(skb_put(skb, size), data, size);
  8334. + return skb;
  8335. +}
  8336. +EXPORT_SYMBOL_GPL(dect_alloc_notification);
  8337. +
  8338. +static void dect_destruct(struct sock *sk)
  8339. +{
  8340. + __skb_queue_purge(&sk->sk_receive_queue);
  8341. + __skb_queue_purge(&sk->sk_error_queue);
  8342. + __skb_queue_purge(&sk->sk_write_queue);
  8343. +}
  8344. +
  8345. +static int dect_release(struct socket *sock)
  8346. +{
  8347. + struct sock *sk = sock->sk;
  8348. + long timeout;
  8349. +
  8350. + if (sk == NULL)
  8351. + return 0;
  8352. +
  8353. + timeout = 0;
  8354. + if (sock_flag(sk, SOCK_LINGER) && !(current->flags & PF_EXITING))
  8355. + timeout = sk->sk_lingertime;
  8356. + sock->sk = NULL;
  8357. + sk->sk_prot->close(sk, timeout);
  8358. + return 0;
  8359. +}
  8360. +
  8361. +static int dect_bind(struct socket *sock, struct sockaddr *uaddr, int len)
  8362. +{
  8363. + struct sock *sk = sock->sk;
  8364. + int err;
  8365. +
  8366. + err = 0;
  8367. + if (sk->sk_prot->bind != NULL)
  8368. + err = sk->sk_prot->bind(sk, uaddr, len);
  8369. +
  8370. + return err;
  8371. +}
  8372. +
  8373. +static int dect_listen(struct socket *sock, int backlog)
  8374. +{
  8375. + struct sock *sk = sock->sk;
  8376. + int err;
  8377. +
  8378. + lock_sock(sk);
  8379. + err = -EINVAL;
  8380. + if (sock->state != SS_UNCONNECTED ||
  8381. + (sock->type != SOCK_STREAM && sock->type != SOCK_SEQPACKET))
  8382. + goto out;
  8383. +
  8384. + if (sk->sk_state != DECT_SK_RELEASED && sk->sk_state != DECT_SK_LISTEN)
  8385. + goto out;
  8386. +
  8387. + if (sk->sk_state != DECT_SK_LISTEN)
  8388. + sk->sk_prot->hash(sk);
  8389. + sk->sk_max_ack_backlog = backlog;
  8390. + err = 0;
  8391. +out:
  8392. + release_sock(sk);
  8393. + return err;
  8394. +}
  8395. +
  8396. +static int dect_accept(struct socket *sock, struct socket *newsock, int flags)
  8397. +{
  8398. + struct sock *sk = sock->sk, *newsk;
  8399. + int err;
  8400. +
  8401. + newsk = sk->sk_prot->accept(sk, flags, &err);
  8402. + if (newsk == NULL)
  8403. + return err;
  8404. +
  8405. + lock_sock(newsk);
  8406. + sock_graft(newsk, newsock);
  8407. + newsock->state = SS_CONNECTED;
  8408. + release_sock(newsk);
  8409. + return 0;
  8410. +}
  8411. +
  8412. +static unsigned int dect_poll(struct file *file, struct socket *sock,
  8413. + struct poll_table_struct *wait)
  8414. +{
  8415. + struct sock *sk = sock->sk;
  8416. + unsigned int mask;
  8417. +
  8418. + poll_wait(file, sk_sleep(sk), wait);
  8419. + mask = 0;
  8420. +
  8421. + if (sk->sk_state == DECT_SK_LISTEN) {
  8422. + if (!hlist_empty(&dect_csk(sk)->accept_queue))
  8423. + return POLLIN | POLLRDNORM;
  8424. + return 0;
  8425. + }
  8426. +
  8427. + /* exceptional events? */
  8428. + if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue))
  8429. + mask |= POLLERR;
  8430. + if (sk->sk_shutdown & RCV_SHUTDOWN)
  8431. + mask |= POLLRDHUP;
  8432. + if (sk->sk_shutdown == SHUTDOWN_MASK)
  8433. + mask |= POLLHUP;
  8434. +
  8435. + /* readable? */
  8436. + if (!skb_queue_empty(&sk->sk_receive_queue) ||
  8437. + (sk->sk_shutdown & RCV_SHUTDOWN))
  8438. + mask |= POLLIN | POLLRDNORM;
  8439. +
  8440. + /* Connection-based need to check for termination and startup */
  8441. + if (sk->sk_state == DECT_SK_RELEASED)
  8442. + mask |= POLLHUP;
  8443. + /* connection hasn't started yet? */
  8444. + if (sk->sk_state == DECT_SK_ESTABLISH_PENDING)
  8445. + return mask;
  8446. +
  8447. + /* writable? */
  8448. + if (sock_writeable(sk))
  8449. + mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
  8450. + else
  8451. + set_bit(SOCKWQ_ASYNC_NOSPACE, &sk->sk_socket->flags);
  8452. +
  8453. + return mask;
  8454. +}
  8455. +
  8456. +static int dect_shutdown(struct socket *sock, int how)
  8457. +{
  8458. + struct sock *sk = sock->sk;
  8459. + int err = 0;
  8460. +
  8461. + how++;
  8462. + if ((how & ~SHUTDOWN_MASK) || !how)
  8463. + return -EINVAL;
  8464. +
  8465. + lock_sock(sk);
  8466. +
  8467. + if (sock->state == SS_CONNECTING &&
  8468. + sk->sk_state == DECT_SK_ESTABLISH_PENDING)
  8469. + sock->state = SS_DISCONNECTING;
  8470. +
  8471. + switch (sk->sk_state) {
  8472. + case DECT_SK_RELEASED:
  8473. + err = -ENOTCONN;
  8474. + break;
  8475. + case DECT_SK_LISTEN:
  8476. + if (!(how & RCV_SHUTDOWN))
  8477. + break;
  8478. + default:
  8479. + sk->sk_shutdown |= how;
  8480. + if (sk->sk_prot->shutdown != NULL)
  8481. + sk->sk_prot->shutdown(sk, how);
  8482. + }
  8483. +
  8484. + /* wake up processes sleeping in poll() */
  8485. + sk->sk_state_change(sk);
  8486. + release_sock(sk);
  8487. + return err;
  8488. +}
  8489. +
  8490. +static int dect_connect(struct socket *sock, struct sockaddr *uaddr, int len,
  8491. + int flags)
  8492. +{
  8493. + struct sock *sk = sock->sk;
  8494. + long timeo;
  8495. + int err;
  8496. +
  8497. + lock_sock(sk);
  8498. + switch (sock->state) {
  8499. + case SS_CONNECTED:
  8500. + err = -EISCONN;
  8501. + goto out;
  8502. + case SS_CONNECTING:
  8503. + err = -EALREADY;
  8504. + goto out;
  8505. + case SS_UNCONNECTED:
  8506. + err = -EISCONN;
  8507. + if (sk->sk_state != DECT_SK_RELEASED)
  8508. + goto out;
  8509. + err = sk->sk_prot->connect(sk, uaddr, len);
  8510. + if (err < 0)
  8511. + goto out;
  8512. + sock->state = SS_CONNECTING;
  8513. + err = -EINPROGRESS;
  8514. + break;
  8515. + default:
  8516. + err = -EINVAL;
  8517. + goto out;
  8518. + }
  8519. +
  8520. + if (sk->sk_state == DECT_SK_ESTABLISH_PENDING) {
  8521. + timeo = sock_sndtimeo(sk, flags & O_NONBLOCK);
  8522. + err = sk_stream_wait_connect(sk, &timeo);
  8523. + if (err < 0)
  8524. + goto out;
  8525. +
  8526. + err = sock_intr_errno(timeo);
  8527. + if (signal_pending(current))
  8528. + goto out;
  8529. + }
  8530. +
  8531. + /* Connection establishment was aborted or failed */
  8532. + if (sk->sk_state == DECT_SK_RELEASED)
  8533. + goto sock_error;
  8534. +
  8535. + sock->state = SS_CONNECTED;
  8536. + err = 0;
  8537. +out:
  8538. + release_sock(sk);
  8539. + return err;
  8540. +
  8541. +sock_error:
  8542. + err = sock_error(sk) ? : -ECONNABORTED;
  8543. + sock->state = SS_UNCONNECTED;
  8544. + goto out;
  8545. +}
  8546. +
  8547. +static int dect_getname(struct socket *sock, struct sockaddr *uaddr, int *len,
  8548. + int peer)
  8549. +{
  8550. + const struct dect_proto *p;
  8551. +
  8552. + /* AF_DECT uses different address formats for the different SAPs */
  8553. + p = container_of(sock->sk->sk_prot, struct dect_proto, proto);
  8554. + if (p->getname != NULL)
  8555. + return p->getname(sock->sk, uaddr, len, peer);
  8556. + *len = 0;
  8557. + return 0;
  8558. +}
  8559. +
  8560. +static int dect_sendmsg(struct socket *sock,
  8561. + struct msghdr *msg, size_t size)
  8562. +{
  8563. + struct sock *sk = sock->sk;
  8564. +
  8565. + return sk->sk_prot->sendmsg(sk, msg, size);
  8566. +}
  8567. +
  8568. +static int dect_setsockopt(struct socket *sock, int level, int optname,
  8569. + char __user *optval, unsigned int optlen)
  8570. +{
  8571. + struct sock *sk = sock->sk;
  8572. + int err;
  8573. +
  8574. + if (level != SOL_DECT)
  8575. + return -ENOPROTOOPT;
  8576. +
  8577. + switch (optname) {
  8578. + default:
  8579. + if (sk->sk_prot->setsockopt)
  8580. + err = sk->sk_prot->setsockopt(sk, level, optname,
  8581. + optval, optlen);
  8582. + else
  8583. + err = -ENOPROTOOPT;
  8584. + }
  8585. + return err;
  8586. +}
  8587. +
  8588. +static int dect_getsockopt(struct socket *sock, int level, int optname,
  8589. + char __user *optval, int __user *optlen)
  8590. +{
  8591. + struct sock *sk = sock->sk;
  8592. + int err;
  8593. +
  8594. + if (level != SOL_DECT)
  8595. + return -ENOPROTOOPT;
  8596. +
  8597. + switch (optname) {
  8598. + default:
  8599. + if (sk->sk_prot->getsockopt)
  8600. + err = sk->sk_prot->getsockopt(sk, level, optname,
  8601. + optval, optlen);
  8602. + else
  8603. + err = -ENOPROTOOPT;
  8604. + }
  8605. + return err;
  8606. +}
  8607. +
  8608. +static int dect_create(struct net *net, struct socket *sock, int protocol,
  8609. + int kern)
  8610. +{
  8611. + struct dect_proto *p;
  8612. + struct sock *sk;
  8613. + int err = 0;
  8614. +
  8615. + if (protocol < 0 || protocol >= DECT_PROTO_NUM)
  8616. + return -EPROTONOSUPPORT;
  8617. +#ifdef CONFIG_MODULES
  8618. + if (dect_protos[protocol] == NULL) {
  8619. + err = request_module("net-pf-%d-proto-%d", PF_DECT, protocol);
  8620. + if (err < 0)
  8621. + return err;
  8622. + }
  8623. +#endif
  8624. + spin_lock(&dect_proto_lock);
  8625. + p = dect_protos[protocol];
  8626. + if (p != NULL && !try_module_get(p->proto.owner))
  8627. + p = NULL;
  8628. + spin_unlock(&dect_proto_lock);
  8629. +
  8630. + if (p == NULL)
  8631. + return -EPROTONOSUPPORT;
  8632. +
  8633. + if (p->type != sock->type) {
  8634. + err = -EPROTONOSUPPORT;
  8635. + goto err;
  8636. + }
  8637. +
  8638. + if (cap_valid(p->capability) && !capable(p->capability)) {
  8639. + err = -EACCES;
  8640. + goto err;
  8641. + }
  8642. +
  8643. + sock->state = SS_UNCONNECTED;
  8644. + sock->ops = p->ops;
  8645. +
  8646. + sk = sk_alloc(net, PF_DECT, GFP_KERNEL, &p->proto, kern);
  8647. + if (sk == NULL) {
  8648. + err = -ENOMEM;
  8649. + goto err;
  8650. + }
  8651. +
  8652. + sock_init_data(sock, sk);
  8653. + sk->sk_protocol = protocol;
  8654. + sk->sk_destruct = dect_destruct;
  8655. +
  8656. + if (sk->sk_prot->init != NULL) {
  8657. + err = sk->sk_prot->init(sk);
  8658. + if (err < 0) {
  8659. + sock_orphan(sk);
  8660. + sock_put(sk);
  8661. + }
  8662. + }
  8663. +err:
  8664. + module_put(p->proto.owner);
  8665. + return err;
  8666. +}
  8667. +
  8668. +const struct proto_ops dect_stream_ops = {
  8669. + .family = PF_DECT,
  8670. + .owner = THIS_MODULE,
  8671. + .release = dect_release,
  8672. + .bind = dect_bind,
  8673. + .connect = dect_connect,
  8674. + .socketpair = sock_no_socketpair,
  8675. + .getname = dect_getname,
  8676. + .poll = dect_poll,
  8677. + .ioctl = sock_no_ioctl,
  8678. + .listen = dect_listen,
  8679. + .accept = dect_accept,
  8680. + .shutdown = dect_shutdown,
  8681. + .setsockopt = dect_setsockopt,
  8682. + .getsockopt = dect_getsockopt,
  8683. + .sendmsg = dect_sendmsg,
  8684. + .recvmsg = sock_common_recvmsg,
  8685. + .mmap = sock_no_mmap,
  8686. + .sendpage = sock_no_sendpage,
  8687. +};
  8688. +EXPORT_SYMBOL_GPL(dect_stream_ops);
  8689. +
  8690. +const struct proto_ops dect_dgram_ops = {
  8691. + .family = PF_DECT,
  8692. + .owner = THIS_MODULE,
  8693. + .release = dect_release,
  8694. + .bind = dect_bind,
  8695. + .connect = sock_no_connect,
  8696. + .socketpair = sock_no_socketpair,
  8697. + .getname = dect_getname,
  8698. + .poll = datagram_poll,
  8699. + .ioctl = sock_no_ioctl,
  8700. + .listen = sock_no_listen,
  8701. + .accept = sock_no_accept,
  8702. + .shutdown = sock_no_shutdown,
  8703. + .setsockopt = sock_no_setsockopt,
  8704. + .getsockopt = sock_no_getsockopt,
  8705. + .sendmsg = dect_sendmsg,
  8706. + .recvmsg = sock_common_recvmsg,
  8707. + .mmap = sock_no_mmap,
  8708. + .sendpage = sock_no_sendpage,
  8709. +};
  8710. +EXPORT_SYMBOL_GPL(dect_dgram_ops);
  8711. +
  8712. +static struct net_proto_family dect_family_ops = {
  8713. + .family = PF_DECT,
  8714. + .create = dect_create,
  8715. + .owner = THIS_MODULE,
  8716. +};
  8717. +
  8718. +int __init dect_af_module_init(void)
  8719. +{
  8720. + return sock_register(&dect_family_ops);
  8721. +}
  8722. +
  8723. +void dect_af_module_exit(void)
  8724. +{
  8725. + sock_unregister(PF_DECT);
  8726. +}
  8727. +
  8728. +MODULE_ALIAS_NETPROTO(PF_DECT);
  8729. diff --git a/net/dect/ccp.c b/net/dect/ccp.c
  8730. new file mode 100644
  8731. index 0000000..c8903ad
  8732. --- /dev/null
  8733. +++ b/net/dect/ccp.c
  8734. @@ -0,0 +1,906 @@
  8735. +/*
  8736. + * DECT Cell Control Protocol
  8737. + *
  8738. + * Copyright (c) 2009 Patrick McHardy <[email protected]>
  8739. + *
  8740. + * This program is free software; you can redistribute it and/or modify
  8741. + * it under the terms of the GNU General Public License version 2 as
  8742. + * published by the Free Software Foundation.
  8743. + */
  8744. +
  8745. +#ifdef CONFIG_DECT_DEBUG
  8746. +#define DEBUG
  8747. +#endif
  8748. +
  8749. +#include <linux/kernel.h>
  8750. +#include <linux/init.h>
  8751. +#include <linux/list.h>
  8752. +#include <linux/skbuff.h>
  8753. +#include <linux/net.h>
  8754. +#include <linux/dect.h>
  8755. +#include <net/dect/dect.h>
  8756. +#include <net/dect/mac_csf.h>
  8757. +#include <net/dect/mac_ccf.h>
  8758. +#include <net/dect/ccp.h>
  8759. +#include <linux/tipc.h>
  8760. +
  8761. +static struct sk_buff *dect_ccp_msg_alloc(size_t size)
  8762. +{
  8763. + struct sk_buff *skb;
  8764. +
  8765. + size += sizeof(struct dect_ccp_msg_hdr) + 2 * LL_MAX_HEADER;
  8766. + skb = alloc_skb(size, GFP_ATOMIC);
  8767. + if (skb == NULL)
  8768. + return NULL;
  8769. + skb_reserve(skb, size);
  8770. + return skb;
  8771. +}
  8772. +
  8773. +static void dect_ccp_build_msg(struct sk_buff *skb,
  8774. + enum dect_ccp_primitives prim)
  8775. +{
  8776. + struct dect_ccp_msg_hdr *h;
  8777. +
  8778. + h = (struct dect_ccp_msg_hdr *)skb_push(skb, sizeof(*h));
  8779. + h->primitive = prim;
  8780. +}
  8781. +
  8782. +static int dect_ccp_send_to_cell(const struct dect_cell_handle *ch,
  8783. + struct sk_buff *skb,
  8784. + enum dect_ccp_primitives prim)
  8785. +{
  8786. + int err;
  8787. +
  8788. + dect_ccp_build_msg(skb, prim);
  8789. + err = tipc_send_buf(ch->portref, skb, skb->len);
  8790. + if (err < 0 && net_ratelimit())
  8791. + printk("Failed to send DECT CCP message\n");
  8792. + return err;
  8793. +}
  8794. +
  8795. +static int dect_ccp_send_to_cluster(const struct dect_cluster_handle *clh,
  8796. + struct sk_buff *skb,
  8797. + enum dect_ccp_primitives prim)
  8798. +{
  8799. + int err;
  8800. +
  8801. + dect_ccp_build_msg(skb, prim);
  8802. + err = tipc_send_buf(clh->portref, skb, skb->len);
  8803. + if (err < 0 && net_ratelimit())
  8804. + printk("Failed to send DECT CCP message\n");
  8805. + return err;
  8806. +}
  8807. +
  8808. +static void dect_ccp_build_tbc_msg(struct sk_buff *skb, const struct dect_tbc_id *id,
  8809. + u8 data)
  8810. +{
  8811. + struct dect_ccp_tbc_msg *msg;
  8812. +
  8813. + msg = (struct dect_ccp_tbc_msg *)__skb_push(skb, sizeof(*msg));
  8814. + msg->tbei = cpu_to_be32(id->tbei);
  8815. + msg->pmid = cpu_to_be32(dect_build_pmid(&id->pmid));
  8816. + msg->ari = cpu_to_be64(dect_build_ari(&id->ari));
  8817. + msg->ecn = id->ecn;
  8818. + msg->data = data;
  8819. +}
  8820. +
  8821. +static bool dect_ccp_parse_tbc_msg(struct dect_tbc_id *id, u8 *data,
  8822. + struct sk_buff *skb)
  8823. +{
  8824. + struct dect_ccp_tbc_msg *msg;
  8825. +
  8826. + if (!pskb_may_pull(skb, sizeof(*msg)))
  8827. + return false;
  8828. + msg = (struct dect_ccp_tbc_msg *)skb->data;
  8829. + __skb_pull(skb, sizeof(*msg));
  8830. +
  8831. + id->tbei = be32_to_cpu(msg->tbei);
  8832. + dect_parse_pmid(&id->pmid, be32_to_cpu(msg->pmid));
  8833. + if (!dect_parse_ari(&id->ari, be64_to_cpu(msg->ari)))
  8834. + return false;
  8835. + id->ecn = msg->ecn;
  8836. + if (data != NULL)
  8837. + *data = msg->data;
  8838. + return true;
  8839. +}
  8840. +
  8841. +static void dect_ccp_build_sysinfo(struct sk_buff *skb,
  8842. + const struct dect_ari *pari, u8 rpn,
  8843. + const struct dect_si *si)
  8844. +{
  8845. + struct dect_ccp_sysinfo_msg *msg;
  8846. + unsigned int i;
  8847. +
  8848. + msg = (struct dect_ccp_sysinfo_msg *)__skb_push(skb, sizeof(*msg));
  8849. + msg->pari = cpu_to_be64(dect_build_ari(pari));
  8850. + for (i = 0; i < si->num_saris; i++)
  8851. + msg->sari[i] = cpu_to_be64(dect_build_ari(&si->sari[i].ari));
  8852. + msg->num_saris = i;
  8853. + msg->fpc = cpu_to_be64(si->fpc.fpc);
  8854. + msg->hlc = cpu_to_be64(si->fpc.hlc);
  8855. + msg->mfn = cpu_to_be32(si->mfn.num);
  8856. + msg->rpn = rpn;
  8857. +}
  8858. +
  8859. +static bool dect_ccp_parse_sysinfo(struct dect_ari *pari, u8 *rpn,
  8860. + struct dect_si *si, struct sk_buff *skb)
  8861. +{
  8862. + struct dect_ccp_sysinfo_msg *msg;
  8863. + unsigned int i;
  8864. +
  8865. + if (!pskb_may_pull(skb, sizeof(*msg)))
  8866. + return false;
  8867. + msg = (struct dect_ccp_sysinfo_msg *)skb->data;
  8868. + __skb_pull(skb, sizeof(*msg));
  8869. +
  8870. + if (!dect_parse_ari(pari, be64_to_cpu(msg->pari)))
  8871. + return false;
  8872. + *rpn = msg->rpn;
  8873. +
  8874. + if (msg->num_saris > ARRAY_SIZE(si->sari))
  8875. + return false;
  8876. + for (i = 0; i < msg->num_saris; i++) {
  8877. + if (!dect_parse_ari(&si->sari[i].ari,
  8878. + be64_to_cpu(msg->sari[i])))
  8879. + return false;
  8880. + }
  8881. + si->fpc.fpc = be64_to_cpu(msg->fpc);
  8882. + si->fpc.hlc = be64_to_cpu(msg->hlc);
  8883. + si->mfn.num = be32_to_cpu(msg->mfn);
  8884. + return true;
  8885. +}
  8886. +
  8887. +static int dect_ccp_send_set_mode(const struct dect_cell_handle *ch,
  8888. + enum dect_cluster_modes mode)
  8889. +{
  8890. + struct dect_ccp_mode_msg *msg;
  8891. + struct sk_buff *skb;
  8892. +
  8893. + skb = dect_ccp_msg_alloc(sizeof(*msg));
  8894. + if (skb == NULL)
  8895. + return -ENOMEM;
  8896. + msg = (struct dect_ccp_mode_msg *)__skb_push(skb, sizeof(*msg));
  8897. + msg->mode = mode;
  8898. +
  8899. + return dect_ccp_send_to_cell(ch, skb, DECT_CCP_SET_MODE);
  8900. +}
  8901. +
  8902. +static void dect_ccp_parse_set_mode(const struct dect_cell_handle *ch,
  8903. + struct sk_buff *skb)
  8904. +{
  8905. + struct dect_ccp_mode_msg *msg;
  8906. +
  8907. + if (!pskb_may_pull(skb, sizeof(*msg)))
  8908. + return;
  8909. + msg = (struct dect_ccp_mode_msg *)skb->data;
  8910. +
  8911. + ch->ops->set_mode(ch, msg->mode);
  8912. +}
  8913. +
  8914. +static int dect_ccp_send_scan(const struct dect_cell_handle *ch,
  8915. + const struct dect_llme_req *lreq,
  8916. + const struct dect_ari *ari,
  8917. + const struct dect_ari *ari_mask)
  8918. +{
  8919. + struct dect_ccp_scan_msg *msg;
  8920. + struct sk_buff *skb;
  8921. +
  8922. + skb = dect_ccp_msg_alloc(sizeof(*msg));
  8923. + if (skb == NULL)
  8924. + return -ENOMEM;
  8925. + msg = (struct dect_ccp_scan_msg *)__skb_push(skb, sizeof(*msg));
  8926. + msg->ari = cpu_to_be64(dect_build_ari(ari));
  8927. + msg->ari_mask = cpu_to_be64(dect_build_ari(ari_mask));
  8928. +
  8929. + return dect_ccp_send_to_cell(ch, skb, DECT_CCP_SCAN);
  8930. +}
  8931. +
  8932. +static void dect_ccp_parse_scan(const struct dect_cell_handle *ch,
  8933. + struct sk_buff *skb)
  8934. +{
  8935. + struct dect_ccp_scan_msg *msg;
  8936. + struct dect_ari ari, ari_mask;
  8937. +
  8938. + if (!pskb_may_pull(skb, sizeof(*msg)))
  8939. + return;
  8940. + msg = (struct dect_ccp_scan_msg *)skb->data;
  8941. +
  8942. + if (!dect_parse_ari(&ari, be64_to_cpu(msg->ari)))
  8943. + return;
  8944. + if (!dect_parse_ari(&ari_mask, be64_to_cpu(msg->ari_mask)))
  8945. + return;
  8946. + ch->ops->scan(ch, NULL, &ari, &ari_mask);
  8947. +}
  8948. +
  8949. +static int dect_ccp_send_preload(const struct dect_cell_handle *ch,
  8950. + const struct dect_ari *pari, u8 rpn,
  8951. + const struct dect_si *si)
  8952. +{
  8953. + struct sk_buff *skb;
  8954. +
  8955. + skb = dect_ccp_msg_alloc(sizeof(struct dect_ccp_sysinfo_msg));
  8956. + if (skb == NULL)
  8957. + return -ENOMEM;
  8958. + dect_ccp_build_sysinfo(skb, pari, rpn, si);
  8959. +
  8960. + return dect_ccp_send_to_cell(ch, skb, DECT_CCP_PRELOAD);
  8961. +}
  8962. +
  8963. +static void dect_ccp_parse_preload(const struct dect_cell_handle *ch,
  8964. + struct sk_buff *skb)
  8965. +{
  8966. + struct dect_ari pari;
  8967. + struct dect_si si;
  8968. + u8 rpn;
  8969. +
  8970. + if (!dect_ccp_parse_sysinfo(&pari, &rpn, &si, skb))
  8971. + return;
  8972. + ch->ops->preload(ch, &pari, rpn, &si);
  8973. +}
  8974. +
  8975. +static int dect_ccp_send_enable(const struct dect_cell_handle *ch)
  8976. +{
  8977. + struct sk_buff *skb;
  8978. +
  8979. + skb = dect_ccp_msg_alloc(0);
  8980. + if (skb == NULL)
  8981. + return -ENOMEM;
  8982. + return dect_ccp_send_to_cell(ch, skb, DECT_CCP_ENABLE);
  8983. +}
  8984. +
  8985. +static void dect_ccp_parse_enable(const struct dect_cell_handle *ch,
  8986. + struct sk_buff *skb)
  8987. +{
  8988. + ch->ops->enable(ch);
  8989. +}
  8990. +
  8991. +static void dect_ccp_send_page_req(const struct dect_cell_handle *ch,
  8992. + struct sk_buff *skb)
  8993. +{
  8994. + struct dect_ccp_page_msg *msg;
  8995. +
  8996. + msg = (struct dect_ccp_page_msg *)__skb_push(skb, sizeof(*msg));
  8997. + msg->fast_page = DECT_BMC_CB(skb)->fast_page;
  8998. + msg->long_page = DECT_BMC_CB(skb)->long_page;
  8999. +
  9000. + dect_ccp_send_to_cell(ch, skb, DECT_CCP_PAGE_REQ);
  9001. +}
  9002. +
  9003. +static void dect_ccp_parse_page_req(const struct dect_cell_handle *ch,
  9004. + struct sk_buff *skb)
  9005. +{
  9006. + struct dect_ccp_page_msg *msg;
  9007. +
  9008. + if (!pskb_may_pull(skb, sizeof(*msg)))
  9009. + return;
  9010. + msg = (struct dect_ccp_page_msg *)skb->data;
  9011. + __pskb_pull(skb, sizeof(*msg));
  9012. +
  9013. + DECT_BMC_CB(skb)->fast_page = msg->fast_page;
  9014. + DECT_BMC_CB(skb)->long_page = msg->long_page;
  9015. +
  9016. + ch->ops->page_req(ch, skb);
  9017. +}
  9018. +
  9019. +static int dect_ccp_send_tbc_establish_req(const struct dect_cell_handle *ch,
  9020. + const struct dect_tbc_id *id,
  9021. + const struct dect_channel_desc *chd,
  9022. + enum dect_mac_service_types service,
  9023. + bool handover)
  9024. +{
  9025. + struct sk_buff *skb;
  9026. +
  9027. + skb = dect_ccp_msg_alloc(sizeof(struct dect_ccp_tbc_msg));
  9028. + if (skb == NULL)
  9029. + return -ENOMEM;
  9030. + dect_ccp_build_tbc_msg(skb, id, 0);
  9031. + return dect_ccp_send_to_cell(ch, skb, DECT_CCP_TBC_ESTABLISH_REQ);
  9032. +}
  9033. +
  9034. +static void dect_ccp_parse_tbc_establish_req(const struct dect_cell_handle *ch,
  9035. + struct sk_buff *skb)
  9036. +{
  9037. + struct dect_tbc_id id;
  9038. +
  9039. + if (!dect_ccp_parse_tbc_msg(&id, NULL, skb))
  9040. + return;
  9041. + ch->ops->tbc_establish_req(ch, &id, NULL, DECT_SERVICE_IN_MIN_DELAY, false);
  9042. +}
  9043. +
  9044. +static void dect_ccp_send_tbc_dis_req(const struct dect_cell_handle *ch,
  9045. + const struct dect_tbc_id *id,
  9046. + enum dect_release_reasons reason)
  9047. +{
  9048. + struct sk_buff *skb;
  9049. +
  9050. + skb = dect_ccp_msg_alloc(sizeof(struct dect_ccp_tbc_msg));
  9051. + if (skb == NULL)
  9052. + return;
  9053. + dect_ccp_build_tbc_msg(skb, id, reason);
  9054. + dect_ccp_send_to_cell(ch, skb, DECT_CCP_TBC_DIS_REQ);
  9055. +}
  9056. +
  9057. +static void dect_ccp_parse_tbc_dis_req(const struct dect_cell_handle *ch,
  9058. + struct sk_buff *skb)
  9059. +{
  9060. + struct dect_tbc_id id;
  9061. + u8 reason;
  9062. +
  9063. + if (!dect_ccp_parse_tbc_msg(&id, &reason, skb))
  9064. + return;
  9065. + ch->ops->tbc_dis_req(ch, &id, reason);
  9066. +}
  9067. +
  9068. +static int dect_ccp_send_tbc_establish_res(const struct dect_cell_handle *ch,
  9069. + const struct dect_tbc_id *id)
  9070. +{
  9071. + struct sk_buff *skb;
  9072. +
  9073. + skb = dect_ccp_msg_alloc(sizeof(struct dect_ccp_tbc_msg));
  9074. + if (skb == NULL)
  9075. + return -ENOMEM;
  9076. + dect_ccp_build_tbc_msg(skb, id, 0);
  9077. + return dect_ccp_send_to_cell(ch, skb, DECT_CCP_TBC_ESTABLISH_RES);
  9078. +}
  9079. +
  9080. +static void dect_ccp_parse_tbc_establish_res(const struct dect_cell_handle *ch,
  9081. + struct sk_buff *skb)
  9082. +{
  9083. + struct dect_tbc_id id;
  9084. +
  9085. + if (!dect_ccp_parse_tbc_msg(&id, NULL, skb))
  9086. + return;
  9087. + ch->ops->tbc_establish_res(ch, &id);
  9088. +}
  9089. +
  9090. +static void dect_ccp_send_tbc_data_req(const struct dect_cell_handle *ch,
  9091. + const struct dect_tbc_id *id,
  9092. + enum dect_data_channels chan,
  9093. + struct sk_buff *skb)
  9094. +{
  9095. + dect_ccp_build_tbc_msg(skb, id, chan);
  9096. + dect_ccp_send_to_cell(ch, skb, DECT_CCP_TBC_DATA_REQ);
  9097. +}
  9098. +
  9099. +static int dect_ccp_send_tbc_enc_key_req(const struct dect_cell_handle *ch,
  9100. + const struct dect_tbc_id *id, u64 ck)
  9101. +{
  9102. + struct dect_ccp_enc_key_msg *msg;
  9103. + struct sk_buff *skb;
  9104. +
  9105. + skb = dect_ccp_msg_alloc(sizeof(struct dect_ccp_tbc_msg) + sizeof(*msg));
  9106. + if (skb == NULL)
  9107. + return -ENOMEM;
  9108. +
  9109. + dect_ccp_build_tbc_msg(skb, id, 0);
  9110. + msg = (struct dect_ccp_enc_key_msg *)skb_tail_pointer(skb);
  9111. + msg->key = cpu_to_be64(ck);
  9112. +
  9113. + return dect_ccp_send_to_cell(ch, skb, DECT_CCP_TBC_ENC_KEY_REQ);
  9114. +}
  9115. +
  9116. +static void dect_ccp_parse_tbc_enc_key_req(const struct dect_cell_handle *ch,
  9117. + struct sk_buff *skb)
  9118. +{
  9119. + const struct dect_ccp_enc_key_msg *msg;
  9120. + struct dect_tbc_id id;
  9121. + u64 ck;
  9122. +
  9123. + if (!dect_ccp_parse_tbc_msg(&id, NULL, skb))
  9124. + return;
  9125. +
  9126. + if (!pskb_may_pull(skb, sizeof(*msg)))
  9127. + return;
  9128. + msg = (struct dect_ccp_enc_key_msg *)skb->data;
  9129. + ck = be64_to_cpu(msg->key);
  9130. +
  9131. + ch->ops->tbc_enc_key_req(ch, &id, ck);
  9132. +}
  9133. +
  9134. +static int dect_ccp_send_tbc_enc_eks_req(const struct dect_cell_handle *ch,
  9135. + const struct dect_tbc_id *id,
  9136. + enum dect_cipher_states status)
  9137. +{
  9138. + struct sk_buff *skb;
  9139. +
  9140. + skb = dect_ccp_msg_alloc(sizeof(struct dect_ccp_tbc_msg));
  9141. + if (skb == NULL)
  9142. + return -ENOMEM;
  9143. + dect_ccp_build_tbc_msg(skb, id, status);
  9144. + return dect_ccp_send_to_cell(ch, skb, DECT_CCP_TBC_ENC_EKS_REQ);
  9145. +}
  9146. +
  9147. +static void dect_ccp_parse_tbc_enc_eks_req(const struct dect_cell_handle *ch,
  9148. + struct sk_buff *skb)
  9149. +{
  9150. + struct dect_tbc_id id;
  9151. + u8 status;
  9152. +
  9153. + if (!dect_ccp_parse_tbc_msg(&id, &status, skb))
  9154. + return;
  9155. +
  9156. + switch (status) {
  9157. + case DECT_CIPHER_DISABLED:
  9158. + case DECT_CIPHER_ENABLED:
  9159. + break;
  9160. + default:
  9161. + return;
  9162. + }
  9163. +
  9164. + ch->ops->tbc_enc_eks_req(ch, &id, status);
  9165. +}
  9166. +
  9167. +static void dect_ccp_send_scan_report(const struct dect_cluster_handle *clh,
  9168. + const struct dect_scan_result *res)
  9169. +{
  9170. +}
  9171. +
  9172. +static void dect_ccp_send_mac_info_ind(const struct dect_cluster_handle *clh,
  9173. + const struct dect_idi *idi,
  9174. + const struct dect_si *si)
  9175. +{
  9176. + struct sk_buff *skb;
  9177. +
  9178. + skb = dect_ccp_msg_alloc(sizeof(struct dect_ccp_sysinfo_msg));
  9179. + if (skb == NULL)
  9180. + return;
  9181. +
  9182. + dect_ccp_build_sysinfo(skb, &idi->pari, idi->rpn, si);
  9183. + dect_ccp_send_to_cluster(clh, skb, DECT_CCP_MAC_INFO_IND);
  9184. +}
  9185. +
  9186. +static void dect_ccp_parse_mac_info_ind(const struct dect_cell_handle *ch,
  9187. + struct sk_buff *skb)
  9188. +{
  9189. + const struct dect_cluster_handle *clh = ch->clh;
  9190. + struct dect_idi idi;
  9191. + struct dect_si si;
  9192. +
  9193. + if (!dect_ccp_parse_sysinfo(&idi.pari, &idi.rpn, &si, skb))
  9194. + return;
  9195. + idi.e = si.num_saris ? true : false;
  9196. +
  9197. + clh->ops->mac_info_ind(clh, &idi, &si);
  9198. +}
  9199. +
  9200. +static int dect_ccp_send_tbc_establish_ind(const struct dect_cluster_handle *clh,
  9201. + const struct dect_cell_handle *ch,
  9202. + const struct dect_tbc_id *id,
  9203. + enum dect_mac_service_types service,
  9204. + bool handover)
  9205. +{
  9206. + struct sk_buff *skb;
  9207. +
  9208. + skb = dect_ccp_msg_alloc(sizeof(struct dect_ccp_tbc_msg));
  9209. + if (skb == NULL)
  9210. + return -ENOMEM;
  9211. + dect_ccp_build_tbc_msg(skb, id, 0);
  9212. +
  9213. + return dect_ccp_send_to_cluster(clh, skb, DECT_CCP_TBC_ESTABLISH_IND);
  9214. +}
  9215. +
  9216. +static void dect_ccp_parse_tbc_establish_ind(const struct dect_cell_handle *ch,
  9217. + struct sk_buff *skb)
  9218. +{
  9219. + const struct dect_cluster_handle *clh = ch->clh;
  9220. + struct dect_tbc_id id;
  9221. +
  9222. + if (!dect_ccp_parse_tbc_msg(&id, NULL, skb))
  9223. + return;
  9224. + clh->ops->tbc_establish_ind(clh, ch, &id, DECT_SERVICE_IN_MIN_DELAY, false);
  9225. +}
  9226. +
  9227. +static int dect_ccp_send_tbc_establish_cfm(const struct dect_cluster_handle *clh,
  9228. + const struct dect_tbc_id *id,
  9229. + bool success, u8 rx_slot)
  9230. +{
  9231. + struct sk_buff *skb;
  9232. +
  9233. + skb = dect_ccp_msg_alloc(sizeof(struct dect_ccp_tbc_msg));
  9234. + if (skb == NULL)
  9235. + return -ENOMEM;
  9236. + dect_ccp_build_tbc_msg(skb, id, 0);
  9237. +
  9238. + return dect_ccp_send_to_cluster(clh, skb, DECT_CCP_TBC_ESTABLISH_CFM);
  9239. +}
  9240. +
  9241. +static void dect_ccp_parse_tbc_establish_cfm(const struct dect_cell_handle *ch,
  9242. + struct sk_buff *skb)
  9243. +{
  9244. + const struct dect_cluster_handle *clh = ch->clh;
  9245. + struct dect_tbc_id id;
  9246. +
  9247. + if (!dect_ccp_parse_tbc_msg(&id, NULL, skb))
  9248. + return;
  9249. + clh->ops->tbc_establish_cfm(clh, &id, true, 0);
  9250. +}
  9251. +
  9252. +static int dect_ccp_send_tbc_event_ind(const struct dect_cluster_handle *clh,
  9253. + const struct dect_tbc_id *id,
  9254. + enum dect_tbc_event event)
  9255. +{
  9256. + struct sk_buff *skb;
  9257. +
  9258. + skb = dect_ccp_msg_alloc(sizeof(struct dect_ccp_tbc_msg));
  9259. + if (skb == NULL)
  9260. + return -ENOMEM;
  9261. + dect_ccp_build_tbc_msg(skb, id, event);
  9262. +
  9263. + return dect_ccp_send_to_cluster(clh, skb, DECT_CCP_TBC_EVENT_IND);
  9264. +}
  9265. +
  9266. +static void dect_ccp_parse_tbc_event_ind(const struct dect_cell_handle *ch,
  9267. + struct sk_buff *skb)
  9268. +{
  9269. + const struct dect_cluster_handle *clh = ch->clh;
  9270. + struct dect_tbc_id id;
  9271. + u8 event;
  9272. +
  9273. + if (!dect_ccp_parse_tbc_msg(&id, &event, skb))
  9274. + return;
  9275. + clh->ops->tbc_event_ind(clh, &id, event);
  9276. +}
  9277. +
  9278. +static void dect_ccp_send_tbc_data_ind(const struct dect_cluster_handle *clh,
  9279. + const struct dect_tbc_id *id,
  9280. + enum dect_data_channels chan,
  9281. + struct sk_buff *skb)
  9282. +{
  9283. + dect_ccp_build_tbc_msg(skb, id, chan);
  9284. + dect_ccp_send_to_cluster(clh, skb, DECT_CCP_TBC_DATA_IND);
  9285. +}
  9286. +
  9287. +static void dect_ccp_parse_tbc_data_ind(const struct dect_cell_handle *ch,
  9288. + struct sk_buff *skb)
  9289. +{
  9290. + const struct dect_cluster_handle *clh = ch->clh;
  9291. + struct dect_tbc_id id;
  9292. + u8 chan;
  9293. +
  9294. + if (!dect_ccp_parse_tbc_msg(&id, &chan, skb))
  9295. + return;
  9296. + clh->ops->tbc_data_ind(clh, &id, chan, skb);
  9297. +}
  9298. +
  9299. +static void dect_ccp_send_tbc_dis_ind(const struct dect_cluster_handle *clh,
  9300. + const struct dect_tbc_id *id,
  9301. + enum dect_release_reasons reason)
  9302. +{
  9303. + struct sk_buff *skb;
  9304. +
  9305. + skb = dect_ccp_msg_alloc(sizeof(struct dect_ccp_tbc_msg));
  9306. + if (skb == NULL)
  9307. + return;// -ENOMEM;
  9308. + dect_ccp_build_tbc_msg(skb, id, reason);
  9309. +
  9310. + dect_ccp_send_to_cluster(clh, skb, DECT_CCP_TBC_DIS_IND);
  9311. +}
  9312. +
  9313. +static void dect_ccp_parse_tbc_dis_ind(const struct dect_cell_handle *ch,
  9314. + struct sk_buff *skb)
  9315. +{
  9316. + const struct dect_cluster_handle *clh = ch->clh;
  9317. + struct dect_tbc_id id;
  9318. + u8 reason;
  9319. +
  9320. + if (!dect_ccp_parse_tbc_msg(&id, &reason, skb))
  9321. + return;
  9322. + clh->ops->tbc_dis_ind(clh, &id, reason);
  9323. +}
  9324. +
  9325. +static void dect_ccp_rcv_cell_msg(void *handle, u32 portref,
  9326. + struct sk_buff **pskb,
  9327. + const u8 *data, u32 size)
  9328. +{
  9329. + struct dect_cell_handle *ch = handle;
  9330. + struct dect_ccp_msg_hdr *h;
  9331. + struct sk_buff *skb = *pskb;
  9332. +
  9333. + if (!pskb_may_pull(skb, sizeof(*h)))
  9334. + return;
  9335. + h = (struct dect_ccp_msg_hdr *)skb->data;
  9336. + __skb_pull(skb, sizeof(*h));
  9337. +
  9338. + switch (h->primitive) {
  9339. + case DECT_CCP_MAC_INFO_IND:
  9340. + return dect_ccp_parse_mac_info_ind(ch, skb);
  9341. + case DECT_CCP_TBC_ESTABLISH_IND:
  9342. + return dect_ccp_parse_tbc_establish_ind(ch, skb);
  9343. + case DECT_CCP_TBC_ESTABLISH_CFM:
  9344. + return dect_ccp_parse_tbc_establish_cfm(ch, skb);
  9345. + case DECT_CCP_TBC_EVENT_IND:
  9346. + return dect_ccp_parse_tbc_event_ind(ch, skb);
  9347. + case DECT_CCP_TBC_DATA_IND:
  9348. + return dect_ccp_parse_tbc_data_ind(ch, skb);
  9349. + case DECT_CCP_TBC_DIS_IND:
  9350. + return dect_ccp_parse_tbc_dis_ind(ch, skb);
  9351. + }
  9352. +}
  9353. +
  9354. +static void dect_ccp_cl_disconnect(void *handle, u32 portref,
  9355. + struct sk_buff **pskb,
  9356. + const u8 *data, u32 size, int reason)
  9357. +{
  9358. + struct dect_cell_handle *ch = handle;
  9359. + struct dect_cluster_handle *clh = ch->clh;
  9360. +
  9361. + pr_debug("cell disconnected\n");
  9362. + clh->ops->unbind(clh, ch);
  9363. + kfree(ch);
  9364. +}
  9365. +
  9366. +static const struct dect_csf_ops dect_ccp_csf_ops = {
  9367. + .set_mode = dect_ccp_send_set_mode,
  9368. + .scan = dect_ccp_send_scan,
  9369. + .enable = dect_ccp_send_enable,
  9370. + .preload = dect_ccp_send_preload,
  9371. + .page_req = dect_ccp_send_page_req,
  9372. + .tbc_establish_req = dect_ccp_send_tbc_establish_req,
  9373. + .tbc_establish_res = dect_ccp_send_tbc_establish_res,
  9374. + .tbc_dis_req = dect_ccp_send_tbc_dis_req,
  9375. + .tbc_enc_key_req = dect_ccp_send_tbc_enc_key_req,
  9376. + .tbc_enc_eks_req = dect_ccp_send_tbc_enc_eks_req,
  9377. + .tbc_data_req = dect_ccp_send_tbc_data_req,
  9378. +};
  9379. +
  9380. +static void dect_ccp_cl_named_msg(void *handle, u32 portref,
  9381. + struct sk_buff **pskb,
  9382. + const u8 *data, u32 size,
  9383. + u32 importance,
  9384. + const struct tipc_portid *source,
  9385. + const struct tipc_name_seq *dest)
  9386. +{
  9387. + struct dect_cluster *cl = handle;
  9388. + struct dect_cluster_handle *clh = &cl->handle;
  9389. + struct dect_cell_handle *ch;
  9390. + struct iovec ack = { NULL, 0};
  9391. + int err;
  9392. +
  9393. + ch = kzalloc(sizeof(*ch), GFP_ATOMIC);
  9394. + if (ch == NULL)
  9395. + goto err1;
  9396. + ch->ops = &dect_ccp_csf_ops;
  9397. +
  9398. + err = tipc_createport(cl->tipc_id, ch, TIPC_HIGH_IMPORTANCE,
  9399. + NULL, NULL, dect_ccp_cl_disconnect,
  9400. + NULL, NULL, dect_ccp_rcv_cell_msg, NULL,
  9401. + &ch->portref);
  9402. + if (err < 0)
  9403. + goto err2;
  9404. +
  9405. + err = tipc_connect2port(ch->portref, source);
  9406. + if (err < 0)
  9407. + goto err3;
  9408. +
  9409. + err = tipc_send(ch->portref, 1, &ack);
  9410. + if (err < 0)
  9411. + goto err3;
  9412. +
  9413. + err = clh->ops->bind(clh, ch);
  9414. + if (err < 0)
  9415. + goto err4;
  9416. + return;
  9417. +
  9418. +err4:
  9419. + tipc_disconnect(ch->portref);
  9420. +err3:
  9421. + tipc_deleteport(ch->portref);
  9422. +err2:
  9423. + kfree(ch);
  9424. +err1:
  9425. + return;
  9426. +}
  9427. +
  9428. +/**
  9429. + * dect_ccp_cluster_init - Initialize a cluster control CCP instance
  9430. + *
  9431. + * @cl: DECT cluster
  9432. + */
  9433. +int dect_ccp_cluster_init(struct dect_cluster *cl)
  9434. +{
  9435. + struct tipc_name_seq seq;
  9436. + int err;
  9437. +
  9438. + err = tipc_attach(&cl->tipc_id, NULL, NULL);
  9439. + if (err < 0)
  9440. + goto err1;
  9441. +
  9442. + err = tipc_createport(cl->tipc_id, cl, TIPC_HIGH_IMPORTANCE,
  9443. + NULL, NULL, NULL, NULL, dect_ccp_cl_named_msg,
  9444. + NULL, NULL, &cl->tipc_portref);
  9445. + if (err < 0)
  9446. + goto err2;
  9447. +
  9448. + seq.type = DECT_CCP_TIPC_TYPE;
  9449. + seq.lower = DECT_CCP_CLUSTER_PORT_BASE + cl->index;
  9450. + seq.upper = DECT_CCP_CLUSTER_PORT_BASE + cl->index;
  9451. + err = tipc_publish(cl->tipc_portref, TIPC_CLUSTER_SCOPE, &seq);
  9452. + if (err < 0)
  9453. + goto err3;
  9454. + return 0;
  9455. +
  9456. +err3:
  9457. + tipc_deleteport(cl->tipc_portref);
  9458. +err2:
  9459. + tipc_detach(cl->tipc_id);
  9460. +err1:
  9461. + return err;
  9462. +}
  9463. +
  9464. +void dect_ccp_cluster_shutdown(struct dect_cluster *cl)
  9465. +{
  9466. + tipc_detach(cl->tipc_id);
  9467. +}
  9468. +
  9469. +static void dect_ccp_rcv_cluster_msg(void *handle, u32 portref,
  9470. + struct sk_buff **pskb,
  9471. + const u8 *data, u32 size)
  9472. +{
  9473. + struct sk_buff *skb = *pskb;
  9474. + struct dect_cell_handle *ch = handle;
  9475. + struct dect_ccp_msg_hdr *h;
  9476. +
  9477. + if (!pskb_may_pull(skb, sizeof(*h)))
  9478. + return;
  9479. + h = (struct dect_ccp_msg_hdr *)skb->data;
  9480. + __skb_pull(skb, sizeof(*h));
  9481. +
  9482. + switch (h->primitive) {
  9483. + case DECT_CCP_SET_MODE:
  9484. + return dect_ccp_parse_set_mode(ch, skb);
  9485. + case DECT_CCP_SCAN:
  9486. + return dect_ccp_parse_scan(ch, skb);
  9487. + case DECT_CCP_ENABLE:
  9488. + return dect_ccp_parse_enable(ch, skb);
  9489. + case DECT_CCP_PRELOAD:
  9490. + return dect_ccp_parse_preload(ch, skb);
  9491. + case DECT_CCP_PAGE_REQ:
  9492. + return dect_ccp_parse_page_req(ch, skb);
  9493. + case DECT_CCP_TBC_ESTABLISH_REQ:
  9494. + return dect_ccp_parse_tbc_establish_req(ch, skb);
  9495. + case DECT_CCP_TBC_ESTABLISH_RES:
  9496. + return dect_ccp_parse_tbc_establish_res(ch, skb);
  9497. + case DECT_CCP_TBC_DIS_REQ:
  9498. + return dect_ccp_parse_tbc_dis_req(ch, skb);
  9499. + case DECT_CCP_TBC_ENC_KEY_REQ:
  9500. + return dect_ccp_parse_tbc_enc_key_req(ch, skb);
  9501. + case DECT_CCP_TBC_ENC_EKS_REQ:
  9502. + return dect_ccp_parse_tbc_enc_eks_req(ch, skb);
  9503. + }
  9504. +}
  9505. +
  9506. +static void dect_ccp_cluster_disconnect(void *handle, u32 portref,
  9507. + struct sk_buff **pskb,
  9508. + const u8 *data, u32 size, int reason)
  9509. +{
  9510. + pr_debug("Cluster disconnected\n");
  9511. +#if 0
  9512. + struct dect_cell_handle *clh = handle;
  9513. +
  9514. + clh->ops->unbind(clh);
  9515. +#endif
  9516. +}
  9517. +
  9518. +static void dect_ccp_subscr_rcv(void *handle, u32 portref,
  9519. + struct sk_buff **pskb,
  9520. + const u8 *data, u32 size)
  9521. +{
  9522. + struct dect_cell_handle *ch = handle;
  9523. + struct dect_cluster_handle *clh = ch->clh;
  9524. + struct sk_buff *skb = *pskb;
  9525. + struct tipc_event *ev;
  9526. + struct tipc_name name;
  9527. + int err;
  9528. +
  9529. + if (!pskb_may_pull(skb, sizeof(*ev)))
  9530. + return;
  9531. + ev = (struct tipc_event *)skb->data;
  9532. +
  9533. + if (ev->event != TIPC_PUBLISHED)
  9534. + return;
  9535. +
  9536. + /* Connect to cluster */
  9537. + err = tipc_createport(clh->tipc_id, ch, TIPC_HIGH_IMPORTANCE,
  9538. + NULL, NULL, dect_ccp_cluster_disconnect,
  9539. + NULL, NULL, dect_ccp_rcv_cluster_msg, NULL,
  9540. + &clh->portref);
  9541. + if (err < 0)
  9542. + goto err1;
  9543. +
  9544. + name.type = DECT_CCP_TIPC_TYPE;
  9545. + name.instance = DECT_CCP_CLUSTER_PORT_BASE + clh->index;
  9546. + err = tipc_send2name(clh->portref, &name, 0, 0, NULL);
  9547. + if (err < 0)
  9548. + goto err2;
  9549. + return;
  9550. +
  9551. +err2:
  9552. + tipc_deleteport(clh->portref);
  9553. +err1:
  9554. + return;
  9555. +}
  9556. +
  9557. +/**
  9558. + * dect_ccp_cell_init - Initialize a cell CCP instance
  9559. + *
  9560. + * @cell: DECT cell
  9561. + */
  9562. +static int dect_ccp_bind_cell(struct dect_cluster_handle *clh,
  9563. + struct dect_cell_handle *ch)
  9564. +{
  9565. + struct tipc_subscr subscr;
  9566. + struct iovec iov = { &subscr, sizeof(subscr) };
  9567. + struct tipc_name tname;
  9568. + int err;
  9569. +
  9570. + err = tipc_attach(&clh->tipc_id, NULL, NULL);
  9571. + if (err < 0)
  9572. + goto err1;
  9573. + ch->clh = clh;
  9574. +
  9575. + /* Connect to topology service and subscribe to cluster port */
  9576. + err = tipc_createport(clh->tipc_id, ch, TIPC_CRITICAL_IMPORTANCE,
  9577. + NULL, NULL, NULL, NULL, NULL,
  9578. + dect_ccp_subscr_rcv, NULL, &clh->tportref);
  9579. + if (err < 0)
  9580. + goto err2;
  9581. +
  9582. + subscr.seq.type = DECT_CCP_TIPC_TYPE;
  9583. + subscr.seq.lower = DECT_CCP_CLUSTER_PORT_BASE + clh->index;
  9584. + subscr.seq.upper = DECT_CCP_CLUSTER_PORT_BASE + clh->index;
  9585. + subscr.timeout = TIPC_WAIT_FOREVER;
  9586. + subscr.filter = TIPC_SUB_PORTS;
  9587. + memset(&subscr.usr_handle, 0, sizeof(subscr.usr_handle));
  9588. +
  9589. + tname.type = TIPC_TOP_SRV;
  9590. + tname.instance = TIPC_TOP_SRV;
  9591. +
  9592. + err = tipc_send2name(clh->tportref, &tname, 0, 1, &iov);
  9593. + if (err < 0)
  9594. + goto err3;
  9595. + return 0;
  9596. +
  9597. +err3:
  9598. + tipc_deleteport(clh->tportref);
  9599. +err2:
  9600. + tipc_detach(clh->tipc_id);
  9601. +err1:
  9602. + return err;
  9603. +
  9604. +}
  9605. +
  9606. +static void dect_ccp_unbind_cell(struct dect_cluster_handle *clh,
  9607. + struct dect_cell_handle *ch)
  9608. +{
  9609. + tipc_detach(clh->tipc_id);
  9610. +}
  9611. +
  9612. +static void dect_ccp_send_bmc_page_ind(const struct dect_cluster_handle *clh,
  9613. + struct sk_buff *skb)
  9614. +{
  9615. +}
  9616. +
  9617. +static const struct dect_ccf_ops dect_ccp_ccf_ops = {
  9618. + .bind = dect_ccp_bind_cell,
  9619. + .unbind = dect_ccp_unbind_cell,
  9620. + .scan_report = dect_ccp_send_scan_report,
  9621. + .mac_info_ind = dect_ccp_send_mac_info_ind,
  9622. + .tbc_establish_ind = dect_ccp_send_tbc_establish_ind,
  9623. + .tbc_establish_cfm = dect_ccp_send_tbc_establish_cfm,
  9624. + .tbc_event_ind = dect_ccp_send_tbc_event_ind,
  9625. + .tbc_dis_ind = dect_ccp_send_tbc_dis_ind,
  9626. + .tbc_data_ind = dect_ccp_send_tbc_data_ind,
  9627. + .bmc_page_ind = dect_ccp_send_bmc_page_ind,
  9628. +};
  9629. +
  9630. +struct dect_cluster_handle *dect_ccp_cell_init(struct dect_cell *cell, u8 clindex)
  9631. +{
  9632. + struct dect_cluster_handle *clh;
  9633. +
  9634. + clh = kzalloc(sizeof(*clh), GFP_KERNEL);
  9635. + if (clh == NULL)
  9636. + return ERR_PTR(-ENOMEM);
  9637. + clh->index = clindex;
  9638. + clh->ops = &dect_ccp_ccf_ops;
  9639. + return clh;
  9640. +}
  9641. diff --git a/net/dect/core.c b/net/dect/core.c
  9642. new file mode 100644
  9643. index 0000000..80a7dd8
  9644. --- /dev/null
  9645. +++ b/net/dect/core.c
  9646. @@ -0,0 +1,183 @@
  9647. +/*
  9648. + * Copyright (c) 2009 Patrick McHardy <[email protected]>
  9649. + *
  9650. + * This program is free software; you can redistribute it and/or modify
  9651. + * it under the terms of the GNU General Public License version 2 as
  9652. + * published by the Free Software Foundation.
  9653. + */
  9654. +
  9655. +#ifdef CONFIG_DECT_DEBUG
  9656. +#define DEBUG
  9657. +#endif
  9658. +
  9659. +#include <linux/kernel.h>
  9660. +#include <linux/module.h>
  9661. +#include <linux/init.h>
  9662. +#include <linux/mutex.h>
  9663. +#include <linux/list.h>
  9664. +#include <linux/notifier.h>
  9665. +#include <net/dect/dect.h>
  9666. +#include <net/dect/transceiver.h>
  9667. +
  9668. +static DEFINE_MUTEX(dect_cfg_mutex);
  9669. +
  9670. +void dect_lock(void)
  9671. +{
  9672. + mutex_lock(&dect_cfg_mutex);
  9673. +}
  9674. +EXPORT_SYMBOL_GPL(dect_lock);
  9675. +
  9676. +void dect_unlock(void)
  9677. +{
  9678. + mutex_unlock(&dect_cfg_mutex);
  9679. +}
  9680. +EXPORT_SYMBOL_GPL(dect_unlock);
  9681. +
  9682. +/*
  9683. + * MAC layer timers
  9684. + */
  9685. +
  9686. +#if 1
  9687. +#define timer_debug(name, base, fmt, args...) \
  9688. + pr_debug("%s: %s %u.%.2u.%.2u: " fmt, name, \
  9689. + (base)->base == DECT_TIMER_TX ? "TX" : "RX", \
  9690. + base->mfn, base->framenum, base->slot, ## args)
  9691. +#else
  9692. +#define timer_debug(base, fmt, args...)
  9693. +#endif
  9694. +
  9695. +void __dect_run_timers(const char *name, struct dect_timer_base *base)
  9696. +{
  9697. + struct dect_timer *t;
  9698. +
  9699. + while (!list_empty(&base->timers)) {
  9700. + t = list_first_entry(&base->timers, struct dect_timer, list);
  9701. +
  9702. + if (dect_mfn_after(t->mfn, base->mfn) ||
  9703. + (t->mfn == base->mfn && t->frame > base->framenum) ||
  9704. + (t->mfn == base->mfn && t->frame == base->framenum &&
  9705. + t->slot > base->slot))
  9706. + break;
  9707. +
  9708. + timer_debug(name, base, "timer %p: %u.%u.%u\n",
  9709. + t, t->mfn, t->frame, t->slot);
  9710. + list_del_init(&t->list);
  9711. + t->cb.cb(t->obj, t->data);
  9712. + }
  9713. +}
  9714. +EXPORT_SYMBOL_GPL(__dect_run_timers);
  9715. +
  9716. +/**
  9717. + * dect_timer_add - (re)schedule a timer
  9718. + *
  9719. + * Frame numbers are relative to the current time, slot positions are absolute.
  9720. + * A timer scheduled for (1, 2) will expire in slot 2 in the next frame.
  9721. + *
  9722. + * A frame number of zero will expire at the next occurence of the slot, which
  9723. + * can be within the same frame in case the slot is not already in the past, or
  9724. + * in the next frame in case it is.
  9725. + */
  9726. +void __dect_timer_add(const char *name, struct dect_timer_base *base,
  9727. + struct dect_timer *timer, u32 frame, u8 slot)
  9728. +{
  9729. + struct dect_timer *t;
  9730. + u32 mfn;
  9731. +
  9732. + if (frame == 0 && slot < base->slot)
  9733. + frame++;
  9734. + frame += base->framenum;
  9735. + mfn = dect_mfn_add(base->mfn, frame / DECT_FRAMES_PER_MULTIFRAME);
  9736. + frame %= DECT_FRAMES_PER_MULTIFRAME;
  9737. +
  9738. + timer_debug(name, base, "timer %p: schedule for %u.%u.%u\n",
  9739. + timer, mfn, frame, slot);
  9740. + if (!list_empty(&timer->list))
  9741. + list_del(&timer->list);
  9742. + list_for_each_entry(t, &base->timers, list) {
  9743. + if (dect_mfn_after(t->mfn, mfn) ||
  9744. + (t->mfn == mfn && t->frame > frame) ||
  9745. + (t->mfn == mfn && t->frame == frame && t->slot > slot))
  9746. + break;
  9747. + }
  9748. +
  9749. + timer->mfn = mfn;
  9750. + timer->frame = frame;
  9751. + timer->slot = slot;
  9752. + list_add_tail(&timer->list, &t->list);
  9753. +}
  9754. +EXPORT_SYMBOL_GPL(__dect_timer_add);
  9755. +
  9756. +struct sk_buff *skb_append_frag(struct sk_buff *head, struct sk_buff *skb)
  9757. +{
  9758. + struct sk_buff **pprev;
  9759. +
  9760. + if (head == NULL)
  9761. + return skb;
  9762. +
  9763. + pprev = &skb_shinfo(head)->frag_list;
  9764. + while (*pprev != NULL)
  9765. + pprev = &(*pprev)->next;
  9766. + *pprev = skb;
  9767. +
  9768. + head->data_len += skb->len;
  9769. + head->len += skb->len;
  9770. + head->truesize += skb->truesize;
  9771. + return head;
  9772. +}
  9773. +EXPORT_SYMBOL_GPL(skb_append_frag);
  9774. +
  9775. +unsigned int skb_queue_pull(struct sk_buff_head *list, unsigned int len)
  9776. +{
  9777. + unsigned int pulled = 0;
  9778. + unsigned long flags;
  9779. + struct sk_buff *skb;
  9780. +
  9781. + spin_lock_irqsave(&list->lock, flags);
  9782. + while (len > pulled) {
  9783. + skb = skb_peek(list);
  9784. + if (skb == NULL)
  9785. + break;
  9786. + if (skb->len <= len) {
  9787. + __skb_unlink(skb, list);
  9788. + pulled += skb->len;
  9789. + kfree_skb(skb);
  9790. + } else {
  9791. + __skb_pull(skb, len);
  9792. + pulled += len;
  9793. + }
  9794. + }
  9795. + spin_unlock_irqrestore(&list->lock, flags);
  9796. + return pulled;
  9797. +}
  9798. +EXPORT_SYMBOL_GPL(skb_queue_pull);
  9799. +
  9800. +static int __init dect_module_init(void)
  9801. +{
  9802. + int err;
  9803. +
  9804. + err = dect_netlink_module_init();
  9805. + if (err < 0)
  9806. + goto err1;
  9807. + err = dect_af_module_init();
  9808. + if (err < 0)
  9809. + goto err2;
  9810. + return 0;
  9811. +
  9812. +err2:
  9813. + dect_netlink_module_exit();
  9814. +err1:
  9815. + return err;
  9816. +}
  9817. +
  9818. +static void __exit dect_module_exit(void)
  9819. +{
  9820. + dect_af_module_exit();
  9821. + dect_netlink_module_exit();
  9822. +}
  9823. +
  9824. +module_init(dect_module_init);
  9825. +module_exit(dect_module_exit);
  9826. +
  9827. +MODULE_AUTHOR("Patrick McHardy <[email protected]>");
  9828. +MODULE_DESCRIPTION("DECT protocol stack");
  9829. +MODULE_LICENSE("GPL");
  9830. diff --git a/net/dect/dect_netlink.c b/net/dect/dect_netlink.c
  9831. new file mode 100644
  9832. index 0000000..80527fb
  9833. --- /dev/null
  9834. +++ b/net/dect/dect_netlink.c
  9835. @@ -0,0 +1,152 @@
  9836. +/*
  9837. + * DECT netlink control interface
  9838. + *
  9839. + * Copyright (c) 2009 Patrick McHardy <[email protected]>
  9840. + *
  9841. + * This program is free software; you can redistribute it and/or modify
  9842. + * it under the terms of the GNU General Public License version 2 as
  9843. + * published by the Free Software Foundation.
  9844. + */
  9845. +
  9846. +#include <linux/kernel.h>
  9847. +#include <linux/module.h>
  9848. +#include <linux/netlink.h>
  9849. +#include <linux/skbuff.h>
  9850. +#include <linux/net.h>
  9851. +#include <linux/dect_netlink.h>
  9852. +#include <linux/dect.h>
  9853. +#include <net/netlink.h>
  9854. +#include <net/sock.h>
  9855. +#include <net/dect/dect.h>
  9856. +#include <net/dect/mac_csf.h>
  9857. +
  9858. +struct sock *dect_nlsk __read_mostly;
  9859. +EXPORT_SYMBOL_GPL(dect_nlsk);
  9860. +
  9861. +LIST_HEAD(dect_cluster_list);
  9862. +EXPORT_SYMBOL_GPL(dect_cluster_list);
  9863. +
  9864. +struct dect_cluster *dect_cluster_get_by_index(int index)
  9865. +{
  9866. + struct dect_cluster *cl;
  9867. +
  9868. + list_for_each_entry(cl, &dect_cluster_list, list) {
  9869. + if (cl->index == index)
  9870. + return cl;
  9871. + }
  9872. + return NULL;
  9873. +}
  9874. +EXPORT_SYMBOL_GPL(dect_cluster_get_by_index);
  9875. +
  9876. +static const struct dect_netlink_handler *dect_dispatch[DECT_NR_MSGTYPES];
  9877. +
  9878. +void dect_netlink_register_handlers(const struct dect_netlink_handler *handler,
  9879. + unsigned int base, unsigned int n)
  9880. +{
  9881. + unsigned int i;
  9882. +
  9883. + dect_lock();
  9884. + base -= DECT_MSG_BASE;
  9885. + for (i = 0; i < n; i++)
  9886. + dect_dispatch[base + i] = handler + i;
  9887. + dect_unlock();
  9888. +}
  9889. +EXPORT_SYMBOL_GPL(dect_netlink_register_handlers);
  9890. +
  9891. +void dect_netlink_unregister_handlers(unsigned int base, unsigned int n)
  9892. +{
  9893. + unsigned int i;
  9894. +
  9895. + dect_lock();
  9896. + base -= DECT_MSG_BASE;
  9897. + for (i = 0; i < n; i++)
  9898. + dect_dispatch[base + i] = NULL;
  9899. + dect_unlock();
  9900. +}
  9901. +EXPORT_SYMBOL_GPL(dect_netlink_unregister_handlers);
  9902. +
  9903. +static int dect_netlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
  9904. +{
  9905. + const struct dect_netlink_handler *link;
  9906. + u16 type;
  9907. + int err;
  9908. +
  9909. + type = nlh->nlmsg_type;
  9910. + if (type > DECT_MSG_MAX)
  9911. + return -EINVAL;
  9912. +
  9913. + link = dect_dispatch[type - DECT_MSG_BASE];
  9914. + if (link == NULL) {
  9915. +#ifdef CONFIG_MODULES
  9916. + dect_unlock();
  9917. + switch (type) {
  9918. + case DECT_NEW_TRANSCEIVER ... DECT_GET_CELL:
  9919. + request_module("dect_csf");
  9920. + break;
  9921. + case DECT_NEW_CLUSTER ... DECT_LLME_MSG:
  9922. + request_module("dect_ccf");
  9923. + break;
  9924. + }
  9925. + dect_lock();
  9926. +
  9927. + link = dect_dispatch[type - DECT_MSG_BASE];
  9928. + if (link == NULL)
  9929. +#endif
  9930. + return -EOPNOTSUPP;
  9931. + }
  9932. +
  9933. + /* dump and get requests don't require privileges */
  9934. + if (link->dump == NULL && !capable(CAP_NET_ADMIN))
  9935. + return -EPERM;
  9936. +
  9937. + if (nlh->nlmsg_flags & NLM_F_DUMP) {
  9938. + struct netlink_dump_control c = {
  9939. + .dump = link->dump,
  9940. + .done = link->done,
  9941. + };
  9942. +
  9943. + if (link->dump == NULL)
  9944. + return -EOPNOTSUPP;
  9945. + return netlink_dump_start(dect_nlsk, skb, nlh, &c);
  9946. + } else {
  9947. + struct nlattr *nla[link->maxtype + 1];
  9948. +
  9949. + err = nlmsg_parse(nlh, sizeof(struct dectmsg), nla,
  9950. + link->maxtype, link->policy);
  9951. + if (err < 0)
  9952. + return err;
  9953. + if (link->doit == NULL)
  9954. + return -EOPNOTSUPP;
  9955. + return link->doit(skb, nlh, (const struct nlattr **)nla);
  9956. + }
  9957. +}
  9958. +
  9959. +static void dect_netlink_rcv(struct sk_buff *skb)
  9960. +{
  9961. + dect_lock();
  9962. + netlink_rcv_skb(skb, dect_netlink_rcv_msg);
  9963. + dect_unlock();
  9964. +}
  9965. +
  9966. +static struct netlink_kernel_cfg dect_netlink_cfg = {
  9967. + .groups = DECTNLGRP_MAX,
  9968. + .input = dect_netlink_rcv,
  9969. +};
  9970. +
  9971. +int __init dect_netlink_module_init(void)
  9972. +{
  9973. + struct sock *sk;
  9974. +
  9975. + sk = netlink_kernel_create(&init_net, NETLINK_DECT, &dect_netlink_cfg);
  9976. + if (sk == NULL)
  9977. + return -ENOMEM;
  9978. + dect_nlsk = sk;
  9979. + return 0;
  9980. +}
  9981. +
  9982. +void dect_netlink_module_exit(void)
  9983. +{
  9984. + netlink_kernel_release(dect_nlsk);
  9985. +}
  9986. +
  9987. +MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_DECT);
  9988. diff --git a/net/dect/dlc.c b/net/dect/dlc.c
  9989. new file mode 100644
  9990. index 0000000..c2d287d
  9991. --- /dev/null
  9992. +++ b/net/dect/dlc.c
  9993. @@ -0,0 +1,282 @@
  9994. +/*
  9995. + * DECT DLC Layer
  9996. + *
  9997. + * Copyright (c) 2009 Patrick McHardy <[email protected]>
  9998. + *
  9999. + * This program is free software; you can redistribute it and/or modify
  10000. + * it under the terms of the GNU General Public License version 2 as
  10001. + * published by the Free Software Foundation.
  10002. + */
  10003. +
  10004. +#ifdef CONFIG_DECT_DEBUG
  10005. +#define DEBUG
  10006. +#endif
  10007. +
  10008. +#include <linux/kernel.h>
  10009. +#include <linux/module.h>
  10010. +#include <linux/init.h>
  10011. +#include <linux/list.h>
  10012. +#include <linux/skbuff.h>
  10013. +#include <linux/net.h>
  10014. +#include <linux/dect.h>
  10015. +#include <net/dect/dect.h>
  10016. +
  10017. +#define mc_debug(mc, fmt, args...) \
  10018. + pr_debug("MC (MCEI %u/%s): " fmt, \
  10019. + (mc)->mcei, dect_mc_states[(mc)->state], ## args)
  10020. +
  10021. +static const char * const dect_mc_states[] = {
  10022. + [DECT_MAC_CONN_CLOSED] = "CLOSED",
  10023. + [DECT_MAC_CONN_OPEN_PENDING] = "OPEN_PENDING",
  10024. + [DECT_MAC_CONN_OPEN] = "OPEN",
  10025. +};
  10026. +
  10027. +static struct dect_mac_conn *
  10028. +dect_mac_conn_get_by_mcei(const struct dect_cluster *cl, u32 mcei)
  10029. +{
  10030. + struct dect_mac_conn *mc;
  10031. +
  10032. + list_for_each_entry(mc, &cl->mac_connections, list) {
  10033. + if (mc->mcei == mcei)
  10034. + return mc;
  10035. + }
  10036. + return NULL;
  10037. +}
  10038. +
  10039. +struct dect_mac_conn *
  10040. +dect_mac_conn_get_by_mci(const struct dect_cluster *cl, const struct dect_mci *mci)
  10041. +{
  10042. + struct dect_mac_conn *mc;
  10043. +
  10044. + list_for_each_entry(mc, &cl->mac_connections, list) {
  10045. + if (!dect_ari_cmp(&mc->mci.ari, &mci->ari) &&
  10046. + !dect_pmid_cmp(&mc->mci.pmid, &mci->pmid) &&
  10047. + mc->mci.lcn == mci->lcn)
  10048. + return mc;
  10049. + }
  10050. + return NULL;
  10051. +}
  10052. +EXPORT_SYMBOL_GPL(dect_mac_conn_get_by_mci);
  10053. +
  10054. +void dect_dlc_mac_conn_destroy(struct dect_mac_conn *mc)
  10055. +{
  10056. + mc_debug(mc, "destroy\n");
  10057. + list_del(&mc->list);
  10058. + kfree(mc);
  10059. +}
  10060. +
  10061. +void dect_dlc_mac_conn_bind(struct dect_mac_conn *mc)
  10062. +{
  10063. + mc_debug(mc, "bind use %u\n", mc->use);
  10064. + mc->use++;
  10065. +}
  10066. +EXPORT_SYMBOL_GPL(dect_dlc_mac_conn_bind);
  10067. +
  10068. +void dect_dlc_mac_conn_unbind(struct dect_mac_conn *mc)
  10069. +{
  10070. + mc_debug(mc, "unbind use %u\n", mc->use);
  10071. + if (--mc->use)
  10072. + return;
  10073. +
  10074. + if (mc->state == DECT_MAC_CONN_OPEN ||
  10075. + mc->state == DECT_MAC_CONN_OPEN_PENDING)
  10076. + dect_mac_dis_req(mc->cl, mc->mcei);
  10077. +
  10078. + dect_dlc_mac_conn_destroy(mc);
  10079. +}
  10080. +EXPORT_SYMBOL_GPL(dect_dlc_mac_conn_unbind);
  10081. +
  10082. +struct dect_mac_conn *dect_mac_conn_init(struct dect_cluster *cl,
  10083. + const struct dect_mci *mci,
  10084. + const struct dect_mbc_id *id)
  10085. +{
  10086. + struct dect_mac_conn *mc;
  10087. +
  10088. + mc = kzalloc(sizeof(*mc), GFP_ATOMIC);
  10089. + if (mc == NULL)
  10090. + return NULL;
  10091. +
  10092. + mc->cl = cl;
  10093. + mc->mcei = id != NULL ? id->mcei : dect_mbc_alloc_mcei(cl);
  10094. + memcpy(&mc->mci, mci, sizeof(mc->mci));
  10095. + mc->state = DECT_MAC_CONN_CLOSED;
  10096. + mc_debug(mc, "init\n");
  10097. +
  10098. + list_add_tail(&mc->list, &cl->mac_connections);
  10099. + return mc;
  10100. +}
  10101. +
  10102. +static void dect_mac_conn_state_change(struct dect_mac_conn *mc,
  10103. + enum dect_mac_conn_states state)
  10104. +{
  10105. + mc_debug(mc, "state change: %s (%u) -> %s (%u)\n",
  10106. + dect_mc_states[mc->state], mc->state,
  10107. + dect_mc_states[state], state);
  10108. +
  10109. + mc->state = state;
  10110. + dect_cplane_notify_state_change(mc);
  10111. +}
  10112. +
  10113. +int dect_dlc_mac_conn_establish(struct dect_mac_conn *mc,
  10114. + const struct dect_mac_conn_params *mcp)
  10115. +{
  10116. + struct dect_mbc_id mid = {
  10117. + .mcei = mc->mcei,
  10118. + .ari = mc->mci.ari,
  10119. + .pmid = mc->mci.pmid,
  10120. + .ecn = mc->mci.lcn,
  10121. + };
  10122. + int err;
  10123. +
  10124. + err = dect_mac_con_req(mc->cl, &mid, mcp);
  10125. + if (err < 0)
  10126. + return err;
  10127. + dect_mac_conn_state_change(mc, DECT_MAC_CONN_OPEN_PENDING);
  10128. + return 0;
  10129. +}
  10130. +
  10131. +int dect_mac_con_cfm(struct dect_cluster *cl, u32 mcei,
  10132. + const struct dect_mac_conn_params *mcp)
  10133. +{
  10134. + struct dect_mac_conn *mc;
  10135. +
  10136. + mc = dect_mac_conn_get_by_mcei(cl, mcei);
  10137. + if (WARN_ON(mc == NULL))
  10138. + return -ENOENT;
  10139. + mc->mcp = *mcp;
  10140. +
  10141. + mc_debug(mc, "MAC_CON-cfm\n");
  10142. + dect_mac_conn_state_change(mc, DECT_MAC_CONN_OPEN);
  10143. + return 0;
  10144. +}
  10145. +
  10146. +int dect_mac_con_ind(struct dect_cluster *cl, const struct dect_mbc_id *id,
  10147. + const struct dect_mac_conn_params *mcp)
  10148. +{
  10149. + struct dect_mac_conn *mc;
  10150. + struct dect_mci mci = {
  10151. + .ari = id->ari,
  10152. + .pmid = id->pmid,
  10153. + .lcn = id->ecn & DECT_LCN_MASK,
  10154. + };
  10155. +
  10156. + mc = dect_mac_conn_init(cl, &mci, id);
  10157. + if (mc == NULL)
  10158. + return -ENOMEM;
  10159. + mc->mcp = *mcp;
  10160. +
  10161. + mc_debug(mc, "MAC_CON-ind\n");
  10162. + dect_mac_conn_state_change(mc, DECT_MAC_CONN_OPEN);
  10163. + return 0;
  10164. +}
  10165. +
  10166. +int dect_dlc_mac_conn_enc_key_req(struct dect_mac_conn *mc, u64 ck)
  10167. +{
  10168. + mc->ck = ck;
  10169. + return dect_mac_enc_key_req(mc->cl, mc->mcei, ck);
  10170. +}
  10171. +
  10172. +int dect_dlc_mac_conn_enc_eks_req(struct dect_mac_conn *mc,
  10173. + enum dect_cipher_states status)
  10174. +{
  10175. + return dect_mac_enc_eks_req(mc->cl, mc->mcei, status);
  10176. +}
  10177. +
  10178. +/* Encryption status change confirmation from CCF */
  10179. +void dect_mac_enc_eks_cfm(struct dect_cluster *cl, u32 mcei,
  10180. + enum dect_cipher_states status)
  10181. +
  10182. +{
  10183. + struct dect_mac_conn *mc;
  10184. +
  10185. + mc = dect_mac_conn_get_by_mcei(cl, mcei);
  10186. + if (WARN_ON(mc == NULL))
  10187. + return;
  10188. + //dect_cplane_mac_enc_eks_ind(mc, status);
  10189. +}
  10190. +
  10191. +/* Encryption status change indication from CCF */
  10192. +void dect_mac_enc_eks_ind(struct dect_cluster *cl, u32 mcei,
  10193. + enum dect_cipher_states status)
  10194. +
  10195. +{
  10196. + struct dect_mac_conn *mc;
  10197. +
  10198. + mc = dect_mac_conn_get_by_mcei(cl, mcei);
  10199. + if (WARN_ON(mc == NULL))
  10200. + return;
  10201. + mc_debug(mc, "MAC_ENC_EKS-ind: status: %u\n", status);
  10202. + dect_cplane_mac_enc_eks_ind(mc, status);
  10203. +}
  10204. +
  10205. +/* Disconnection indication from CCF */
  10206. +int dect_mac_dis_ind(struct dect_cluster *cl, u32 mcei,
  10207. + enum dect_release_reasons reason)
  10208. +{
  10209. + struct dect_mac_conn *mc;
  10210. +
  10211. + mc = dect_mac_conn_get_by_mcei(cl, mcei);
  10212. + if (WARN_ON(mc == NULL))
  10213. + return -ENOENT;
  10214. +
  10215. + mc_debug(mc, "MAC_DIS-ind: reason: %x\n", reason);
  10216. + dect_mac_conn_state_change(mc, DECT_MAC_CONN_CLOSED);
  10217. + /* If nothing is using the connection, release immediately */
  10218. + if (mc->use == 0)
  10219. + dect_dlc_mac_conn_destroy(mc);
  10220. + else
  10221. + dect_cplane_mac_dis_ind(mc, reason);
  10222. + return 0;
  10223. +}
  10224. +
  10225. +/* Data indication from CCF */
  10226. +void dect_mac_co_data_ind(struct dect_cluster *cl, u32 mcei,
  10227. + enum dect_data_channels chan,
  10228. + struct sk_buff *skb)
  10229. +{
  10230. + struct dect_mac_conn *mc;
  10231. +
  10232. + mc = dect_mac_conn_get_by_mcei(cl, mcei);
  10233. + if (WARN_ON(mc == NULL))
  10234. + goto err;
  10235. +
  10236. + mc_debug(mc, "MAC_CO_DATA-ind: chan: %u len: %u\n", chan, skb->len);
  10237. + switch (chan) {
  10238. + case DECT_MC_C_S:
  10239. + case DECT_MC_C_F:
  10240. + return dect_cplane_rcv(mc, chan, skb);
  10241. + case DECT_MC_I_N:
  10242. + case DECT_MC_I_P:
  10243. + return dect_uplane_rcv(mc, chan, skb);
  10244. + default:
  10245. + goto err;
  10246. + }
  10247. +err:
  10248. + kfree_skb(skb);
  10249. +}
  10250. +
  10251. +/* Data-ready indication from CCF */
  10252. +struct sk_buff *dect_mac_co_dtr_ind(struct dect_cluster *cl, u32 mcei,
  10253. + enum dect_data_channels chan)
  10254. +{
  10255. + struct dect_mac_conn *mc;
  10256. +
  10257. + mc = dect_mac_conn_get_by_mcei(cl, mcei);
  10258. + if (mc == NULL) {
  10259. + if (net_ratelimit())
  10260. + pr_debug("DLC: DTR no connection\n");
  10261. + return NULL;
  10262. + }
  10263. +
  10264. + mc_debug(mc, "MAC_CO_DTR-ind: chan: %u\n", chan);
  10265. + switch (chan) {
  10266. + case DECT_MC_C_S:
  10267. + case DECT_MC_C_F:
  10268. + return dect_cplane_dtr(mc, chan);
  10269. + case DECT_MC_I_N:
  10270. + case DECT_MC_I_P:
  10271. + return dect_uplane_dtr(mc, chan);
  10272. + default:
  10273. + return NULL;
  10274. + }
  10275. +}
  10276. diff --git a/net/dect/dlc_b_sap.c b/net/dect/dlc_b_sap.c
  10277. new file mode 100644
  10278. index 0000000..28782d4
  10279. --- /dev/null
  10280. +++ b/net/dect/dlc_b_sap.c
  10281. @@ -0,0 +1,278 @@
  10282. +/*
  10283. + * DECT DLC B SAP sockets - DLC C-plane broadcast service access
  10284. + *
  10285. + * Copyright (c) 2009 Patrick McHardy <[email protected]>
  10286. + *
  10287. + * This program is free software; you can redistribute it and/or modify
  10288. + * it under the terms of the GNU General Public License version 2 as
  10289. + * published by the Free Software Foundation.
  10290. + */
  10291. +
  10292. +#include <linux/kernel.h>
  10293. +#include <linux/module.h>
  10294. +#include <linux/init.h>
  10295. +#include <linux/net.h>
  10296. +#include <linux/socket.h>
  10297. +#include <linux/dect.h>
  10298. +#include <net/sock.h>
  10299. +#include <net/dect/dect.h>
  10300. +
  10301. +static DEFINE_SPINLOCK(dect_bsap_lock);
  10302. +static HLIST_HEAD(dect_bsap_sockets);
  10303. +
  10304. +struct dect_bsap {
  10305. + struct sock sk;
  10306. +};
  10307. +
  10308. +static inline struct dect_bsap *dect_bsap(struct sock *sk)
  10309. +{
  10310. + return (struct dect_bsap *)sk;
  10311. +}
  10312. +
  10313. +void dect_bsap_rcv(const struct dect_cluster *cl, struct sk_buff *skb)
  10314. +{
  10315. + struct hlist_node *node;
  10316. + struct sk_buff *skb2;
  10317. + struct sock *sk, *prev = NULL;
  10318. +
  10319. + spin_lock(&dect_bsap_lock);
  10320. + sk_for_each(sk, &dect_bsap_sockets) {
  10321. + if (sk->sk_bound_dev_if &&
  10322. + sk->sk_bound_dev_if != cl->index)
  10323. + continue;
  10324. +
  10325. + skb2 = skb_clone(skb, GFP_ATOMIC);
  10326. + if (skb2 == NULL) {
  10327. + sk->sk_err = -ENOMEM;
  10328. + sk->sk_error_report(sk);
  10329. + break;
  10330. + }
  10331. +
  10332. + if (prev != NULL) {
  10333. + if (dect_sock_queue_rcv_skb(prev, skb2) < 0)
  10334. + kfree_skb(skb2);
  10335. + }
  10336. + prev = sk;
  10337. + }
  10338. +
  10339. + if (prev == NULL || dect_sock_queue_rcv_skb(prev, skb) < 0)
  10340. + kfree_skb(skb);
  10341. +
  10342. + spin_unlock(&dect_bsap_lock);
  10343. +}
  10344. +
  10345. +static void dect_bsap_close(struct sock *sk, long timeout)
  10346. +{
  10347. + sk_common_release(sk);
  10348. +}
  10349. +
  10350. +static int dect_bsap_bind(struct sock *sk, struct sockaddr *uaddr, int len)
  10351. +{
  10352. + const struct sockaddr_dect *addr = (struct sockaddr_dect *)uaddr;
  10353. + int err;
  10354. +
  10355. + if (len < sizeof(*addr) || addr->dect_family != AF_DECT)
  10356. + return -EINVAL;
  10357. +
  10358. + if (addr->dect_index != 0 &&
  10359. + !dect_cluster_get_by_index(addr->dect_index))
  10360. + return -ENODEV;
  10361. +
  10362. + lock_sock(sk);
  10363. + err = -EINVAL;
  10364. + if (!sk_unhashed(sk))
  10365. + goto out;
  10366. +
  10367. + sk->sk_bound_dev_if = addr->dect_index;
  10368. +
  10369. + spin_lock_bh(&dect_bsap_lock);
  10370. + sk_add_node(sk, &dect_bsap_sockets);
  10371. + spin_unlock_bh(&dect_bsap_lock);
  10372. +
  10373. + err = 0;
  10374. +out:
  10375. + release_sock(sk);
  10376. + return err;
  10377. +}
  10378. +
  10379. +static void dect_bsap_unhash(struct sock *sk)
  10380. +{
  10381. + if (sk_hashed(sk)) {
  10382. + spin_lock_bh(&dect_bsap_lock);
  10383. + sk_del_node_init(sk);
  10384. + spin_unlock_bh(&dect_bsap_lock);
  10385. + }
  10386. +}
  10387. +
  10388. +static int dect_bsap_getname(struct sock *sk, struct sockaddr *uaddr, int *len,
  10389. + int peer)
  10390. +{
  10391. + struct sockaddr_dect *addr = (struct sockaddr_dect *)uaddr;
  10392. +
  10393. + if (peer)
  10394. + return -EOPNOTSUPP;
  10395. +
  10396. + addr->dect_family = AF_DECT;
  10397. + addr->dect_index = sk->sk_bound_dev_if;
  10398. + *len = sizeof(*addr);
  10399. + return 0;
  10400. +}
  10401. +
  10402. +static int dect_bsap_recvmsg(struct sock *sk,
  10403. + struct msghdr *msg, size_t len,
  10404. + int noblock, int flags, int *addrlen)
  10405. +{
  10406. + struct sockaddr_dect *addr;
  10407. + struct dect_bsap_auxdata aux;
  10408. + struct sk_buff *skb;
  10409. + size_t copied = 0;
  10410. + int err;
  10411. +
  10412. + if (flags & MSG_OOB)
  10413. + return -EOPNOTSUPP;
  10414. +
  10415. + skb = skb_recv_datagram(sk, flags, noblock, &err);
  10416. + if (skb == NULL)
  10417. + goto out;
  10418. +
  10419. + //msg->msg_flags |= DECT_LB_CB(skb)->expedited ? MSG_OOB : 0;
  10420. +
  10421. + copied = skb->len;
  10422. + if (len < copied) {
  10423. + msg->msg_flags |= MSG_TRUNC;
  10424. + copied = len;
  10425. + }
  10426. +
  10427. + err = skb_copy_datagram_msg(skb, 0, msg, copied);
  10428. + if (err < 0)
  10429. + goto out_free;
  10430. +
  10431. + if (msg->msg_name != NULL) {
  10432. + addr = (struct sockaddr_dect *)msg->msg_name;
  10433. + addr->dect_family = AF_DECT;
  10434. + addr->dect_index = DECT_SK_CB(skb)->index;
  10435. + msg->msg_namelen = sizeof(*addr);
  10436. + }
  10437. +
  10438. + sock_recv_timestamp(msg, sk, skb);
  10439. +
  10440. + aux.long_page = DECT_BMC_CB(skb)->long_page;
  10441. + put_cmsg(msg, SOL_DECT, DECT_BSAP_AUXDATA, sizeof(aux), &aux);
  10442. +
  10443. + if (flags & MSG_TRUNC)
  10444. + copied = skb->len;
  10445. +out_free:
  10446. + skb_free_datagram(sk, skb);
  10447. +out:
  10448. + return err ? : copied;
  10449. +}
  10450. +
  10451. +static int dect_bsap_sendmsg(struct sock *sk,
  10452. + struct msghdr *msg, size_t len)
  10453. +{
  10454. + const struct sockaddr_dect *addr = msg->msg_name;
  10455. + bool expedited = msg->msg_flags & MSG_OOB;
  10456. + struct dect_cluster *cl;
  10457. + struct sk_buff *skb;
  10458. + struct cmsghdr *cmsg;
  10459. + struct dect_bsap_auxdata *aux;
  10460. + bool long_page = false;
  10461. + int index;
  10462. + int err;
  10463. +
  10464. + if (msg->msg_namelen) {
  10465. + if (addr->dect_family != AF_DECT)
  10466. + return -EINVAL;
  10467. + index = addr->dect_index;
  10468. + } else
  10469. + index = sk->sk_bound_dev_if;
  10470. +
  10471. + /* Transmission is always in direction FP -> PP */
  10472. + cl = dect_cluster_get_by_index(index);
  10473. + if (cl == NULL)
  10474. + return -ENODEV;
  10475. + if (cl->mode != DECT_MODE_FP)
  10476. + return -EOPNOTSUPP;
  10477. +
  10478. + for (cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL; cmsg = CMSG_NXTHDR(msg, cmsg)) {
  10479. + if (!CMSG_OK(msg, cmsg))
  10480. + return -EINVAL;
  10481. + if (cmsg->cmsg_level != SOL_DECT)
  10482. + continue;
  10483. +
  10484. + switch (cmsg->cmsg_type) {
  10485. + case DECT_BSAP_AUXDATA:
  10486. + if (cmsg->cmsg_len != CMSG_LEN(sizeof(*aux)))
  10487. + return -EINVAL;
  10488. + aux = (struct dect_bsap_auxdata *)CMSG_DATA(cmsg);
  10489. + long_page = aux->long_page;
  10490. + break;
  10491. + default:
  10492. + return -EINVAL;
  10493. + }
  10494. + }
  10495. +
  10496. + /* Valid frame sizes are 3 bytes (short frame), 5 bytes (long frame)
  10497. + * or multiples of 5 bytes up to 30 bytes (extended frame). Extended
  10498. + * frames can not use expedited operation. */
  10499. + if (len == DECT_LB_SHORT_FRAME_SIZE) {
  10500. + if (long_page)
  10501. + return -EINVAL;
  10502. + } else if (len % DECT_LB_LONG_FRAME_SIZE == 0) {
  10503. + if (len == 0 || len > DECT_LB_EXTENDED_FRAME_SIZE_MAX)
  10504. + return -EMSGSIZE;
  10505. + if (len > DECT_LB_LONG_FRAME_SIZE && !long_page)
  10506. + return -EINVAL;
  10507. + if (expedited)
  10508. + return -EOPNOTSUPP;
  10509. + } else
  10510. + return -EINVAL;
  10511. +
  10512. + skb = sock_alloc_send_skb(sk, len, msg->msg_flags & MSG_DONTWAIT, &err);
  10513. + if (skb == NULL)
  10514. + goto err1;
  10515. + err = memcpy_from_msg(skb_put(skb, len), msg, len);
  10516. + if (err < 0)
  10517. + goto err2;
  10518. + DECT_BMC_CB(skb)->long_page = long_page;
  10519. + DECT_BMC_CB(skb)->fast_page = expedited;
  10520. + dect_bmc_mac_page_req(cl, skb);
  10521. + return len;
  10522. +
  10523. +err2:
  10524. + kfree_skb(skb);
  10525. +err1:
  10526. + return err;
  10527. +}
  10528. +
  10529. +static struct dect_proto dect_bsap_proto __read_mostly = {
  10530. + .type = SOCK_DGRAM,
  10531. + .protocol = DECT_B_SAP,
  10532. + .capability = CAP_NET_RAW,
  10533. + .ops = &dect_dgram_ops,
  10534. + .proto.name = "DECT_B_SAP",
  10535. + .proto.owner = THIS_MODULE,
  10536. + .proto.obj_size = sizeof(struct dect_bsap),
  10537. + .proto.close = dect_bsap_close,
  10538. + .proto.bind = dect_bsap_bind,
  10539. + .proto.unhash = dect_bsap_unhash,
  10540. + .proto.recvmsg = dect_bsap_recvmsg,
  10541. + .proto.sendmsg = dect_bsap_sendmsg,
  10542. + .getname = dect_bsap_getname,
  10543. +};
  10544. +
  10545. +int __init dect_bsap_module_init(void)
  10546. +{
  10547. + return dect_proto_register(&dect_bsap_proto);
  10548. +}
  10549. +
  10550. +void dect_bsap_module_exit(void)
  10551. +{
  10552. + dect_proto_unregister(&dect_bsap_proto);
  10553. +}
  10554. +
  10555. +MODULE_AUTHOR("Patrick McHardy <[email protected]>");
  10556. +MODULE_DESCRIPTION("DECT DLC B SAP sockets");
  10557. +MODULE_LICENSE("GPL");
  10558. +
  10559. +MODULE_ALIAS_NET_PF_PROTO(PF_DECT, DECT_B_SAP);
  10560. diff --git a/net/dect/dlc_cplane.c b/net/dect/dlc_cplane.c
  10561. new file mode 100644
  10562. index 0000000..9365b9d
  10563. --- /dev/null
  10564. +++ b/net/dect/dlc_cplane.c
  10565. @@ -0,0 +1,981 @@
  10566. +/*
  10567. + * DECT DLC C-plane
  10568. + *
  10569. + * Copyright (c) 2009 Patrick McHardy <[email protected]>
  10570. + *
  10571. + * This program is free software; you can redistribute it and/or modify
  10572. + * it under the terms of the GNU General Public License version 2 as
  10573. + * published by the Free Software Foundation.
  10574. + */
  10575. +
  10576. +#ifdef CONFIG_DECT_DEBUG
  10577. +#define DEBUG
  10578. +#endif
  10579. +
  10580. +#include <linux/kernel.h>
  10581. +#include <linux/module.h>
  10582. +#include <linux/init.h>
  10583. +#include <linux/list.h>
  10584. +#include <linux/skbuff.h>
  10585. +#include <linux/net.h>
  10586. +#include <linux/dect.h>
  10587. +#include <net/dect/dect.h>
  10588. +
  10589. +void dect_mac_page_ind(struct dect_cluster *cl, struct sk_buff *skb)
  10590. +{
  10591. + dect_bsap_rcv(cl, skb);
  10592. +}
  10593. +
  10594. +static void dect_fa_parse_len(struct dect_fa_len *len, const struct sk_buff *skb)
  10595. +{
  10596. + u8 l;
  10597. +
  10598. + l = skb->data[DECT_FA_LI_OFF];
  10599. + len->len = (l & DECT_FA_LI_LENGTH_MASK) >> DECT_FA_LI_LENGTH_SHIFT;
  10600. + len->more = (l & DECT_FA_LI_M_FLAG);
  10601. +}
  10602. +
  10603. +/*
  10604. + * LAPC entity
  10605. + */
  10606. +
  10607. +#define lapc_debug(lapc, fmt, args...) \
  10608. + pr_debug("LAPC (MCEI: %u LLN: %u): " fmt, \
  10609. + (lapc)->lc->mc->mcei, (lapc)->dli.lln, ## args)
  10610. +
  10611. +static inline u8 lapc_seq_add(const struct dect_lapc *lapc, u8 s1, u8 s2)
  10612. +{
  10613. + return (s1 + s2) & (lapc->mod - 1);
  10614. +}
  10615. +
  10616. +static inline bool dect_fa_seq_before(const struct dect_lapc *lapc, u8 s1, u8 s2)
  10617. +{
  10618. + if (lapc->window == 1)
  10619. + return s1 != s2;
  10620. + else
  10621. + return (s8)((s2 << 5) - (s1 << 5)) > 0;
  10622. +}
  10623. +
  10624. +static inline bool dect_fa_seq_after(const struct dect_lapc *lapc, u8 s1, u8 s2)
  10625. +{
  10626. + return dect_fa_seq_before(lapc, s2, s1);
  10627. +}
  10628. +
  10629. +static void dect_lapc_transmit_skb(struct dect_lapc *lapc)
  10630. +{
  10631. + struct sk_buff *skb = skb_peek(&lapc->retransmit_queue);
  10632. + struct dect_fa_hdr *fh;
  10633. +
  10634. + skb = skb_clone(skb, GFP_ATOMIC);
  10635. + if (skb == NULL)
  10636. + return;
  10637. +
  10638. + fh = (struct dect_fa_hdr *)skb->data;
  10639. + lapc_debug(lapc, "queue I-frame: v_a: %u v_r: %u v_s: %u "
  10640. + "len: %u addr: %02x ctrl: %02x\n", lapc->v_a, lapc->v_r,
  10641. + lapc->v_s, skb->len, fh->addr, fh->ctrl);
  10642. + skb_queue_tail(&lapc->lc->txq, skb);
  10643. +}
  10644. +
  10645. +static void dect_lapc_error_report(struct dect_lapc *lapc, int err)
  10646. +{
  10647. + struct sock *sk = lapc->sk;
  10648. +
  10649. + lapc_debug(lapc, "socket error: %d\n", err);
  10650. + sk->sk_err = err;
  10651. + sk->sk_error_report(sk);
  10652. +}
  10653. +
  10654. +static void dect_lapc_state_change(struct dect_lapc *lapc, int state)
  10655. +{
  10656. + struct sock *sk = lapc->sk;
  10657. +
  10658. + lapc_debug(lapc, "socket state change: %d\n", state);
  10659. + sk->sk_state = state;
  10660. + sk->sk_state_change(sk);
  10661. +}
  10662. +
  10663. +/**
  10664. + * dect_lapc_timeout - retransmission timer
  10665. + *
  10666. + * Handle missing acknowledgements:
  10667. + *
  10668. + * - If not already in timer recovery condition, enter it
  10669. + * - otherwise add one to retransmission count
  10670. + *
  10671. + * If the retransmission count is below the maximum, restart the timer and
  10672. + * send an "appropriate" S-frame acknowledgement or retransmit the last
  10673. + * I-frame, in both cases with the poll bit set.
  10674. + */
  10675. +static void dect_lapc_timeout(unsigned long data)
  10676. +{
  10677. + struct dect_lapc *lapc = (struct dect_lapc *)data;
  10678. +
  10679. + lapc_debug(lapc, "retransmission timer: cnt: %u\n", lapc->retransmit_cnt);
  10680. + if (lapc->retransmit_cnt++ < DECT_LAPC_RETRANSMIT_MAX) {
  10681. + dect_lapc_transmit_skb(lapc);
  10682. + mod_timer(&lapc->timer, jiffies + DECT_LAPC_CLASS_A_ESTABLISH_TIMEOUT);
  10683. + } else
  10684. + dect_lapc_error_report(lapc, ETIMEDOUT);
  10685. +}
  10686. +
  10687. +static bool dect_lapc_done(const struct dect_lapc *lapc)
  10688. +{
  10689. + return skb_queue_empty(&lapc->sk->sk_write_queue) &&
  10690. + skb_queue_empty(&lapc->retransmit_queue);
  10691. +}
  10692. +
  10693. +void dect_lapc_destroy(struct dect_lapc *lapc)
  10694. +{
  10695. + lapc_debug(lapc, "destroy\n");
  10696. +
  10697. + del_timer_sync(&lapc->timer);
  10698. + skb_queue_purge(&lapc->retransmit_queue);
  10699. + dect_lc_unbind(lapc->lc, lapc);
  10700. + sock_put(lapc->sk);
  10701. + kfree(lapc);
  10702. +}
  10703. +
  10704. +static void dect_lapc_reset(struct dect_lapc *lapc)
  10705. +{
  10706. + lapc->nlf = true;
  10707. + lapc->v_s = 0;
  10708. + lapc->v_a = 0;
  10709. + lapc->v_r = 0;
  10710. +}
  10711. +
  10712. +/**
  10713. + * dect_lapc_init - initialize a new LAPC entity
  10714. + */
  10715. +struct dect_lapc *dect_lapc_init(struct sock *sk, const struct dect_dli *dli,
  10716. + enum dect_sapis sapi, struct dect_lc *lc,
  10717. + gfp_t gfp)
  10718. +{
  10719. + struct dect_lapc *lapc;
  10720. +
  10721. + lapc = kzalloc(sizeof(*lapc), gfp);
  10722. + if (lapc == NULL)
  10723. + return NULL;
  10724. +
  10725. + lapc->sk = sk;
  10726. + sock_hold(sk);
  10727. +
  10728. + memcpy(&lapc->dli, dli, sizeof(lapc->dli));
  10729. + lapc->sapi = sapi;
  10730. + lapc->state = DECT_LAPC_ULI;
  10731. + skb_queue_head_init(&lapc->retransmit_queue);
  10732. +
  10733. + lapc->lc = lc;
  10734. + setup_timer(&lapc->timer, dect_lapc_timeout, (unsigned long)lapc);
  10735. + lapc->cmd = (lc->mc->cl->mode == DECT_MODE_FP) ? true : false;
  10736. +
  10737. + switch (lapc->dli.lln) {
  10738. + case DECT_LLN_CLASS_U:
  10739. + break;
  10740. + case DECT_LLN_CLASS_A:
  10741. + lapc->window = DECT_LAPC_CLASS_A_WINDOW;
  10742. + lapc->mod = DECT_LAPC_CLASS_A_MOD;
  10743. + break;
  10744. + default:
  10745. + lapc->window = DECT_LAPC_CLASS_B_INITIAL_WINDOW;
  10746. + lapc->mod = DECT_LAPC_CLASS_B_MOD;
  10747. + break;
  10748. + }
  10749. +
  10750. + dect_lapc_reset(lapc);
  10751. +
  10752. + lapc_debug(lapc, "init\n");
  10753. + return lapc;
  10754. +}
  10755. +
  10756. +#define DECT_FA_FRAME_RESERVE 16
  10757. +#define DECT_FA_FRAME_SPACE 16
  10758. +
  10759. +static struct sk_buff *dect_lapc_alloc_skb(struct dect_lapc *lapc)
  10760. +{
  10761. + struct sk_buff *skb;
  10762. +
  10763. + skb = alloc_skb(DECT_FA_FRAME_SPACE + DECT_FA_FRAME_RESERVE, GFP_ATOMIC);
  10764. + if (skb == NULL)
  10765. + return NULL;
  10766. + skb_reset_mac_header(skb);
  10767. + skb_reserve(skb, DECT_FA_FRAME_RESERVE);
  10768. + skb_reserve(skb, DECT_FA_HDR_SIZE);
  10769. + skb_reset_network_header(skb);
  10770. + return skb;
  10771. +}
  10772. +
  10773. +static struct dect_fa_hdr *dect_prepare_fa_frame(const struct dect_lapc *lapc,
  10774. + bool command,
  10775. + struct sk_buff *skb)
  10776. +{
  10777. + struct dect_fa_hdr *fh;
  10778. + u8 ilen = skb->len;
  10779. +
  10780. + fh = (struct dect_fa_hdr *)skb_push(skb, DECT_FA_HDR_SIZE);
  10781. + fh->addr = lapc->dli.lln << DECT_FA_ADDR_LLN_SHIFT;
  10782. + fh->addr |= lapc->sapi << DECT_FA_ADDR_SAPI_SHIFT;
  10783. + fh->addr |= DECT_FA_ADDR_RES_BIT;
  10784. + fh->addr |= (command ? lapc->cmd : !lapc->cmd) ? DECT_FA_ADDR_CR_FLAG : 0;
  10785. + fh->addr |= lapc->nlf ? DECT_FA_ADDR_NLF_FLAG : 0;
  10786. + fh->ctrl = 0;
  10787. + fh->li = ilen << DECT_FA_LI_LENGTH_SHIFT;
  10788. + fh->li |= DECT_FA_LI_EXT_FLAG;
  10789. + return fh;
  10790. +}
  10791. +
  10792. +static bool dect_lapc_send_iframe(struct dect_lapc *lapc, bool pf)
  10793. +{
  10794. + struct dect_fa_hdr *fh;
  10795. + struct sk_buff *skb;
  10796. +
  10797. + /* Window size full? */
  10798. + lapc_debug(lapc, "send I-frame: v_a: %u window: %u v_s: %u\n",
  10799. + lapc->v_a, lapc->window, lapc->v_s);
  10800. + if (lapc_seq_add(lapc, lapc->v_a, lapc->window) == lapc->v_s)
  10801. + return false;
  10802. +
  10803. + /* Prepare a new I-frame */
  10804. + skb = skb_dequeue(&lapc->sk->sk_write_queue);
  10805. + if (skb == NULL)
  10806. + return false;
  10807. + fh = dect_prepare_fa_frame(lapc, true, skb);
  10808. + fh->ctrl |= DECT_FA_CTRL_I_FMT_ID;
  10809. + fh->ctrl |= lapc->v_r << DECT_FA_CTRL_I_NR_SHIFT;
  10810. + fh->ctrl |= lapc->v_s << DECT_FA_CTRL_I_NS_SHIFT;
  10811. + fh->ctrl |= pf ? DECT_FA_CTRL_I_P_FLAG : 0;
  10812. +
  10813. + /* Append to retransmission queue and (re)start retransmission timer */
  10814. + skb_queue_tail(&lapc->retransmit_queue, skb);
  10815. + if (!timer_pending(&lapc->timer))
  10816. + mod_timer(&lapc->timer, jiffies + DECT_LAPC_RETRANSMISSION_TIMEOUT);
  10817. +
  10818. + lapc->v_s = lapc_seq_add(lapc, lapc->v_s, 1);
  10819. +
  10820. + dect_lapc_transmit_skb(lapc);
  10821. + return true;
  10822. +}
  10823. +
  10824. +/*
  10825. + * Send a S-frame with the specified command. The command/response bit setting
  10826. + * depends on the role of the LAPC, a PP uses 0 for commands and 1 for responses,
  10827. + * a FT 1 for commands and 0 for responses.
  10828. + */
  10829. +static bool dect_lapc_send_sframe(struct dect_lapc *lapc, u8 cr,
  10830. + bool command, bool pf)
  10831. +{
  10832. + struct dect_fa_hdr *fh;
  10833. + struct sk_buff *skb;
  10834. +
  10835. + skb = dect_lapc_alloc_skb(lapc);
  10836. + if (skb == NULL)
  10837. + return false;
  10838. +
  10839. + fh = dect_prepare_fa_frame(lapc, command, skb);
  10840. + fh->ctrl |= DECT_FA_CTRL_S_FMT_ID;
  10841. + fh->ctrl |= lapc->v_r << DECT_FA_CTRL_S_NR_SHIFT;
  10842. + fh->ctrl |= cr;
  10843. + fh->ctrl |= pf ? DECT_FA_CTRL_S_PF_FLAG : 0;
  10844. +
  10845. + lapc_debug(lapc, "queue S-frame: v_r: %u len: %u addr: %02x ctrl: %02x\n",
  10846. + lapc->v_r, skb->len, fh->addr, fh->ctrl);
  10847. + skb_queue_tail(&lapc->lc->txq, skb);
  10848. +
  10849. + lapc->nlf = false;
  10850. + return true;
  10851. +}
  10852. +
  10853. +/*
  10854. + * Send an acknowledgement frame. Class B entities use RNR responses to indicate
  10855. + * their status while busy. Otherwise an I-frame is used when data is available
  10856. + * and a RR response frame otherwise.
  10857. + */
  10858. +static void dect_lapc_send_ack(struct dect_lapc *lapc, bool pf)
  10859. +{
  10860. + lapc_debug(lapc, "send ACK: I-frame present: %u\n",
  10861. + skb_peek(&lapc->sk->sk_write_queue) ? 1 : 0);
  10862. + if (lapc->dli.lln != DECT_LLN_CLASS_A && lapc->busy)
  10863. + dect_lapc_send_sframe(lapc, DECT_FA_CTRL_S_CR_RNR, false, false);
  10864. + else if (!lapc->peer_busy && skb_peek(&lapc->sk->sk_write_queue))
  10865. + dect_lapc_send_iframe(lapc, pf);
  10866. + else
  10867. + dect_lapc_send_sframe(lapc, DECT_FA_CTRL_S_CR_RR, false, pf);
  10868. +}
  10869. +
  10870. +static void dect_lapc_queue_data(struct dect_lapc *lapc, struct sk_buff *skb)
  10871. +{
  10872. + struct dect_fa_hdr *fh = (struct dect_fa_hdr *)skb->data;
  10873. +
  10874. + skb_pull(skb, DECT_FA_HDR_SIZE);
  10875. + if (skb->len == 0) {
  10876. + kfree_skb(skb);
  10877. + return;
  10878. + }
  10879. + lapc_debug(lapc, "reassemble message: segment len: %u more: %u\n",
  10880. + skb->len, (fh->li & DECT_FA_LI_M_FLAG) ? 1 : 0);
  10881. +
  10882. + lapc->rcv_head = skb_append_frag(lapc->rcv_head, skb);
  10883. + if (!(fh->li & DECT_FA_LI_M_FLAG)) {
  10884. + skb = lapc->rcv_head;
  10885. + lapc->rcv_head = NULL;
  10886. + lapc_debug(lapc, "reassembled message: len: %u\n", skb->len);
  10887. + sock_queue_rcv_skb(lapc->sk, skb);
  10888. + }
  10889. +}
  10890. +
  10891. +static bool dect_lapc_update_ack(struct dect_lapc *lapc, u8 seq)
  10892. +{
  10893. + u8 v_a = lapc->v_a;
  10894. +
  10895. + lapc_debug(lapc, "update ACK: v_a: %u v_s: %u seq: %u\n",
  10896. + lapc->v_a, lapc->v_s, seq);
  10897. +#if 0
  10898. + lapc_debug(lapc, "seq %u after v_a %u: %u\n", seq, lapc->v_a,
  10899. + dect_fa_seq_after(lapc, seq, lapc->v_a));
  10900. + lapc_debug(lapc, "v_s %u !after seq %u: %u\n", lapc->v_s, seq,
  10901. + !dect_fa_seq_after(lapc, lapc->v_s, seq));
  10902. +#endif
  10903. +
  10904. + /* If all outstanding I-frames have been acknowledged, stop
  10905. + * retransmission timer, otherwise reset it.
  10906. + */
  10907. + if (dect_fa_seq_after(lapc, seq, lapc->v_a) &&
  10908. + !dect_fa_seq_after(lapc, lapc->v_s, seq)) {
  10909. + lapc->v_a = seq;
  10910. + if (lapc->v_a == lapc->v_s) {
  10911. + del_timer_sync(&lapc->timer);
  10912. + lapc->retransmit_cnt = 0;
  10913. + } else
  10914. + mod_timer(&lapc->timer, jiffies + DECT_LAPC_RETRANSMISSION_TIMEOUT);
  10915. + } else if (seq != lapc->v_a)
  10916. + return false;
  10917. +
  10918. + /* Purge acknowledged frames from transmit queue */
  10919. + while (v_a != lapc->v_a) {
  10920. + lapc_debug(lapc, "purge retransmit queue: seq: %u\n", v_a);
  10921. + kfree_skb(skb_dequeue(&lapc->retransmit_queue));
  10922. + v_a = lapc_seq_add(lapc, v_a, 1);
  10923. + }
  10924. +
  10925. + if (lapc->sk->sk_state == DECT_SK_RELEASE_PENDING &&
  10926. + dect_lapc_done(lapc)) {
  10927. + dect_lapc_state_change(lapc, DECT_SK_RELEASED);
  10928. + dect_lapc_destroy(lapc);
  10929. + return false;
  10930. + }
  10931. +
  10932. + return true;
  10933. +}
  10934. +
  10935. +/*
  10936. + * Receive a Class A or Class B I-frame. Frames with valid sequence numbers
  10937. + * are acknowledged and queued for segment reassembly. Invalid sequence
  10938. + * numbers cause an ACK with the expected sequence number to be sent.
  10939. + *
  10940. + * Class B entities need to indicate their receiver busy status when busy or
  10941. + * when explicitly polled.
  10942. + */
  10943. +static void dect_lapc_rcv_iframe(struct dect_lapc *lapc, struct sk_buff *skb)
  10944. +{
  10945. + struct dect_fa_hdr *fh = (struct dect_fa_hdr *)skb->data;
  10946. + bool poll = false;
  10947. + u8 n_s, n_r, res;
  10948. +
  10949. + if (lapc->dli.lln == DECT_LLN_CLASS_U) {
  10950. + kfree_skb(skb);
  10951. + return;
  10952. + }
  10953. +
  10954. + if (fh->addr & DECT_FA_ADDR_NLF_FLAG)
  10955. + dect_lapc_reset(lapc);
  10956. +
  10957. + n_r = (fh->ctrl & DECT_FA_CTRL_I_NR_MASK) >> DECT_FA_CTRL_I_NR_SHIFT;
  10958. + n_s = (fh->ctrl & DECT_FA_CTRL_I_NS_MASK) >> DECT_FA_CTRL_I_NS_SHIFT;
  10959. + if (lapc->dli.lln != DECT_LLN_CLASS_A)
  10960. + poll = fh->ctrl & DECT_FA_CTRL_I_P_FLAG;
  10961. +
  10962. + lapc_debug(lapc, "receive I-frame: n_r: %u n_s: %u poll: %u\n",
  10963. + n_r, n_s, poll);
  10964. + dect_lapc_update_ack(lapc, n_r);
  10965. +
  10966. + /* While in receiver busy condition, all I-frames are dropped after
  10967. + * updating the acknowledgement number. In Class B mode receiver status
  10968. + * queries are still answered.
  10969. + */
  10970. + if (lapc->busy) {
  10971. + kfree_skb(skb);
  10972. + if (poll)
  10973. + goto poll;
  10974. + return;
  10975. + }
  10976. +
  10977. + /* When the frame contains an invalid sequence number, send an
  10978. + * immediate ACK. */
  10979. + if (n_s != lapc->v_r) {
  10980. + lapc_debug(lapc, "invalid sequence number %u %u\n", n_s, lapc->v_r);
  10981. + kfree_skb(skb);
  10982. + goto ack;
  10983. + }
  10984. +
  10985. + lapc->v_r = lapc_seq_add(lapc, lapc->v_r, 1);
  10986. + dect_lapc_queue_data(lapc, skb);
  10987. + if (poll)
  10988. + goto poll;
  10989. +ack:
  10990. + return dect_lapc_send_ack(lapc, poll);
  10991. +
  10992. +poll:
  10993. + res = lapc->busy ? DECT_FA_CTRL_S_CR_RNR : DECT_FA_CTRL_S_CR_RR;
  10994. + dect_lapc_send_sframe(lapc, res, false, true);
  10995. +}
  10996. +
  10997. +static void dect_lapc_rcv_sframe(struct dect_lapc *lapc, struct sk_buff *skb)
  10998. +{
  10999. + struct dect_fa_hdr *fh = (struct dect_fa_hdr *)skb->data;
  11000. + bool pf;
  11001. + u8 n_r;
  11002. +
  11003. + n_r = (fh->ctrl & DECT_FA_CTRL_S_NR_MASK) >> DECT_FA_CTRL_S_NR_SHIFT;
  11004. + pf = (fh->ctrl & DECT_FA_CTRL_S_PF_FLAG);
  11005. + lapc_debug(lapc, "receive S-frame: n_r: %u pf: %u\n", n_r, pf);
  11006. +
  11007. + switch (fh->ctrl & DECT_FA_CTRL_S_CR_MASK) {
  11008. + case DECT_FA_CTRL_S_CR_RR:
  11009. + if (!dect_lapc_update_ack(lapc, n_r))
  11010. + goto err;
  11011. +
  11012. + if (lapc->lc->elapc == lapc) {
  11013. + /* Connection establishment completed */
  11014. + lapc_debug(lapc, "established\n");
  11015. + lapc->lc->elapc = NULL;
  11016. + del_timer_sync(&lapc->timer);
  11017. + dect_lapc_state_change(lapc, DECT_SK_ESTABLISHED);
  11018. + }
  11019. +
  11020. + dect_lapc_send_iframe(lapc, pf);
  11021. + break;
  11022. + case DECT_FA_CTRL_S_CR_RNR:
  11023. + /*
  11024. + * Note peer receiver busy condition. If it was a RNR command
  11025. + * with the P bit set to 1, send a RR response with the F bit
  11026. + * set to 1. If it was a RNR response with the F bit set to 1,
  11027. + * clear timer recovery condition and update V(S).
  11028. + */
  11029. + lapc->peer_busy = true;
  11030. +
  11031. + if (fh->addr & DECT_FA_ADDR_CR_FLAG && pf)
  11032. + dect_lapc_send_sframe(lapc, DECT_FA_CTRL_S_CR_RR, true, true);
  11033. + else if (!(fh->addr & DECT_FA_ADDR_CR_FLAG) && pf) {
  11034. + del_timer_sync(&lapc->timer);
  11035. + lapc->v_s = n_r;
  11036. + }
  11037. +
  11038. + dect_lapc_update_ack(lapc, n_r);
  11039. + break;
  11040. + case DECT_FA_CTRL_S_CR_REJ:
  11041. + lapc->peer_busy = false;
  11042. + lapc->v_s = n_r;
  11043. + lapc->v_a = n_r;
  11044. + del_timer_sync(&lapc->timer);
  11045. + break;
  11046. + default:
  11047. + goto err;
  11048. + }
  11049. +
  11050. +err:
  11051. + kfree_skb(skb);
  11052. +}
  11053. +
  11054. +static void dect_lapc_rcv_uframe(struct dect_lapc *lapc, struct sk_buff *skb)
  11055. +{
  11056. + struct dect_fa_hdr *fh = (struct dect_fa_hdr *)skb->data;
  11057. + u8 pf, cr;
  11058. +
  11059. + pf = (fh->ctrl & DECT_FA_CTRL_U_PF_FLAG);
  11060. + cr = (fh->ctrl & DECT_FA_CTRL_U_U1_MASK) |
  11061. + (fh->ctrl & DECT_FA_CTRL_U_CR_MASK);
  11062. +
  11063. + /* unnumbered information is only valid in class U mode */
  11064. + if (cr == DECT_FA_CTRL_U_CR_UI) {
  11065. + if (lapc->dli.lln != DECT_LLN_CLASS_U)
  11066. + goto err;
  11067. + lapc_debug(lapc, "queue UI message: len: %u\n", skb->len);
  11068. + sock_queue_rcv_skb(lapc->sk, skb);
  11069. + return;
  11070. + }
  11071. +
  11072. + /* the remaining commands/responses are only valid in class B mode */
  11073. + if (lapc->dli.lln == DECT_LLN_CLASS_A)
  11074. + goto err;
  11075. +
  11076. + switch (cr) {
  11077. + case DECT_FA_CTRL_U_CR_SABM:
  11078. + break;
  11079. + case DECT_FA_CTRL_U_CR_DM:
  11080. + break;
  11081. + case DECT_FA_CTRL_U_CR_DISC:
  11082. + break;
  11083. + case DECT_FA_CTRL_U_CR_UA:
  11084. + break;
  11085. + }
  11086. +
  11087. +err:
  11088. + kfree_skb(skb);
  11089. +}
  11090. +
  11091. +static void dect_lapc_rcv(struct dect_lapc *lapc, struct sk_buff *skb)
  11092. +{
  11093. + struct dect_fa_hdr *fh = (struct dect_fa_hdr *)skb->data;
  11094. +
  11095. + if ((fh->ctrl & DECT_FA_CTRL_I_FMT_MASK) == DECT_FA_CTRL_I_FMT_ID)
  11096. + return dect_lapc_rcv_iframe(lapc, skb);
  11097. + else if ((fh->ctrl & DECT_FA_CTRL_S_FMT_MASK) == DECT_FA_CTRL_S_FMT_ID)
  11098. + return dect_lapc_rcv_sframe(lapc, skb);
  11099. + else if ((fh->ctrl & DECT_FA_CTRL_U_FMT_MASK) == DECT_FA_CTRL_U_FMT_ID)
  11100. + return dect_lapc_rcv_uframe(lapc, skb);
  11101. + else
  11102. + kfree_skb(skb);
  11103. +}
  11104. +
  11105. +int dect_lapc_transmit(struct dect_lapc *lapc)
  11106. +{
  11107. + dect_lapc_send_iframe(lapc, 0);
  11108. + return 0;
  11109. +}
  11110. +
  11111. +int dect_lapc_establish(struct dect_lapc *lapc)
  11112. +{
  11113. + struct sk_buff *skb;
  11114. +
  11115. + lapc_debug(lapc, "establish\n");
  11116. +
  11117. + /* Prepend zero-sized message to transmit queue to trigger connection
  11118. + * establishment.
  11119. + */
  11120. + skb = dect_lapc_alloc_skb(lapc);
  11121. + if (skb == NULL)
  11122. + return -ENOMEM;
  11123. + skb_queue_head(&lapc->sk->sk_write_queue, skb);
  11124. +
  11125. + lapc->lc->elapc = lapc;
  11126. + dect_lapc_send_iframe(lapc, lapc->dli.lln != DECT_LLN_CLASS_A);
  11127. + lapc->nlf = false;
  11128. +
  11129. + mod_timer(&lapc->timer, jiffies + DECT_LAPC_CLASS_A_ESTABLISH_TIMEOUT);
  11130. + return 0;
  11131. +}
  11132. +
  11133. +/*
  11134. + * Initiate link release.
  11135. + */
  11136. +void dect_lapc_release(struct dect_lapc *lapc, bool normal)
  11137. +{
  11138. + lapc_debug(lapc, "release: normal: %u\n", normal);
  11139. + if (dect_lapc_done(lapc) || !normal) {
  11140. + lapc->sk->sk_state = DECT_SK_RELEASED;
  11141. + dect_lapc_destroy(lapc);
  11142. + } else
  11143. + dect_lapc_state_change(lapc, DECT_SK_RELEASE_PENDING);
  11144. +}
  11145. +
  11146. +/*
  11147. + * Lc entity
  11148. + *
  11149. + * The Lc entity receives and transmits LAPC frames from/to the MAC layer.
  11150. + *
  11151. + * For transmission the frames are checksummed and fragmented into channel
  11152. + * sized units. The channel is chosen before transmission of a new frame
  11153. + * based on availability and demand. All fragments of one frame are
  11154. + * transmitted in the chosen channel.
  11155. + *
  11156. + * Received fragments are resegmented and have their checksum validated,
  11157. + * then routed to the LAPC entity associated with the logical link number.
  11158. + */
  11159. +
  11160. +#define lc_debug(lc, fmt, args...) \
  11161. + pr_debug("Lc (MCEI %u): " fmt, (lc)->mc->mcei, ## args)
  11162. +
  11163. +void dect_lc_destroy(struct dect_lc *lc)
  11164. +{
  11165. + lc_debug(lc, "destroy\n");
  11166. + dect_dlc_mac_conn_unbind(lc->mc);
  11167. + kfree_skb(lc->rx_head);
  11168. + kfree_skb(lc->tx_head);
  11169. + __skb_queue_purge(&lc->txq);
  11170. + kfree(lc);
  11171. +}
  11172. +
  11173. +static void dect_lc_put(struct dect_lc *lc)
  11174. +{
  11175. + if (--lc->use > 0)
  11176. + return;
  11177. + dect_lc_destroy(lc);
  11178. +}
  11179. +
  11180. +static void dect_lc_hold(struct dect_lc *lc)
  11181. +{
  11182. + lc->use++;
  11183. +}
  11184. +
  11185. +void dect_lc_unbind(struct dect_lc *lc, struct dect_lapc *lapc)
  11186. +{
  11187. + lc_debug(lc, "unbind LLN: %u use: %u\n", lapc->dli.lln, lc->use);
  11188. + if (WARN_ON(lc->lapcs[lapc->dli.lln] == NULL))
  11189. + return;
  11190. +
  11191. + lc->lapcs[lapc->dli.lln] = NULL;
  11192. + dect_lc_put(lc);
  11193. +}
  11194. +
  11195. +void dect_lc_bind(struct dect_lc *lc, struct dect_lapc *lapc)
  11196. +{
  11197. + lc_debug(lc, "bind LLN: %u use: %u\n", lapc->dli.lln, lc->use);
  11198. +
  11199. + lc->lapcs[lapc->dli.lln] = lapc;
  11200. + dect_lc_hold(lc);
  11201. +}
  11202. +
  11203. +struct dect_lc *dect_lc_init(struct dect_mac_conn *mc, gfp_t gfp)
  11204. +{
  11205. + struct dect_lc *lc;
  11206. +
  11207. + lc = kzalloc(sizeof(*lc), gfp);
  11208. + if (lc == NULL)
  11209. + return NULL;
  11210. +
  11211. + lc->mc = mc;
  11212. + dect_dlc_mac_conn_bind(mc);
  11213. +
  11214. + lc_debug(lc, "init\n");
  11215. + skb_queue_head_init(&lc->txq);
  11216. + switch (mc->mci.pmid.type) {
  11217. + case DECT_PMID_ASSIGNED:
  11218. + lc->lsig = dect_build_pmid(&mc->mci.pmid);
  11219. + break;
  11220. + default:
  11221. + lc->lsig = 0;
  11222. + break;
  11223. + }
  11224. +
  11225. + return lc;
  11226. +}
  11227. +
  11228. +static void dect_fa_frame_csum(const struct dect_lc *lc, struct sk_buff *skb)
  11229. +{
  11230. + u8 *data = skb->data;
  11231. + unsigned int i;
  11232. + u8 c0 = 0, c1 = 0;
  11233. + u8 x, y;
  11234. + u16 t;
  11235. +
  11236. + data[skb->len - 2] = 0;
  11237. + data[skb->len - 1] = 0;
  11238. +
  11239. + for (i = 0; i < skb->len; i++) {
  11240. + t = c0 + data[i];
  11241. + c0 = (t & 0xffU) + ((t >> 8) & 0x1U);
  11242. + t = c1 + c0;
  11243. + c1 = (t & 0xffU) + ((t >> 8) & 0x1U);
  11244. + }
  11245. +
  11246. + t = c0 + (u8)~c1;
  11247. + x = (t & 0xffU) + ((t >> 8) & 0x1U);
  11248. +
  11249. + t = (u8)~c0 + (u8)~c0;
  11250. + t = (t & 0xffU) + ((t >> 8) & 0x1U);
  11251. + t += c1;
  11252. + y = (t & 0xffU) + ((t >> 8) & 0x1U);
  11253. +
  11254. + data[skb->len - 2] = x ^ (lc->lsig >> 8);
  11255. + data[skb->len - 1] = y ^ (lc->lsig & 0xff);
  11256. + lc_debug(lc, "checksum: lsig: %.4x x: %.2x y: %.2x\n",
  11257. + lc->lsig, x, y);
  11258. +}
  11259. +
  11260. +static bool dect_fa_frame_csum_verify(const struct dect_lc *lc,
  11261. + struct sk_buff *skb)
  11262. +{
  11263. + u8 *data = skb->data;
  11264. + unsigned int i;
  11265. + u8 c0 = 0, c1 = 0;
  11266. + u16 t;
  11267. +
  11268. + data[skb->len - 2] ^= lc->lsig >> 8;
  11269. + data[skb->len - 1] ^= lc->lsig & 0xff;
  11270. +
  11271. + for (i = 0; i < skb->len; i++) {
  11272. + t = c0 + data[i];
  11273. + c0 = (t & 0xffU) + ((t >> 8) & 0x1U);
  11274. + t = c1 + c0;
  11275. + c1 = (t & 0xffU) + ((t >> 8) & 0x1U);
  11276. + }
  11277. +
  11278. + lc_debug(lc, "csum verify: lsig %.4x c0: %.2x c1: %.2x\n",
  11279. + lc->lsig, c0, c1);
  11280. + return c0 == (u8)~0 && c1 == (u8)~0;
  11281. +}
  11282. +
  11283. +static const u8 channel_sdu_size[] = {
  11284. + [DECT_MC_C_S] = DECT_C_S_SDU_SIZE,
  11285. + [DECT_MC_C_F] = DECT_C_F_SDU_SIZE,
  11286. +};
  11287. +
  11288. +/*
  11289. + * Prepare a DLC frame for transmission to the MAC layer. This involves
  11290. + * checksumming the frame, selecting the logical channel for transmission
  11291. + * and fragmenting it into units carried by the logical channel.
  11292. + */
  11293. +static struct sk_buff *dect_lc_tx(struct dect_lc *lc)
  11294. +{
  11295. + struct sk_buff *skb, *frag;
  11296. + u8 *fill, fill_len;
  11297. + u8 flen;
  11298. +
  11299. + skb = lc->tx_head;
  11300. + if (skb == NULL) {
  11301. + skb = skb_dequeue(&lc->txq);
  11302. + if (skb == NULL)
  11303. + return NULL;
  11304. + lc_debug(lc, "tx: begin new frame len: %u\n", skb->len);
  11305. +
  11306. + flen = channel_sdu_size[DECT_MC_C_S];
  11307. + fill_len = roundup(skb->len + DECT_FA_CSUM_SIZE, flen) -
  11308. + (skb->len + DECT_FA_CSUM_SIZE);
  11309. + fill = skb_put(skb, fill_len);
  11310. + memset(fill, DECT_FA_FILL_PATTERN, fill_len);
  11311. +
  11312. + skb_put(skb, DECT_FA_CSUM_SIZE);
  11313. + dect_fa_frame_csum(lc, skb);
  11314. +
  11315. + lc->tx_head = skb;
  11316. + lc->tx_len = flen;
  11317. + }
  11318. +
  11319. + /* Fragment into tx_len sized units */
  11320. + if (skb->len > lc->tx_len) {
  11321. + frag = skb_copy(skb, GFP_ATOMIC);
  11322. + if (frag == NULL)
  11323. + return NULL;
  11324. + skb_trim(frag, lc->tx_len);
  11325. + skb_pull(skb, lc->tx_len);
  11326. + } else {
  11327. + frag = lc->tx_head;
  11328. + lc->tx_head = NULL;
  11329. + }
  11330. +
  11331. + lc_debug(lc, "tx: %sfragment len: %u\n",
  11332. + lc->tx_head ? "" : "last ", frag->len);
  11333. + return frag;
  11334. +}
  11335. +
  11336. +static struct sk_buff *dect_lc_reassemble(struct dect_lc *lc,
  11337. + enum dect_data_channels chan,
  11338. + struct sk_buff *skb)
  11339. +{
  11340. + struct dect_fa_len fl;
  11341. + u8 flen, len;
  11342. +
  11343. + if (lc->rx_head == NULL) {
  11344. + dect_fa_parse_len(&fl, skb);
  11345. + len = fl.len;
  11346. + len += DECT_FA_HDR_SIZE + DECT_FA_CSUM_SIZE;
  11347. +
  11348. + flen = channel_sdu_size[chan];
  11349. + lc->rx_len = roundup(len, flen);
  11350. + lc_debug(lc, "new SDU: len: %u flen: %u\n", len, flen);
  11351. + }
  11352. +
  11353. + lc->rx_head = skb_append_frag(lc->rx_head, skb);
  11354. + skb = NULL;
  11355. +
  11356. + if (lc->rx_head->len >= lc->rx_len) {
  11357. + WARN_ON(lc->rx_head->len != lc->rx_len);
  11358. + skb = lc->rx_head;
  11359. + lc->rx_head = NULL;
  11360. +
  11361. + if (skb_linearize(skb) < 0)
  11362. + goto err;
  11363. + if (!dect_fa_frame_csum_verify(lc, skb))
  11364. + goto err;
  11365. +
  11366. + /* Trim checksum and filling */
  11367. + dect_fa_parse_len(&fl, skb);
  11368. + skb_trim(skb, fl.len + DECT_FA_HDR_SIZE);
  11369. + lc_debug(lc, "reassembled SDU: len: %u\n", skb->len);
  11370. + }
  11371. +
  11372. + return skb;
  11373. +
  11374. +err:
  11375. + lc_debug(lc, "reassembly failed\n");
  11376. + kfree_skb(skb);
  11377. + return NULL;
  11378. +}
  11379. +
  11380. +static void dect_lc_rcv(struct dect_lc *lc, enum dect_data_channels chan,
  11381. + struct sk_buff *skb)
  11382. +{
  11383. + struct dect_fa_hdr *fh;
  11384. + struct dect_lapc *lapc;
  11385. + struct dect_dli dli;
  11386. + enum dect_sapis sapi;
  11387. +
  11388. + skb = dect_lc_reassemble(lc, chan, skb);
  11389. + if (skb == NULL)
  11390. + return;
  11391. + fh = (struct dect_fa_hdr *)skb->data;
  11392. +
  11393. + dli.lln = (fh->addr & DECT_FA_ADDR_LLN_MASK) >> DECT_FA_ADDR_LLN_SHIFT;
  11394. + lc_debug(lc, "receive: LLN %u NLF %u SAPI %u\n",
  11395. + dli.lln, (fh->addr & DECT_FA_ADDR_NLF_FLAG) ? 1 : 0,
  11396. + (fh->addr & DECT_FA_ADDR_SAPI_MASK) >> DECT_FA_ADDR_SAPI_SHIFT);
  11397. +
  11398. + if (lc->lapcs[dli.lln] != NULL)
  11399. + return dect_lapc_rcv(lc->lapcs[dli.lln], skb);
  11400. +
  11401. + /* Link establishment: new requests are only valid while no link
  11402. + * establishment is in progress.
  11403. + */
  11404. + if (!(fh->addr & DECT_FA_ADDR_NLF_FLAG))
  11405. + goto err;
  11406. + if ((fh->ctrl & DECT_FA_CTRL_I_FMT_MASK) != DECT_FA_CTRL_I_FMT_ID)
  11407. + goto err;
  11408. + if (lc->elapc != NULL)
  11409. + goto err;
  11410. +
  11411. + sapi = (fh->addr & DECT_FA_ADDR_SAPI_MASK) >> DECT_FA_ADDR_SAPI_SHIFT;
  11412. + if (sapi != DECT_SAPI_CO_SIGNALLING && sapi != DECT_SAPI_CL_SIGNALLING)
  11413. + goto err;
  11414. + memcpy(&dli.mci, &lc->mc->mci, sizeof(dli.mci));
  11415. +
  11416. + lapc = dect_ssap_rcv_request(lc, &dli, sapi);
  11417. + if (lapc == NULL)
  11418. + goto err;
  11419. + dect_lc_bind(lc, lapc);
  11420. +
  11421. + return dect_lapc_rcv(lapc, skb);
  11422. +
  11423. +err:
  11424. + lc_debug(lc, "packet ignored\n");
  11425. + kfree_skb(skb);
  11426. +}
  11427. +
  11428. +void dect_cplane_rcv(struct dect_mac_conn *mc, enum dect_data_channels chan,
  11429. + struct sk_buff *skb)
  11430. +{
  11431. + struct dect_lc *lc;
  11432. +
  11433. + if (mc->lc == NULL) {
  11434. + lc = dect_lc_init(mc, GFP_ATOMIC);
  11435. + if (lc == NULL)
  11436. + goto err;
  11437. + mc->lc = lc;
  11438. + }
  11439. +
  11440. + lc_debug(mc->lc, "MAC_CO_DATA-ind: chan: %u len: %u\n", chan, skb->len);
  11441. + return dect_lc_rcv(mc->lc, chan, skb);
  11442. +
  11443. +err:
  11444. + kfree_skb(skb);
  11445. +}
  11446. +
  11447. +struct sk_buff *dect_cplane_dtr(struct dect_mac_conn *mc, enum dect_data_channels chan)
  11448. +{
  11449. + struct dect_lc *lc;
  11450. +
  11451. + lc = mc->lc;
  11452. + if (lc == NULL)
  11453. + return NULL;
  11454. + lc_debug(lc, "MAC_CO_DTR-ind: chan: %u\n", chan);
  11455. + return dect_lc_tx(lc);
  11456. +}
  11457. +
  11458. +void dect_cplane_notify_state_change(struct dect_mac_conn *mc)
  11459. +{
  11460. + struct dect_lc *lc = mc->lc;
  11461. + unsigned int i;
  11462. +
  11463. + if (lc == NULL)
  11464. + return;
  11465. +
  11466. + lc_debug(lc, "mac conn state change: state: %u\n", mc->state);
  11467. + switch (mc->state) {
  11468. + // FIXME: this does not make sense for incoming connections
  11469. + case DECT_MAC_CONN_OPEN_PENDING:
  11470. + break;
  11471. + case DECT_MAC_CONN_OPEN:
  11472. + for (i = 0; i < ARRAY_SIZE(lc->lapcs); i++) {
  11473. + if (lc->lapcs[i] == NULL)
  11474. + continue;
  11475. + dect_lapc_establish(lc->lapcs[i]);
  11476. + break;
  11477. + }
  11478. + break;
  11479. + case DECT_MAC_CONN_CLOSED:
  11480. + break;
  11481. + }
  11482. +}
  11483. +
  11484. +void dect_cplane_mac_dis_ind(const struct dect_mac_conn *mc,
  11485. + enum dect_release_reasons reason)
  11486. +{
  11487. + struct dect_lc *lc = mc->lc;
  11488. + unsigned int i;
  11489. + int err;
  11490. +
  11491. + if (lc == NULL)
  11492. + return;
  11493. +
  11494. + switch (reason) {
  11495. + case DECT_REASON_BEARER_RELEASE:
  11496. + err = 0;
  11497. + break;
  11498. + case DECT_REASON_BEARER_SETUP_OR_HANDOVER_FAILED:
  11499. + err = EHOSTUNREACH;
  11500. + break;
  11501. + case DECT_REASON_TIMEOUT_LOST_HANDSHAKE:
  11502. + err = ETIMEDOUT;
  11503. + break;
  11504. + default:
  11505. + err = EIO;
  11506. + break;
  11507. + }
  11508. +
  11509. + dect_lc_hold(lc);
  11510. + for (i = 0; i < ARRAY_SIZE(lc->lapcs); i++) {
  11511. + if (lc->lapcs[i] == NULL)
  11512. + continue;
  11513. + lc->lapcs[i]->sk->sk_state = DECT_SK_RELEASED;
  11514. + dect_lapc_error_report(lc->lapcs[i], err);
  11515. + dect_lapc_destroy(lc->lapcs[i]);
  11516. + }
  11517. + dect_lc_put(lc);
  11518. +}
  11519. +
  11520. +void dect_cplane_mac_enc_eks_ind(const struct dect_mac_conn *mc,
  11521. + enum dect_cipher_states status)
  11522. +{
  11523. + struct dect_lc *lc = mc->lc;
  11524. + struct dect_dl_encrypt enc;
  11525. + struct sk_buff *skb, *nskb;
  11526. + unsigned int i;
  11527. +
  11528. + if (lc == NULL || lc->use == 0)
  11529. + return;
  11530. +
  11531. + enc.status = status;
  11532. + skb = dect_alloc_notification(DECT_DL_ENCRYPT, &enc, sizeof(enc));
  11533. +
  11534. + for (i = 0; i < ARRAY_SIZE(lc->lapcs); i++) {
  11535. + if (lc->lapcs[i] == NULL)
  11536. + continue;
  11537. +
  11538. + nskb = skb ? skb_clone(skb, GFP_ATOMIC) : NULL;
  11539. + if (nskb != NULL)
  11540. + sock_queue_err_skb(lc->lapcs[i]->sk, nskb);
  11541. + else
  11542. + dect_lapc_error_report(lc->lapcs[i], ENOMEM);
  11543. + }
  11544. +
  11545. + kfree_skb(skb);
  11546. +}
  11547. diff --git a/net/dect/dlc_lu1_sap.c b/net/dect/dlc_lu1_sap.c
  11548. new file mode 100644
  11549. index 0000000..ff2b35e
  11550. --- /dev/null
  11551. +++ b/net/dect/dlc_lu1_sap.c
  11552. @@ -0,0 +1,475 @@
  11553. +/*
  11554. + * DECT DLC LU1 SAP sockets
  11555. + *
  11556. + * Copyright (c) 2009-2011 Patrick McHardy <[email protected]>
  11557. + *
  11558. + * This program is free software; you can redistribute it and/or modify
  11559. + * it under the terms of the GNU General Public License version 2 as
  11560. + * published by the Free Software Foundation.
  11561. + */
  11562. +
  11563. +#include <linux/kernel.h>
  11564. +#include <linux/module.h>
  11565. +#include <linux/init.h>
  11566. +#include <linux/socket.h>
  11567. +#include <linux/net.h>
  11568. +#include <linux/dect.h>
  11569. +#include <net/sock.h>
  11570. +#include <net/dect/dect.h>
  11571. +#include <net/dect/transceiver.h>
  11572. +
  11573. +#define DECT_LU1_FRAME_NONE 255
  11574. +#define DECT_LU1_PREQUEUE_LEN 5
  11575. +
  11576. +#define lu1_debug(lu1, fmt, args...) \
  11577. + pr_debug("LU1: rx_bytes: %u tx_bytes: %u " fmt, \
  11578. + (lu1)->qstats.rx_bytes, (lu1)->qstats.tx_bytes, \
  11579. + ## args)
  11580. +
  11581. +struct dect_lu1_sap {
  11582. + struct sock sk;
  11583. + int index;
  11584. + struct dect_ulei ulei;
  11585. + struct dect_mac_conn *mc;
  11586. + u8 frame;
  11587. + u8 slot;
  11588. + struct sk_buff *last;
  11589. + struct dect_lux lux;
  11590. + struct dect_lu1_queue_stats qstats;
  11591. +};
  11592. +
  11593. +/* Seamless handover slot offsets as per ETS 300 175-3 Annex F */
  11594. +static const u8 slot_offset_tbl[][DECT_HALF_FRAME_SIZE] = {
  11595. + [DECT_FULL_SLOT] = {
  11596. + [0] = 0,
  11597. + [1] = 1,
  11598. + [2] = 3,
  11599. + [3] = 5,
  11600. + [4] = 6,
  11601. + [5] = 8,
  11602. + [6] = 10,
  11603. + [7] = 11,
  11604. + [8] = 13,
  11605. + [9] = 15,
  11606. + [10] = 16,
  11607. + [11] = 18,
  11608. + },
  11609. + [DECT_DOUBLE_SLOT] = {
  11610. + [0] = 0,
  11611. + [2] = 8,
  11612. + [4] = 16,
  11613. + [6] = 24,
  11614. + [8] = 32,
  11615. + [10] = 40,
  11616. + },
  11617. + [DECT_LONG_SLOT_640] = {
  11618. + [0] = 0,
  11619. + [1] = 3,
  11620. + [2] = 6,
  11621. + [3] = 10,
  11622. + [4] = 13,
  11623. + [5] = 16,
  11624. + [6] = 20,
  11625. + [7] = 23,
  11626. + [8] = 26,
  11627. + [9] = 30,
  11628. + [10] = 33,
  11629. + },
  11630. +};
  11631. +
  11632. +static struct sk_buff *dect_lu1_dequeue(struct dect_lux *lux)
  11633. +{
  11634. + struct dect_lu1_sap *lu1 = container_of(lux, struct dect_lu1_sap, lux);
  11635. + struct dect_cluster *cl = lu1->mc->cl;
  11636. + struct sock *sk = &lu1->sk;
  11637. + struct sk_buff *skb, *clone, *head = NULL;
  11638. + u8 need = dect_b_field_size(lu1->mc->mcp.slot);
  11639. + u8 frame, slot, off, last_off;
  11640. +
  11641. + /* Fill queue up to prequeue len before delivering the first frame */
  11642. + if (lu1->frame == DECT_LU1_FRAME_NONE &&
  11643. + sk->sk_write_queue.qlen < DECT_LU1_PREQUEUE_LEN)
  11644. + return NULL;
  11645. +
  11646. + /* Calculate seamless handover data offset */
  11647. + frame = __dect_framenum(&cl->timer_base[DECT_TIMER_TX]);
  11648. + slot = __dect_slotnum(&cl->timer_base[DECT_TIMER_TX]);
  11649. + if (slot >= DECT_HALF_FRAME_SIZE)
  11650. + slot -= DECT_HALF_FRAME_SIZE;
  11651. +
  11652. + last_off = slot_offset_tbl[lu1->mc->mcp.slot][lu1->slot];
  11653. + off = slot_offset_tbl[lu1->mc->mcp.slot][slot];
  11654. +
  11655. + if (off > last_off)
  11656. + off -= last_off;
  11657. + else
  11658. + off += need - last_off;
  11659. +
  11660. + /* Advance queue */
  11661. + lu1_debug(lu1, "dequeue: slot: %u off: %u need: %u\n", slot, off, need);
  11662. + if (lu1->frame != DECT_LU1_FRAME_NONE && lu1->frame != frame)
  11663. + lu1->qstats.tx_bytes -= skb_queue_pull(&sk->sk_write_queue, off);
  11664. +
  11665. + lu1->frame = frame;
  11666. + lu1->slot = slot;
  11667. +
  11668. + /* Duplicate data from last frame on underflow */
  11669. + if (lu1->qstats.tx_bytes < need && lu1->last) {
  11670. + lu1->qstats.tx_underflow++;
  11671. + skb = skb_clone(lu1->last, GFP_ATOMIC);
  11672. + if (skb == NULL)
  11673. + goto err;
  11674. + skb_pull(skb, skb->len - (need - lu1->qstats.tx_bytes));
  11675. +
  11676. + skb_queue_head(&sk->sk_write_queue, skb);
  11677. + lu1->qstats.tx_bytes += skb->len;
  11678. + lu1_debug(lu1, "fill: len: %u need: %u\n", skb->len, need);
  11679. +
  11680. + }
  11681. +
  11682. + skb = NULL;
  11683. + while (need > 0) {
  11684. + if (skb == NULL) {
  11685. + skb = skb_peek(&sk->sk_write_queue);
  11686. + if (skb == NULL)
  11687. + goto underflow;
  11688. + /* The head needs to be copied to avoid sharing the
  11689. + * frag list. */
  11690. + clone = skb_copy(skb, GFP_ATOMIC);
  11691. + } else {
  11692. + if (skb_queue_is_last(&sk->sk_write_queue, skb))
  11693. + goto underflow;
  11694. + skb = skb->next;
  11695. + clone = skb_clone(skb, GFP_ATOMIC);
  11696. + }
  11697. +
  11698. + if (clone == NULL)
  11699. + goto err;
  11700. +
  11701. + if (clone->len > need)
  11702. + skb_trim(clone, need);
  11703. + need -= clone->len;
  11704. +
  11705. + head = skb_append_frag(head, clone);
  11706. + lu1_debug(lu1, "dequeue: head: %u need: %u\n", head->len, need);
  11707. + }
  11708. +
  11709. + if (skb_linearize(head) < 0)
  11710. + goto err;
  11711. +
  11712. + kfree_skb(lu1->last);
  11713. + lu1->last = skb_get(head);
  11714. +
  11715. + lu1_debug(lu1, "dequeued: len: %u\n", head->len);
  11716. + return head;
  11717. +
  11718. +underflow:
  11719. + lu1->qstats.tx_underflow++;
  11720. +err:
  11721. + kfree_skb(head);
  11722. + lu1_debug(lu1, "dequeue: no frame available\n");
  11723. + return NULL;
  11724. +}
  11725. +
  11726. +static void dect_lu1_enqueue(struct dect_lux *lux, struct sk_buff *skb)
  11727. +{
  11728. + struct dect_lu1_sap *lu1 = container_of(lux, struct dect_lu1_sap, lux);
  11729. + unsigned int len = skb->len;
  11730. +
  11731. + if (sock_queue_rcv_skb(&lu1->sk, skb) < 0)
  11732. + kfree_skb(skb);
  11733. + else
  11734. + lu1->qstats.rx_bytes += len;
  11735. +}
  11736. +
  11737. +static void dect_lu1_disconnect(struct dect_lux *lux)
  11738. +{
  11739. + struct dect_lu1_sap *lu1 = container_of(lux, struct dect_lu1_sap, lux);
  11740. + struct sock *sk = &lu1->sk;
  11741. +
  11742. + sk->sk_state = DECT_SK_RELEASED;
  11743. + sk->sk_err = ENETDOWN;
  11744. + if (!sock_flag(sk, SOCK_DEAD))
  11745. + sk->sk_error_report(sk);
  11746. + lu1->mc->fbx = NULL;
  11747. + dect_dlc_mac_conn_unbind(lu1->mc);
  11748. + lu1->mc = NULL;
  11749. +}
  11750. +
  11751. +static const struct dect_lux_ops dect_lu1_ops = {
  11752. + .dequeue = dect_lu1_dequeue,
  11753. + .enqueue = dect_lu1_enqueue,
  11754. + .disconnect = dect_lu1_disconnect,
  11755. +};
  11756. +
  11757. +static inline struct dect_lu1_sap *dect_lu1_sap(struct sock *sk)
  11758. +{
  11759. + return (struct dect_lu1_sap *)sk;
  11760. +}
  11761. +
  11762. +static int dect_parse_ulei(struct dect_ulei *ulei,
  11763. + const struct sockaddr_dect_lu *addr)
  11764. +{
  11765. + if (dect_parse_ari(&ulei->mci.ari, (u64)addr->dect_ari << 24) == 0)
  11766. + return -EINVAL;
  11767. + dect_parse_pmid(&ulei->mci.pmid, addr->dect_pmid);
  11768. + ulei->mci.lcn = addr->dect_lcn;
  11769. + return 0;
  11770. +}
  11771. +
  11772. +static void dect_build_ulei(struct sockaddr_dect_lu *addr,
  11773. + const struct dect_ulei *ulei)
  11774. +{
  11775. + addr->dect_family = AF_DECT;
  11776. + addr->dect_pmid = dect_build_pmid(&ulei->mci.pmid);
  11777. + addr->dect_lcn = ulei->mci.lcn;
  11778. +}
  11779. +
  11780. +static int dect_lu1_init(struct sock *sk)
  11781. +{
  11782. + struct dect_lu1_sap *lu1 = dect_lu1_sap(sk);
  11783. +
  11784. + sk->sk_state = DECT_SK_RELEASED;
  11785. + lu1->frame = DECT_LU1_FRAME_NONE;
  11786. + return 0;
  11787. +}
  11788. +
  11789. +static void dect_lu1_close(struct sock *sk, long timeout)
  11790. +{
  11791. + struct dect_lu1_sap *lu1 = dect_lu1_sap(sk);
  11792. +
  11793. + if (sk->sk_state == DECT_SK_ESTABLISHED) {
  11794. + lu1->mc->fbx = NULL;
  11795. + dect_dlc_mac_conn_unbind(lu1->mc);
  11796. + sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
  11797. + }
  11798. +
  11799. + __skb_queue_purge(&sk->sk_receive_queue);
  11800. + __skb_queue_purge(&sk->sk_write_queue);
  11801. + kfree_skb(lu1->last);
  11802. +
  11803. + sock_orphan(sk);
  11804. + sock_put(sk);
  11805. +}
  11806. +
  11807. +static int dect_lu1_getname(struct sock *sk, struct sockaddr *uaddr,
  11808. + int *len, int peer)
  11809. +{
  11810. + struct sockaddr_dect_lu *addr = (struct sockaddr_dect_lu *)uaddr;
  11811. + struct dect_lu1_sap *lu1 = dect_lu1_sap(sk);
  11812. +
  11813. + if (peer)
  11814. + return -EOPNOTSUPP;
  11815. +
  11816. + addr->dect_index = lu1->index;
  11817. + dect_build_ulei(addr, &lu1->ulei);
  11818. + *len = sizeof(*addr);
  11819. + return 0;
  11820. +}
  11821. +
  11822. +static int dect_lu1_connect(struct sock *sk, struct sockaddr *uaddr, int len)
  11823. +{
  11824. + struct sockaddr_dect_lu *addr = (struct sockaddr_dect_lu *)uaddr;
  11825. + struct dect_lu1_sap *lu1 = dect_lu1_sap(sk);
  11826. + struct dect_cluster *cl;
  11827. + struct dect_ulei ulei;
  11828. + struct dect_mac_conn *mc;
  11829. + int err;
  11830. +
  11831. + err = dect_parse_ulei(&ulei, addr);
  11832. + if (err < 0)
  11833. + goto err1;
  11834. +
  11835. + err = -ENODEV;
  11836. + cl = dect_cluster_get_by_index(addr->dect_index);
  11837. + if (cl == NULL)
  11838. + goto err1;
  11839. +
  11840. + err = -ENETDOWN;
  11841. + mc = dect_mac_conn_get_by_mci(cl, &ulei.mci);
  11842. + if (mc == NULL)
  11843. + goto err1;
  11844. + WARN_ON(mc->state == DECT_MAC_CONN_CLOSED);
  11845. +
  11846. + err = -EBUSY;
  11847. + if (mc->fbx != NULL)
  11848. + goto err1;
  11849. +
  11850. + memcpy(&lu1->ulei, &ulei, sizeof(lu1->ulei));
  11851. +
  11852. + sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
  11853. + sk->sk_state = DECT_SK_ESTABLISHED;
  11854. +
  11855. + lu1->lux.fbx.ops = &dect_fbn_ops;
  11856. + lu1->lux.ops = &dect_lu1_ops;
  11857. + lu1->mc = mc;
  11858. + mc->fbx = &lu1->lux.fbx;
  11859. + dect_dlc_mac_conn_bind(lu1->mc);
  11860. + pr_debug("LU1: bound to MCEI %u\n", mc->mcei);
  11861. + return 0;
  11862. +
  11863. +err1:
  11864. + return err;
  11865. +}
  11866. +
  11867. +static int dect_lu1_getsockopt(struct sock *sk, int level, int optname,
  11868. + char __user *optval, int __user *optlen)
  11869. +{
  11870. + struct dect_lu1_sap *lu1 = dect_lu1_sap(sk);
  11871. + int len;
  11872. +
  11873. + if (get_user(len, optlen))
  11874. + return -EFAULT;
  11875. + if (len < 0)
  11876. + return -EINVAL;
  11877. +
  11878. + switch (optname) {
  11879. + case DECT_LU1_QUEUE_STATS:
  11880. + if (len > sizeof(lu1->qstats))
  11881. + len = sizeof(lu1->qstats);
  11882. + if (put_user(len, optlen) ||
  11883. + copy_to_user(optval, &lu1->qstats, len))
  11884. + return -EFAULT;
  11885. + break;
  11886. + default:
  11887. + return -ENOPROTOOPT;
  11888. + }
  11889. +
  11890. + return 0;
  11891. +}
  11892. +
  11893. +static int dect_lu1_recvmsg(struct sock *sk,
  11894. + struct msghdr *msg, size_t len,
  11895. + int noblock, int flags, int *addr_len)
  11896. +{
  11897. + struct dect_lu1_sap *lu1 = dect_lu1_sap(sk);
  11898. + struct sk_buff *skb;
  11899. + size_t copied = 0, copy;
  11900. + long timeo;
  11901. + int err = 0;
  11902. +
  11903. + if (flags & (MSG_OOB | MSG_TRUNC))
  11904. + return -EOPNOTSUPP;
  11905. +
  11906. + lock_sock(sk);
  11907. +
  11908. + if (sk->sk_state != DECT_SK_ESTABLISHED) {
  11909. + err = -ENOTCONN;
  11910. + goto out;
  11911. + }
  11912. +
  11913. + timeo = sock_rcvtimeo(sk, noblock);
  11914. +
  11915. + while (copied < len) {
  11916. + skb = skb_peek(&sk->sk_receive_queue);
  11917. + if (skb != NULL)
  11918. + goto copy;
  11919. +
  11920. + if (!timeo) {
  11921. + err = -EAGAIN;
  11922. + break;
  11923. + }
  11924. +
  11925. + if (signal_pending(current)) {
  11926. + err = sock_intr_errno(timeo);
  11927. + break;
  11928. + }
  11929. +
  11930. + sk_wait_data(sk, &timeo, NULL);
  11931. + continue;
  11932. +
  11933. +copy:
  11934. + copy = len - copied;
  11935. + if (copy > skb->len)
  11936. + copy = skb->len;
  11937. +
  11938. + err = skb_copy_datagram_msg(skb, 0, msg, copy);
  11939. + if (err < 0)
  11940. + break;
  11941. + copied += copy;
  11942. +
  11943. + if (copy < skb->len) {
  11944. + __skb_pull(skb, copy);
  11945. + break;
  11946. + } else
  11947. + sk_eat_skb(sk, skb);
  11948. + }
  11949. +
  11950. +out:
  11951. + lu1->qstats.rx_bytes -= copied;
  11952. + if (copied < len)
  11953. + lu1->qstats.rx_underflow++;
  11954. +
  11955. + release_sock(sk);
  11956. + lu1_debug(lu1, "recvmsg: dequeued: %zu len: %zu\n", copied, len);
  11957. + return copied ? : err;
  11958. +}
  11959. +
  11960. +static int dect_lu1_sendmsg(struct sock *sk,
  11961. + struct msghdr *msg, size_t len)
  11962. +{
  11963. + struct dect_lu1_sap *lu1 = dect_lu1_sap(sk);
  11964. + struct sk_buff *skb;
  11965. + int err;
  11966. +
  11967. + if (msg->msg_flags & MSG_OOB)
  11968. + return -EOPNOTSUPP;
  11969. +
  11970. + if (sk->sk_state != DECT_SK_ESTABLISHED)
  11971. + return -ENOTCONN;
  11972. +
  11973. + skb = sock_alloc_send_skb(sk, len, msg->msg_flags & MSG_DONTWAIT, &err);
  11974. + if (skb == NULL)
  11975. + goto err1;
  11976. + err = memcpy_from_msg(skb_put(skb, len), msg, len);
  11977. + if (err < 0)
  11978. + goto err2;
  11979. +
  11980. + skb_queue_tail(&sk->sk_write_queue, skb);
  11981. + lu1->qstats.tx_bytes += len;
  11982. + lu1_debug(lu1, "sendmsg: queued: %zu\n", len);
  11983. + return len;
  11984. +
  11985. +err2:
  11986. + kfree_skb(skb);
  11987. +err1:
  11988. + return err;
  11989. +}
  11990. +
  11991. +static struct dect_proto dect_lu1_proto = {
  11992. + .type = SOCK_STREAM,
  11993. + .protocol = DECT_LU1_SAP,
  11994. + .capability = -1,
  11995. + .ops = &dect_stream_ops,
  11996. + .proto.name = "DECT_LU1_SAP",
  11997. + .proto.owner = THIS_MODULE,
  11998. + .proto.obj_size = sizeof(struct dect_lu1_sap),
  11999. + .proto.init = dect_lu1_init,
  12000. + .proto.close = dect_lu1_close,
  12001. + .proto.connect = dect_lu1_connect,
  12002. + .proto.getsockopt = dect_lu1_getsockopt,
  12003. + .proto.recvmsg = dect_lu1_recvmsg,
  12004. + .proto.sendmsg = dect_lu1_sendmsg,
  12005. + .getname = dect_lu1_getname,
  12006. +};
  12007. +
  12008. +static int __init dect_lu1_sap_module_init(void)
  12009. +{
  12010. + BUILD_BUG_ON(sizeof(struct sockaddr_dect_lu) >
  12011. + sizeof(struct sockaddr));
  12012. + return dect_proto_register(&dect_lu1_proto);
  12013. +}
  12014. +
  12015. +static void dect_lu1_sap_module_exit(void)
  12016. +{
  12017. + dect_proto_unregister(&dect_lu1_proto);
  12018. +}
  12019. +
  12020. +module_init(dect_lu1_sap_module_init);
  12021. +module_exit(dect_lu1_sap_module_exit);
  12022. +
  12023. +MODULE_AUTHOR("Patrick McHardy <[email protected]>");
  12024. +MODULE_DESCRIPTION("DECT DLC LU1 SAP sockets");
  12025. +MODULE_LICENSE("GPL");
  12026. +
  12027. +MODULE_ALIAS_NET_PF_PROTO(PF_DECT, DECT_LU1_SAP);
  12028. diff --git a/net/dect/dlc_s_sap.c b/net/dect/dlc_s_sap.c
  12029. new file mode 100644
  12030. index 0000000..a744344
  12031. --- /dev/null
  12032. +++ b/net/dect/dlc_s_sap.c
  12033. @@ -0,0 +1,728 @@
  12034. +/*
  12035. + * DECT DLC S SAP sockets - DLC C-plane data link service access
  12036. + *
  12037. + * Copyright (c) 2009 Patrick McHardy <[email protected]>
  12038. + *
  12039. + * This program is free software; you can redistribute it and/or modify
  12040. + * it under the terms of the GNU General Public License version 2 as
  12041. + * published by the Free Software Foundation.
  12042. + */
  12043. +
  12044. +#ifdef CONFIG_DECT_DEBUG
  12045. +#define DEBUG
  12046. +#endif
  12047. +
  12048. +#include <linux/kernel.h>
  12049. +#include <linux/module.h>
  12050. +#include <linux/init.h>
  12051. +#include <linux/socket.h>
  12052. +#include <linux/net.h>
  12053. +#include <linux/dect.h>
  12054. +#include <asm/uaccess.h>
  12055. +#include <net/sock.h>
  12056. +#include <net/dect/dect.h>
  12057. +
  12058. +static DEFINE_SPINLOCK(dect_ssap_lock);
  12059. +static HLIST_HEAD(dect_ssap_sockets);
  12060. +static HLIST_HEAD(dect_ssap_listeners);
  12061. +
  12062. +struct dect_ssap {
  12063. + struct dect_csk csk;
  12064. + int index;
  12065. + struct dect_dlei dlei;
  12066. + struct dect_lapc *lapc;
  12067. + struct dect_mac_conn_params mcp;
  12068. +};
  12069. +
  12070. +static inline struct dect_ssap *dect_ssap(struct sock *sk)
  12071. +{
  12072. + return (struct dect_ssap *)sk;
  12073. +}
  12074. +
  12075. +static int dect_parse_dlei(struct dect_dlei *dlei,
  12076. + const struct sockaddr_dect_ssap *addr)
  12077. +{
  12078. + if (dect_parse_ari(&dlei->mci.ari, (u64)addr->dect_ari << 24) == 0)
  12079. + return -EINVAL;
  12080. + dect_parse_pmid(&dlei->mci.pmid, addr->dect_pmid);
  12081. + dlei->mci.lcn = addr->dect_lcn;
  12082. +
  12083. + dlei->lln = addr->dect_lln;
  12084. + if (dlei->lln > DECT_LLN_UNASSIGNED &&
  12085. + dlei->lln != DECT_LLN_ANY)
  12086. + return -EINVAL;
  12087. +
  12088. + dlei->sapi = addr->dect_sapi;
  12089. + switch (dlei->sapi) {
  12090. + case DECT_SAPI_CO_SIGNALLING:
  12091. + case DECT_SAPI_CL_SIGNALLING:
  12092. + case DECT_SAPI_ANY:
  12093. + break;
  12094. + default:
  12095. + return -EINVAL;
  12096. + }
  12097. + return 0;
  12098. +}
  12099. +
  12100. +static void dect_build_dlei(struct sockaddr_dect_ssap *addr,
  12101. + const struct dect_dlei *dlei)
  12102. +{
  12103. + addr->dect_family = AF_DECT;
  12104. + addr->dect_pmid = dect_build_pmid(&dlei->mci.pmid);
  12105. + addr->dect_ari = dect_build_ari(&dlei->mci.ari) >> 24;
  12106. + addr->dect_lcn = dlei->mci.lcn;
  12107. + addr->dect_lln = dlei->lln;
  12108. + addr->dect_sapi = dlei->sapi;
  12109. +}
  12110. +
  12111. +static void dect_ssap_insert(struct sock *sk)
  12112. +{
  12113. + sk_add_node(sk, &dect_ssap_sockets);
  12114. + sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
  12115. +}
  12116. +
  12117. +static void dect_ssap_unlink(struct sock *sk)
  12118. +{
  12119. + if (sk_del_node_init(sk))
  12120. + sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
  12121. +}
  12122. +
  12123. +static int dect_ssap_init(struct sock *sk)
  12124. +{
  12125. + struct dect_ssap *ssap = dect_ssap(sk);
  12126. +
  12127. + INIT_HLIST_HEAD(&ssap->csk.accept_queue);
  12128. + return 0;
  12129. +}
  12130. +
  12131. +static struct sock *dect_ssap_acceptq_dequeue(struct dect_ssap *ssap)
  12132. +{
  12133. + struct sock *sk;
  12134. +
  12135. + if (hlist_empty(&ssap->csk.accept_queue))
  12136. + return NULL;
  12137. + sk = hlist_entry(ssap->csk.accept_queue.first, struct sock, sk_bind_node);
  12138. + __sk_del_bind_node(sk);
  12139. + sk_node_init(&sk->sk_bind_node);
  12140. + sk_acceptq_removed(&ssap->csk.sk);
  12141. + return sk;
  12142. +}
  12143. +
  12144. +static void dect_ssap_close(struct sock *sk, long timeout)
  12145. +{
  12146. + struct dect_ssap *ssap = dect_ssap(sk);
  12147. + struct sock *req;
  12148. +
  12149. + pr_debug("close sock %p refcnt %u rmem %u wmem %u\n",
  12150. + sk, atomic_read(&sk->sk_refcnt),
  12151. + atomic_read(&sk->sk_rmem_alloc),
  12152. + atomic_read(&sk->sk_wmem_alloc));
  12153. +
  12154. + spin_lock_bh(&dect_ssap_lock);
  12155. + dect_ssap_unlink(sk);
  12156. + spin_unlock_bh(&dect_ssap_lock);
  12157. +
  12158. + if (sk->sk_state != DECT_SK_RELEASED && ssap->lapc != NULL)
  12159. + dect_lapc_release(ssap->lapc, false);
  12160. +
  12161. + if (!hlist_unhashed(&sk->sk_bind_node))
  12162. + __sk_del_bind_node(sk);
  12163. +
  12164. + while ((req = dect_ssap_acceptq_dequeue(ssap)) != NULL) {
  12165. + spin_lock_bh(&dect_ssap_lock);
  12166. + dect_ssap_unlink(req);
  12167. + spin_unlock_bh(&dect_ssap_lock);
  12168. +
  12169. + dect_lapc_release(dect_ssap(req)->lapc, false);
  12170. + }
  12171. +
  12172. + sk_common_release(sk);
  12173. +}
  12174. +
  12175. +static int dect_ssap_bind_conflict(int index, const struct dect_dlei *dlei)
  12176. +{
  12177. + struct dect_ssap *ssap;
  12178. + struct sock *sk;
  12179. +
  12180. + // FIXME: wildcards
  12181. + sk_for_each(sk, &dect_ssap_sockets) {
  12182. + ssap = dect_ssap(sk);
  12183. + if (ssap->index == index &&
  12184. + !dect_ari_cmp(&ssap->dlei.mci.ari, &dlei->mci.ari) &&
  12185. + !dect_pmid_cmp(&ssap->dlei.mci.pmid, &dlei->mci.pmid) &&
  12186. + ssap->dlei.lln == dlei->lln &&
  12187. + ssap->dlei.sapi == dlei->sapi)
  12188. + return -EADDRINUSE;
  12189. + }
  12190. + return 0;
  12191. +}
  12192. +
  12193. +static int dect_ssap_bind(struct sock *sk, struct sockaddr *uaddr, int len)
  12194. +{
  12195. + struct sockaddr_dect_ssap *addr = (struct sockaddr_dect_ssap *)uaddr;
  12196. + struct dect_ssap *ssap = dect_ssap(sk);
  12197. + struct dect_dlei dlei;
  12198. + int err;
  12199. +
  12200. + if (len < sizeof(*addr) || addr->dect_family != AF_DECT)
  12201. + return -EINVAL;
  12202. +
  12203. + err = dect_parse_dlei(&dlei, addr);
  12204. + if (err < 0)
  12205. + return err;
  12206. +
  12207. + lock_sock(sk);
  12208. + spin_lock_bh(&dect_ssap_lock);
  12209. +
  12210. + err = dect_ssap_bind_conflict(addr->dect_index, &dlei);
  12211. + if (err < 0)
  12212. + goto out;
  12213. +
  12214. + ssap->index = addr->dect_index;
  12215. + memcpy(&ssap->dlei, &dlei, sizeof(ssap->dlei));
  12216. + dect_ssap_insert(sk);
  12217. +out:
  12218. + spin_unlock_bh(&dect_ssap_lock);
  12219. + release_sock(sk);
  12220. + return err;
  12221. +}
  12222. +
  12223. +static struct dect_ssap *dect_ssap_lookup_listener(const struct dect_cluster *cl,
  12224. + const struct dect_dli *dli,
  12225. + enum dect_sapis sapi)
  12226. +{
  12227. + struct dect_ssap *ssap;
  12228. + struct sock *sk;
  12229. +
  12230. + pr_debug("lookup listener: lln %u sapi %u\n", dli->lln, sapi);
  12231. + sk_for_each_bound(sk, &dect_ssap_listeners) {
  12232. + ssap = dect_ssap(sk);
  12233. + if (cl->index != ssap->index)
  12234. + continue;
  12235. +#if 0
  12236. + if (!dect_ari_cmp(&ssap->dlei.mci.ari, &dli->mci.ari))
  12237. + continue;
  12238. + if (!dect_pmid_cmp(&ssap->dlei.mci.pmid, &dli->mci.pmid))
  12239. + continue;
  12240. +#endif
  12241. + pr_debug("ssap: lln %u sapi %u\n", ssap->dlei.lln, ssap->dlei.sapi);
  12242. + if (ssap->dlei.lln != DECT_LLN_ANY &&
  12243. + ssap->dlei.lln != dli->lln)
  12244. + continue;
  12245. + if (ssap->dlei.sapi != DECT_SAPI_ANY &&
  12246. + ssap->dlei.sapi != sapi)
  12247. + continue;
  12248. + return ssap;
  12249. + }
  12250. + return NULL;
  12251. +}
  12252. +
  12253. +struct dect_lapc *dect_ssap_rcv_request(struct dect_lc *lc,
  12254. + const struct dect_dli *dli,
  12255. + enum dect_sapis sapi)
  12256. +{
  12257. + struct dect_ssap *ssap, *newssap;
  12258. + struct sock *sk, *newsk;
  12259. + struct dect_lapc *lapc = NULL;
  12260. +
  12261. + spin_lock(&dect_ssap_lock);
  12262. + ssap = dect_ssap_lookup_listener(lc->mc->cl, dli, sapi);
  12263. + if (ssap == NULL)
  12264. + goto out;
  12265. +
  12266. + sk = &ssap->csk.sk;
  12267. + if (sk_acceptq_is_full(sk))
  12268. + goto out;
  12269. +
  12270. + newsk = sk_alloc(&init_net, PF_DECT, GFP_ATOMIC, sk->sk_prot, 0);
  12271. + if (newsk == NULL)
  12272. + goto out;
  12273. +
  12274. + sock_init_data(NULL, newsk);
  12275. + newsk->sk_type = sk->sk_type;
  12276. + newsk->sk_protocol = sk->sk_protocol;
  12277. + newsk->sk_destruct = sk->sk_destruct;
  12278. +
  12279. + lapc = dect_lapc_init(newsk, dli, sapi, lc, GFP_ATOMIC);
  12280. + if (lapc == NULL)
  12281. + goto err1;
  12282. +
  12283. + newssap = dect_ssap(newsk);
  12284. + newssap->index = lc->mc->cl->index;
  12285. + memcpy(&newssap->dlei.mci, &dli->mci, sizeof(newssap->dlei.mci));
  12286. + newssap->dlei.lln = dli->lln;
  12287. + newssap->dlei.sapi = sapi;
  12288. + newssap->lapc = lapc;
  12289. +
  12290. + newsk->sk_state = DECT_SK_ESTABLISHED;
  12291. + dect_ssap_insert(newsk);
  12292. + sk_add_bind_node(newsk, &ssap->csk.accept_queue);
  12293. + sk_acceptq_added(sk);
  12294. +
  12295. + sk->sk_state_change(sk);
  12296. + sk->sk_data_ready(0);
  12297. +out:
  12298. + spin_unlock(&dect_ssap_lock);
  12299. + return lapc;
  12300. +
  12301. +err1:
  12302. + sk_free(newsk);
  12303. + goto out;
  12304. +}
  12305. +
  12306. +static int dect_ssap_hash(struct sock *sk)
  12307. +{
  12308. + sk->sk_state = DECT_SK_LISTEN;
  12309. +
  12310. + spin_lock_bh(&dect_ssap_lock);
  12311. + sk_add_bind_node(sk, &dect_ssap_listeners);
  12312. + spin_unlock_bh(&dect_ssap_lock);
  12313. + return 0;
  12314. +}
  12315. +
  12316. +static void dect_ssap_unhash(struct sock *sk)
  12317. +{
  12318. + if (sk_hashed(sk)) {
  12319. + spin_lock_bh(&dect_ssap_lock);
  12320. + __sk_del_bind_node(sk);
  12321. + spin_unlock_bh(&dect_ssap_lock);
  12322. + }
  12323. +}
  12324. +
  12325. +static int dect_ssap_wait_req(struct sock *sk, int noblock)
  12326. +{
  12327. + struct task_struct *tsk = current;
  12328. + struct dect_ssap *ssap = dect_ssap(sk);
  12329. + long timeo = sock_rcvtimeo(sk, noblock);
  12330. +
  12331. + for (;;) {
  12332. + DEFINE_WAIT(wait);
  12333. +
  12334. + if (sk->sk_state != DECT_SK_LISTEN)
  12335. + return -EINVAL;
  12336. + if (!hlist_empty(&ssap->csk.accept_queue))
  12337. + break;
  12338. + if (!timeo)
  12339. + return -EWOULDBLOCK;
  12340. + if (signal_pending(tsk))
  12341. + return sock_intr_errno(timeo);
  12342. +
  12343. + prepare_to_wait_exclusive(sk_sleep(sk), &wait,
  12344. + TASK_INTERRUPTIBLE);
  12345. + release_sock(sk);
  12346. + timeo = schedule_timeout(timeo);
  12347. + lock_sock(sk);
  12348. + finish_wait(sk_sleep(sk), &wait);
  12349. + }
  12350. + return 0;
  12351. +}
  12352. +
  12353. +static struct sock *dect_ssap_accept(struct sock *sk, int flags, int *errp)
  12354. +{
  12355. + struct dect_ssap *ssap = dect_ssap(sk);
  12356. + struct sock *newsk;
  12357. + int err;
  12358. +
  12359. + lock_sock(sk);
  12360. + err = dect_ssap_wait_req(sk, flags & O_NONBLOCK);
  12361. + if (err < 0)
  12362. + goto err;
  12363. +
  12364. + newsk = dect_ssap_acceptq_dequeue(ssap);
  12365. + release_sock(sk);
  12366. +
  12367. + *errp = 0;
  12368. + return newsk;
  12369. +
  12370. +err:
  12371. + release_sock(sk);
  12372. + *errp = err;
  12373. + return NULL;
  12374. +}
  12375. +
  12376. +static int dect_ssap_connect(struct sock *sk, struct sockaddr *uaddr, int len)
  12377. +{
  12378. + struct sockaddr_dect_ssap *addr = (struct sockaddr_dect_ssap *)uaddr;
  12379. + struct dect_ssap *ssap = dect_ssap(sk);
  12380. + struct dect_cluster *cl;
  12381. + struct dect_dlei dlei;
  12382. + struct dect_dli dli;
  12383. + struct dect_lapc *lapc;
  12384. + struct dect_lc *lc;
  12385. + struct dect_mac_conn *mc;
  12386. + bool new_mc = false, new_lc = false;
  12387. + int err;
  12388. +
  12389. + if (len < sizeof(*addr) || addr->dect_family != AF_DECT)
  12390. + return -EINVAL;
  12391. +
  12392. + err = dect_parse_dlei(&dlei, addr);
  12393. + if (err < 0)
  12394. + goto err1;
  12395. +
  12396. + err = -ENODEV;
  12397. + cl = dect_cluster_get_by_index(addr->dect_index);
  12398. + if (cl == NULL)
  12399. + goto err1;
  12400. +
  12401. + /* The assignable class B LLNs may only be used for connections
  12402. + * originating from a PT. The unassigned LLN may be used by an FT
  12403. + * to request class B operation. Class A and U may be used by both.
  12404. + */
  12405. + err = -EINVAL;
  12406. + switch (dlei.lln) {
  12407. + case DECT_LLN_ASSIGNABLE_MIN ... DECT_LLN_ASSIGNABLE_MAX:
  12408. + if (cl->mode != DECT_MODE_PP)
  12409. + goto err1;
  12410. + break;
  12411. + case DECT_LLN_UNASSIGNED:
  12412. + if (cl->mode != DECT_MODE_FP)
  12413. + goto err1;
  12414. + break;
  12415. + default:
  12416. + break;
  12417. + }
  12418. +
  12419. + /* Lookup MAC connection and initiate new one if necessary */
  12420. + err = -ENOMEM;
  12421. + mc = dect_mac_conn_get_by_mci(cl, &dlei.mci);
  12422. + if (mc == NULL) {
  12423. + mc = dect_mac_conn_init(cl, &dlei.mci, NULL);
  12424. + if (mc == NULL)
  12425. + goto err1;
  12426. + new_mc = true;
  12427. + lc = NULL;
  12428. + } else {
  12429. + WARN_ON(mc->state == DECT_MAC_CONN_CLOSED);
  12430. + lc = mc->lc;
  12431. + }
  12432. +
  12433. + /* Get Lc entity and verify LLN is available */
  12434. + if (lc == NULL) {
  12435. + lc = dect_lc_init(mc, GFP_KERNEL);
  12436. + if (lc == NULL)
  12437. + goto err2;
  12438. + mc->lc = lc;
  12439. + new_lc = true;
  12440. + } else {
  12441. + err = -EADDRINUSE;
  12442. + if (lc->lapcs[dlei.lln] != NULL)
  12443. + goto err2;
  12444. + }
  12445. +
  12446. + memcpy(&dli.mci, &dlei.mci, sizeof(dli.mci));
  12447. + dli.lln = dlei.lln;
  12448. +
  12449. + lapc = dect_lapc_init(sk, &dli, dlei.sapi, lc, GFP_KERNEL);
  12450. + if (lapc == NULL)
  12451. + goto err3;
  12452. + ssap->lapc = lapc;
  12453. +
  12454. + dect_lc_bind(lc, lapc);
  12455. +
  12456. + if (new_mc)
  12457. + err = dect_dlc_mac_conn_establish(mc, &ssap->mcp);
  12458. + else
  12459. + err = dect_lapc_establish(lapc);
  12460. +
  12461. + if (err < 0)
  12462. + goto err4;
  12463. +
  12464. + sk->sk_state = DECT_SK_ESTABLISH_PENDING;
  12465. + return 0;
  12466. +
  12467. +err4:
  12468. + dect_lapc_destroy(lapc);
  12469. + /* Both will be release by dect_lapc_destroy() */
  12470. + new_lc = false;
  12471. + new_mc = false;
  12472. +err3:
  12473. + if (new_lc)
  12474. + dect_lc_destroy(lc);
  12475. +err2:
  12476. + if (new_mc)
  12477. + dect_dlc_mac_conn_destroy(mc);
  12478. +err1:
  12479. + return err;
  12480. +}
  12481. +
  12482. +static int dect_ssap_getname(struct sock *sk, struct sockaddr *uaddr, int *len,
  12483. + int peer)
  12484. +{
  12485. + struct sockaddr_dect_ssap *addr = (struct sockaddr_dect_ssap *)uaddr;
  12486. + struct dect_ssap *ssap = dect_ssap(sk);
  12487. +
  12488. +#if 0
  12489. + if (peer)
  12490. + return -EOPNOTSUPP;
  12491. +#endif
  12492. + addr->dect_index = ssap->index;
  12493. + dect_build_dlei(addr, &ssap->dlei);
  12494. + *len = sizeof(*addr);
  12495. + return 0;
  12496. +}
  12497. +
  12498. +static void dect_ssap_shutdown(struct sock *sk, int how)
  12499. +{
  12500. + struct dect_ssap *ssap = dect_ssap(sk);
  12501. +
  12502. + if (!(how & SEND_SHUTDOWN))
  12503. + return;
  12504. +
  12505. + if (sk->sk_state == DECT_SK_ESTABLISHED)
  12506. + dect_lapc_release(ssap->lapc, true);
  12507. +}
  12508. +
  12509. +static int dect_ssap_setsockopt(struct sock *sk, int level, int optname,
  12510. + char __user *optval, unsigned int optlen)
  12511. +{
  12512. + struct dect_ssap *ssap = dect_ssap(sk);
  12513. + struct dect_mac_conn_params mcp;
  12514. + struct dect_dl_encrypt dle;
  12515. + int err;
  12516. + u64 ck;
  12517. +
  12518. + switch (optname) {
  12519. + case DECT_DL_MAC_CONN_PARAMS:
  12520. + if (optlen != sizeof(mcp))
  12521. + return -EINVAL;
  12522. + if (sk->sk_state != DECT_SK_RELEASED)
  12523. + return -EISCONN;
  12524. + if (copy_from_user(&mcp, optval, sizeof(mcp)))
  12525. + return -EFAULT;
  12526. +
  12527. + switch (mcp.service) {
  12528. + case DECT_SERVICE_IN_MIN_DELAY:
  12529. + case DECT_SERVICE_IPX_ENCODED_PROTECTED:
  12530. + case DECT_SERVICE_IN_NORMAL_DELAY:
  12531. + case DECT_SERVICE_UNKNOWN:
  12532. + case DECT_SERVICE_C_CHANNEL_ONLY:
  12533. + case DECT_SERVICE_IP_ERROR_DETECTION:
  12534. + case DECT_SERVICE_IPQ_ERROR_DETECTION:
  12535. + break;
  12536. + default:
  12537. + return -EINVAL;
  12538. + }
  12539. +
  12540. + switch (mcp.slot) {
  12541. + case DECT_FULL_SLOT:
  12542. + case DECT_HALF_SLOT:
  12543. + case DECT_DOUBLE_SLOT:
  12544. + case DECT_LONG_SLOT_640:
  12545. + case DECT_LONG_SLOT_672:
  12546. + break;
  12547. + default:
  12548. + return -EINVAL;
  12549. + }
  12550. +
  12551. + ssap->mcp = mcp;
  12552. + err = 0;
  12553. + break;
  12554. + case DECT_DL_ENC_KEY:
  12555. + if (optlen != sizeof(ck))
  12556. + return -EINVAL;
  12557. + if (sk->sk_state != DECT_SK_ESTABLISH_PENDING &&
  12558. + sk->sk_state != DECT_SK_ESTABLISHED)
  12559. + return -ENOTCONN;
  12560. + if (copy_from_user(&ck, optval, sizeof(ck)))
  12561. + return -EFAULT;
  12562. + err = dect_dlc_mac_conn_enc_key_req(ssap->lapc->lc->mc, ck);
  12563. + break;
  12564. + case DECT_DL_ENCRYPT:
  12565. + if (optlen != sizeof(dle))
  12566. + return -EINVAL;
  12567. + if (sk->sk_state != DECT_SK_ESTABLISHED)
  12568. + return -ENOTCONN;
  12569. + if (ssap->lapc->lc->mc->cl->mode != DECT_MODE_PP)
  12570. + return -EOPNOTSUPP;
  12571. + if (copy_from_user(&dle, optval, sizeof(dle)))
  12572. + return -EFAULT;
  12573. + err = dect_dlc_mac_conn_enc_eks_req(ssap->lapc->lc->mc,
  12574. + dle.status);
  12575. + break;
  12576. + default:
  12577. + err = -ENOPROTOOPT;
  12578. + }
  12579. + return err;
  12580. +}
  12581. +
  12582. +static int dect_ssap_getsockopt(struct sock *sk, int level, int optname,
  12583. + char __user *optval, int __user *optlen)
  12584. +{
  12585. + struct dect_ssap *ssap = dect_ssap(sk);
  12586. + struct dect_mac_conn_params *mcp;
  12587. + int len;
  12588. +
  12589. + if (get_user(len, optlen))
  12590. + return -EFAULT;
  12591. + if (len < 0)
  12592. + return -EINVAL;
  12593. +
  12594. + switch (optname) {
  12595. + case DECT_DL_MAC_CONN_PARAMS:
  12596. + if (sk->sk_state != DECT_SK_ESTABLISH_PENDING &&
  12597. + sk->sk_state != DECT_SK_ESTABLISHED)
  12598. + return -ENOTCONN;
  12599. +
  12600. + mcp = &ssap->lapc->lc->mc->mcp;
  12601. + len = min_t(unsigned int, len, sizeof(*mcp));
  12602. + if (copy_to_user(optval, mcp, len))
  12603. + return -EFAULT;
  12604. + break;
  12605. + default:
  12606. + return -ENOPROTOOPT;
  12607. + }
  12608. +
  12609. + if (put_user(len, optlen))
  12610. + return -EFAULT;
  12611. + return 0;
  12612. +}
  12613. +
  12614. +static int dect_ssap_recvmsg(struct sock *sk,
  12615. + struct msghdr *msg, size_t len,
  12616. + int noblock, int flags, int *addr_len)
  12617. +{
  12618. + struct sockaddr_dect *addr;
  12619. + struct sk_buff *skb, *eskb;
  12620. + size_t copied = 0;
  12621. + int err;
  12622. +
  12623. + if (flags & MSG_OOB)
  12624. + return -EOPNOTSUPP;
  12625. +
  12626. + eskb = skb_dequeue(&sk->sk_error_queue);
  12627. + skb = skb_recv_datagram(sk, flags, noblock, &err);
  12628. + if (skb == NULL) {
  12629. + if (eskb != NULL && err == -EAGAIN) {
  12630. + err = 0;
  12631. + goto out;
  12632. + }
  12633. + if (sk->sk_type == SOCK_SEQPACKET) {
  12634. + lock_sock(sk);
  12635. + if (sk->sk_state != DECT_SK_ESTABLISHED &&
  12636. + err == -EAGAIN)
  12637. + err = -ENOTCONN;
  12638. + release_sock(sk);
  12639. + }
  12640. + goto out;
  12641. + }
  12642. +
  12643. + copied = skb->len;
  12644. + if (len < copied) {
  12645. + msg->msg_flags |= MSG_TRUNC;
  12646. + copied = len;
  12647. + }
  12648. +
  12649. + err = skb_copy_datagram_msg(skb, 0, msg, copied);
  12650. + if (err < 0)
  12651. + goto out_free;
  12652. +
  12653. + if (msg->msg_name != NULL) {
  12654. + addr = (struct sockaddr_dect *)msg->msg_name;
  12655. + addr->dect_family = AF_DECT;
  12656. + addr->dect_index = DECT_SK_CB(skb)->index;
  12657. + msg->msg_namelen = sizeof(*addr);
  12658. + }
  12659. +
  12660. + sock_recv_timestamp(msg, sk, skb);
  12661. +
  12662. + if (flags & MSG_TRUNC)
  12663. + copied = skb->len;
  12664. +out_free:
  12665. + skb_free_datagram(sk, skb);
  12666. +out:
  12667. + if (eskb != NULL)
  12668. + put_cmsg(msg, SOL_DECT, DECT_NOTIFY_CB(eskb)->type,
  12669. + eskb->len, eskb->data);
  12670. + kfree_skb(eskb);
  12671. +
  12672. + return err ? : copied;
  12673. +}
  12674. +
  12675. +static int dect_ssap_sendmsg(struct sock *sk,
  12676. + struct msghdr *msg, size_t len)
  12677. +{
  12678. + struct dect_ssap *ssap = dect_ssap(sk);
  12679. + struct sk_buff *skb;
  12680. + long timeo;
  12681. + int err;
  12682. +
  12683. + if (msg->msg_flags & MSG_OOB)
  12684. + return -EOPNOTSUPP;
  12685. +
  12686. + if (len > DECT_FA_I_MAX)
  12687. + return -EMSGSIZE;
  12688. +
  12689. + lock_sock(sk);
  12690. + if (sk->sk_type == SOCK_SEQPACKET) {
  12691. + if (sk->sk_state != DECT_SK_ESTABLISHED) {
  12692. + timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT);
  12693. + err = sk_stream_wait_connect(sk, &timeo);
  12694. + if (err < 0)
  12695. + goto err1;
  12696. + }
  12697. + }
  12698. +
  12699. + err = -EPIPE;
  12700. + if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN))
  12701. + goto err1;
  12702. +
  12703. + skb = sock_alloc_send_skb(sk, len + 32, msg->msg_flags & MSG_DONTWAIT, &err);
  12704. + if (skb == NULL)
  12705. + goto err1;
  12706. + skb_reset_mac_header(skb);
  12707. + skb_reserve(skb, 16);
  12708. + err = memcpy_from_msg(skb_put(skb, len), msg, len);
  12709. + if (err < 0)
  12710. + goto err2;
  12711. +
  12712. + skb_queue_tail(&sk->sk_write_queue, skb);
  12713. + release_sock(sk);
  12714. +
  12715. + dect_lapc_transmit(ssap->lapc);
  12716. + return len;
  12717. +
  12718. +err2:
  12719. + kfree_skb(skb);
  12720. +err1:
  12721. + err = sk_stream_error(sk, msg->msg_flags, err);
  12722. + release_sock(sk);
  12723. + return err;
  12724. +}
  12725. +
  12726. +static struct dect_proto dect_ssap_proto __read_mostly = {
  12727. + .type = SOCK_SEQPACKET,
  12728. + .protocol = DECT_S_SAP,
  12729. + .capability = CAP_NET_RAW,
  12730. + .ops = &dect_stream_ops,
  12731. + .proto.name = "DECT_S_SAP",
  12732. + .proto.owner = THIS_MODULE,
  12733. + .proto.obj_size = sizeof(struct dect_ssap),
  12734. + .proto.init = dect_ssap_init,
  12735. + .proto.close = dect_ssap_close,
  12736. + .proto.bind = dect_ssap_bind,
  12737. + .proto.hash = dect_ssap_hash,
  12738. + .proto.unhash = dect_ssap_unhash,
  12739. + .proto.accept = dect_ssap_accept,
  12740. + .proto.connect = dect_ssap_connect,
  12741. + .proto.shutdown = dect_ssap_shutdown,
  12742. + .proto.setsockopt = dect_ssap_setsockopt,
  12743. + .proto.getsockopt = dect_ssap_getsockopt,
  12744. + .proto.recvmsg = dect_ssap_recvmsg,
  12745. + .proto.sendmsg = dect_ssap_sendmsg,
  12746. + .getname = dect_ssap_getname,
  12747. +};
  12748. +
  12749. +int __init dect_ssap_module_init(void)
  12750. +{
  12751. + BUILD_BUG_ON(sizeof(struct sockaddr_dect_ssap) >
  12752. + sizeof(struct sockaddr));
  12753. + return dect_proto_register(&dect_ssap_proto);
  12754. +}
  12755. +
  12756. +void dect_ssap_module_exit(void)
  12757. +{
  12758. + dect_proto_unregister(&dect_ssap_proto);
  12759. +}
  12760. +
  12761. +MODULE_ALIAS_NET_PF_PROTO(PF_DECT, DECT_S_SAP);
  12762. diff --git a/net/dect/dlc_uplane.c b/net/dect/dlc_uplane.c
  12763. new file mode 100644
  12764. index 0000000..6d8d318
  12765. --- /dev/null
  12766. +++ b/net/dect/dlc_uplane.c
  12767. @@ -0,0 +1,86 @@
  12768. +/*
  12769. + * DECT DLC U-plane
  12770. + *
  12771. + * Copyright (c) 2009 Patrick McHardy <[email protected]>
  12772. + *
  12773. + * This program is free software; you can redistribute it and/or modify
  12774. + * it under the terms of the GNU General Public License version 2 as
  12775. + * published by the Free Software Foundation.
  12776. + */
  12777. +
  12778. +#ifdef CONFIG_DECT_DEBUG
  12779. +#define DEBUG
  12780. +#endif
  12781. +
  12782. +#include <linux/kernel.h>
  12783. +#include <linux/module.h>
  12784. +#include <linux/init.h>
  12785. +#include <linux/list.h>
  12786. +#include <linux/skbuff.h>
  12787. +#include <linux/net.h>
  12788. +#include <linux/dect.h>
  12789. +#include <net/dect/dect.h>
  12790. +
  12791. +static struct sk_buff *dect_fbn_dequeue(struct dect_fbx *fbx)
  12792. +{
  12793. + struct dect_lux *lux = container_of(fbx, struct dect_lux, fbx);
  12794. +
  12795. + return lux->ops->dequeue(lux);
  12796. +}
  12797. +
  12798. +static void dect_fbn_enqueue(struct dect_fbx *fbx, struct sk_buff *skb)
  12799. +{
  12800. + struct dect_lux *lux = container_of(fbx, struct dect_lux, fbx);
  12801. +
  12802. + lux->ops->enqueue(lux, skb);
  12803. +}
  12804. +
  12805. +const struct dect_fbx_ops dect_fbn_ops = {
  12806. + .dequeue = dect_fbn_dequeue,
  12807. + .enqueue = dect_fbn_enqueue,
  12808. +};
  12809. +EXPORT_SYMBOL_GPL(dect_fbn_ops);
  12810. +
  12811. +struct sk_buff *dect_uplane_dtr(struct dect_mac_conn *mc, enum dect_data_channels chan)
  12812. +{
  12813. + struct dect_fbx *fbx;
  12814. +
  12815. + fbx = mc->fbx;
  12816. + if (fbx == NULL)
  12817. + return NULL;
  12818. + return fbx->ops->dequeue(fbx);
  12819. +}
  12820. +
  12821. +void dect_uplane_rcv(struct dect_mac_conn *mc, enum dect_data_channels chan,
  12822. + struct sk_buff *skb)
  12823. +{
  12824. + struct dect_fbx *fbx;
  12825. +
  12826. + fbx = mc->fbx;
  12827. + if (fbx == NULL)
  12828. + goto err;
  12829. + return fbx->ops->enqueue(fbx, skb);
  12830. +
  12831. +err:
  12832. + kfree_skb(skb);
  12833. +}
  12834. +
  12835. +void dect_uplane_notify_state_change(struct dect_mac_conn *mc)
  12836. +{
  12837. + struct dect_lux *lux;
  12838. + struct dect_fbx *fbx;
  12839. +
  12840. + fbx = mc->fbx;
  12841. + if (fbx == NULL)
  12842. + return;
  12843. + lux = container_of(fbx, struct dect_lux, fbx);
  12844. +
  12845. + switch (mc->state) {
  12846. + case DECT_MAC_CONN_OPEN_PENDING:
  12847. + break;
  12848. + case DECT_MAC_CONN_OPEN:
  12849. + break;
  12850. + case DECT_MAC_CONN_CLOSED:
  12851. + return lux->ops->disconnect(lux);
  12852. + }
  12853. +}
  12854. diff --git a/net/dect/dsc.c b/net/dect/dsc.c
  12855. new file mode 100644
  12856. index 0000000..d3f597a
  12857. --- /dev/null
  12858. +++ b/net/dect/dsc.c
  12859. @@ -0,0 +1,141 @@
  12860. +/*
  12861. + * DECT Standard Cipher
  12862. + *
  12863. + * Copyright (c) 2010 Erik Tews <[email protected]>
  12864. + *
  12865. + * This program is free software; you can redistribute it and/or modify
  12866. + * it under the terms of the GNU General Public License version 2 as
  12867. + * published by the Free Software Foundation.
  12868. + */
  12869. +
  12870. +#include <linux/kernel.h>
  12871. +#include <linux/string.h>
  12872. +#include <net/dect/dsc.h>
  12873. +
  12874. +#define R1_LEN 17
  12875. +#define R2_LEN 19
  12876. +#define R3_LEN 21
  12877. +#define R4_LEN 23
  12878. +
  12879. +#define MASK_R1 (65536 | 32)
  12880. +#define MASK_R2 (262144 | 4096 | 8 | 4)
  12881. +#define MASK_R3 (1048576 | 2)
  12882. +#define MASK_R4 (256 | 4194304)
  12883. +
  12884. +#define R1_CLOCKMASK (1 << 8)
  12885. +#define R2_CLOCKMASK (1 << 9)
  12886. +#define R3_CLOCKMASK (1 << 10)
  12887. +
  12888. +#define R1_R4_CLOCKMASK (1 << 0)
  12889. +#define R2_R4_CLOCKMASK (1 << 1)
  12890. +#define R3_R4_CLOCKMASK (1 << 2)
  12891. +
  12892. +static uint32_t clock(uint32_t lfsr, int length, uint32_t mask)
  12893. +{
  12894. + return (lfsr >> 1) ^ (-(lfsr & 1) & mask);
  12895. +}
  12896. +
  12897. +static uint32_t combine(uint32_t comb, uint32_t r1, uint32_t r2, uint32_t r3)
  12898. +{
  12899. + uint32_t c, x10, x11, x20, x21, x30, x31;
  12900. +
  12901. + c = comb;
  12902. + x10 = r1 & 1;
  12903. + x11 = (r1 >> 1) & 1;
  12904. + x20 = r2 & 1;
  12905. + x21 = (r2 >> 1) & 1;
  12906. + x30 = r3 & 1;
  12907. + x31 = (r3 >> 1) & 1;
  12908. +
  12909. + return (x11 & x10 & c) ^
  12910. + (x20 & x11 & x10) ^
  12911. + (x21 & x10 & c) ^
  12912. + (x21 & x20 & x10) ^
  12913. + (x30 & x10 & c) ^
  12914. + (x30 & x20 & x10) ^
  12915. + (x11 & c) ^
  12916. + (x11 & x10) ^
  12917. + (x20 & x11) ^
  12918. + (x30 & c) ^
  12919. + (x31 & c) ^
  12920. + (x31 & x10) ^
  12921. + (x21) ^
  12922. + (x31);
  12923. +}
  12924. +
  12925. +void dect_dsc_keystream(uint64_t iv, const uint8_t *key,
  12926. + uint8_t *output, unsigned int len)
  12927. +{
  12928. + uint8_t input[16];
  12929. + uint32_t R1, R2, R3, R4, N1, N2, N3, COMB;
  12930. + unsigned int i, keybit;
  12931. +
  12932. + memset(output, 0, len);
  12933. + input[0] = iv & 0xff;
  12934. + input[1] = (iv >> 8) & 0xff;
  12935. + input[2] = (iv >> 16) & 0xff;
  12936. + input[3] = (iv >> 24) & 0xff;
  12937. + input[4] = (iv >> 32) & 0xff;
  12938. + for (i = 5; i < 8; i++)
  12939. + input[i] = 0;
  12940. + for (i = 0; i < 8; i++)
  12941. + input[i + 8] = key[i];
  12942. +
  12943. + R1 = R2 = R3 = R4 = COMB = 0;
  12944. +
  12945. + /* load IV and KEY */
  12946. + for (i = 0; i < 128; i++) {
  12947. + keybit = (input[i / 8] >> ((i) & 7)) & 1;
  12948. + R1 = clock(R1, R1_LEN, MASK_R1) ^ (keybit << (R1_LEN - 1));
  12949. + R2 = clock(R2, R2_LEN, MASK_R2) ^ (keybit << (R2_LEN - 1));
  12950. + R3 = clock(R3, R3_LEN, MASK_R3) ^ (keybit << (R3_LEN - 1));
  12951. + R4 = clock(R4, R4_LEN, MASK_R4) ^ (keybit << (R4_LEN - 1));
  12952. + }
  12953. +
  12954. + for (i = 0; i < 40 + (len * 8); i++) {
  12955. + N1 = R1;
  12956. + N2 = R2;
  12957. + N3 = R3;
  12958. + COMB = combine(COMB, R1, R2, R3);
  12959. + if (((R2 & R2_CLOCKMASK) != 0) ^
  12960. + ((R3 & R3_CLOCKMASK) != 0) ^
  12961. + ((R4 & R1_R4_CLOCKMASK) != 0))
  12962. + N1 = clock(R1, R1_LEN, MASK_R1);
  12963. + if (((R1 & R1_CLOCKMASK) != 0) ^
  12964. + ((R3 & R3_CLOCKMASK) != 0) ^
  12965. + ((R4 & R2_R4_CLOCKMASK) != 0))
  12966. + N2 = clock(R2, R2_LEN, MASK_R2);
  12967. + if (((R1 & R1_CLOCKMASK) != 0) ^
  12968. + ((R2 & R2_CLOCKMASK) != 0) ^
  12969. + ((R4 & R3_R4_CLOCKMASK) != 0))
  12970. + N3 = clock(R3, R3_LEN, MASK_R3);
  12971. +
  12972. + /* Check whether any registers are zero after 11 pre-ciphering
  12973. + * steps. If a register is all-zero after 11 steps, set input
  12974. + * bit to one (see U.S. patent 5608802)
  12975. + */
  12976. + if (i == 11) {
  12977. + if (!R1)
  12978. + N1 ^= (1 << (R1_LEN - 1));
  12979. + if (!R2)
  12980. + N2 ^= (1 << (R2_LEN - 1));
  12981. + if (!R3)
  12982. + N3 ^= (1 << (R3_LEN - 1));
  12983. + if (!R4)
  12984. + R4 ^= (1 << (R4_LEN - 1));
  12985. + }
  12986. +
  12987. + N1 = clock(N1, R1_LEN, MASK_R1);
  12988. + R1 = clock(N1, R1_LEN, MASK_R1);
  12989. + N2 = clock(N2, R2_LEN, MASK_R2);
  12990. + R2 = clock(N2, R2_LEN, MASK_R2);
  12991. + N3 = clock(N3, R3_LEN, MASK_R3);
  12992. + R3 = clock(N3, R3_LEN, MASK_R3);
  12993. + R4 = clock(R4, R4_LEN, MASK_R4);
  12994. + R4 = clock(R4, R4_LEN, MASK_R4);
  12995. + R4 = clock(R4, R4_LEN, MASK_R4);
  12996. +
  12997. + if (i >= 40)
  12998. + output[(i - 40) / 8] |= ((COMB) << (7 - ((i - 40) & 7)));
  12999. + }
  13000. +}
  13001. diff --git a/net/dect/identities.c b/net/dect/identities.c
  13002. new file mode 100644
  13003. index 0000000..28fe80d
  13004. --- /dev/null
  13005. +++ b/net/dect/identities.c
  13006. @@ -0,0 +1,222 @@
  13007. +/*
  13008. + * Copyright (c) 2009 Patrick McHardy <[email protected]>
  13009. + *
  13010. + * This program is free software; you can redistribute it and/or modify
  13011. + * it under the terms of the GNU General Public License version 2 as
  13012. + * published by the Free Software Foundation.
  13013. + */
  13014. +
  13015. +#include <linux/kernel.h>
  13016. +#include <linux/export.h>
  13017. +#include <linux/dect.h>
  13018. +#include <net/dect/dect.h>
  13019. +
  13020. +bool dect_ari_masked_cmp(const struct dect_ari *a1, const struct dect_ari *a2,
  13021. + const struct dect_ari *m)
  13022. +{
  13023. + /* An empty class mask implies a wildcard for everything */
  13024. + if (!m->arc)
  13025. + return false;
  13026. + if (a1->arc != a2->arc)
  13027. + return true;
  13028. +
  13029. + if ((a1->fpn ^ a2->fpn) & m->fpn)
  13030. + return true;
  13031. +
  13032. + switch (a1->arc) {
  13033. + case DECT_ARC_A:
  13034. + return ((a1->emc ^ a2->emc) & m->emc);
  13035. + case DECT_ARC_B:
  13036. + return (((a1->eic ^ a2->eic) & m->eic) |
  13037. + ((a1->fps ^ a2->fps) & m->fps));
  13038. + case DECT_ARC_C:
  13039. + return (((a1->poc ^ a2->poc) & m->poc) |
  13040. + ((a1->fps ^ a2->fps) & m->fps));
  13041. + case DECT_ARC_D:
  13042. + return ((a1->gop ^ a2->gop) & m->gop);
  13043. + case DECT_ARC_E:
  13044. + return ((a1->fil ^ a2->fil) & m->fil);
  13045. + default:
  13046. + return true;
  13047. + }
  13048. +}
  13049. +EXPORT_SYMBOL_GPL(dect_ari_masked_cmp);;
  13050. +
  13051. +bool dect_ari_cmp(const struct dect_ari *a1, const struct dect_ari *a2)
  13052. +{
  13053. + static const struct dect_ari mask = {
  13054. + .arc = ~0,
  13055. + .fpn = ~0,
  13056. + .fps = ~0,
  13057. + { ~0 }
  13058. + };
  13059. + return dect_ari_masked_cmp(a1, a2, &mask);
  13060. +}
  13061. +EXPORT_SYMBOL_GPL(dect_ari_cmp);
  13062. +
  13063. +u8 dect_parse_ari(struct dect_ari *ari, u64 a)
  13064. +{
  13065. + ari->arc = (a & DECT_ARI_ARC_MASK) >> DECT_ARI_ARC_SHIFT;
  13066. + switch (ari->arc) {
  13067. + case DECT_ARC_A:
  13068. + ari->emc = (a & DECT_ARI_A_EMC_MASK) >> DECT_ARI_A_EMC_SHIFT;
  13069. + ari->fpn = (a & DECT_ARI_A_FPN_MASK) >> DECT_ARI_A_FPN_SHIFT;
  13070. + return DECT_ARC_A_LEN;
  13071. + case DECT_ARC_B:
  13072. + ari->eic = (a & DECT_ARI_B_EIC_MASK) >> DECT_ARI_B_EIC_SHIFT;
  13073. + ari->fpn = (a & DECT_ARI_B_FPN_MASK) >> DECT_ARI_B_FPN_SHIFT;
  13074. + ari->fps = (a & DECT_ARI_B_FPS_MASK) >> DECT_ARI_B_FPS_SHIFT;
  13075. + return DECT_ARC_B_LEN;
  13076. + case DECT_ARC_C:
  13077. + ari->poc = (a & DECT_ARI_C_POC_MASK) >> DECT_ARI_C_POC_SHIFT;
  13078. + ari->fpn = (a & DECT_ARI_C_FPN_MASK) >> DECT_ARI_C_FPN_SHIFT;
  13079. + ari->fps = (a & DECT_ARI_C_FPS_MASK) >> DECT_ARI_C_FPS_SHIFT;
  13080. + return DECT_ARC_C_LEN;
  13081. + case DECT_ARC_D:
  13082. + ari->gop = (a & DECT_ARI_D_GOP_MASK) >> DECT_ARI_D_GOP_SHIFT;
  13083. + ari->fpn = (a & DECT_ARI_D_FPN_MASK) >> DECT_ARI_D_FPN_SHIFT;
  13084. + return DECT_ARC_D_LEN;
  13085. + case DECT_ARC_E:
  13086. + ari->fil = (a & DECT_ARI_E_FIL_MASK) >> DECT_ARI_E_FIL_SHIFT;
  13087. + ari->fpn = (a & DECT_ARI_E_FPN_MASK) >> DECT_ARI_E_FPN_SHIFT;
  13088. + return DECT_ARC_E_LEN;
  13089. + default:
  13090. + return 0;
  13091. + }
  13092. +}
  13093. +EXPORT_SYMBOL_GPL(dect_parse_ari);
  13094. +
  13095. +u64 dect_build_ari(const struct dect_ari *ari)
  13096. +{
  13097. + u64 a = 0;
  13098. +
  13099. + a |= (u64)ari->arc << DECT_ARI_ARC_SHIFT;
  13100. + switch (ari->arc) {
  13101. + case DECT_ARC_A:
  13102. + a |= (u64)ari->emc << DECT_ARI_A_EMC_SHIFT;
  13103. + a |= (u64)ari->fpn << DECT_ARI_A_FPN_SHIFT;
  13104. + break;
  13105. + case DECT_ARC_B:
  13106. + a |= (u64)ari->eic << DECT_ARI_B_EIC_SHIFT;
  13107. + a |= (u64)ari->fpn << DECT_ARI_B_FPN_SHIFT;
  13108. + a |= (u64)ari->fps << DECT_ARI_B_FPS_SHIFT;
  13109. + break;
  13110. + case DECT_ARC_C:
  13111. + a |= (u64)ari->poc << DECT_ARI_C_POC_SHIFT;
  13112. + a |= (u64)ari->fpn << DECT_ARI_C_FPN_SHIFT;
  13113. + a |= (u64)ari->fps << DECT_ARI_C_FPS_SHIFT;
  13114. + break;
  13115. + case DECT_ARC_D:
  13116. + a |= (u64)ari->gop << DECT_ARI_D_GOP_SHIFT;
  13117. + a |= (u64)ari->fpn << DECT_ARI_D_FPN_SHIFT;
  13118. + break;
  13119. + case DECT_ARC_E:
  13120. + a |= (u64)ari->fil << DECT_ARI_E_FIL_SHIFT;
  13121. + a |= (u64)ari->fpn << DECT_ARI_E_FPN_SHIFT;
  13122. + break;
  13123. + }
  13124. + return a;
  13125. +}
  13126. +EXPORT_SYMBOL_GPL(dect_build_ari);
  13127. +
  13128. +u64 dect_build_rfpi(const struct dect_idi *idi)
  13129. +{
  13130. + u64 t = 0;
  13131. +
  13132. + t |= idi->e ? DECT_RFPI_E_FLAG : 0;
  13133. + t |= dect_build_ari(&idi->pari) >> DECT_RFPI_ARI_SHIFT;
  13134. + t |= (u64)idi->rpn << DECT_RFPI_RPN_SHIFT;
  13135. + return t;
  13136. +}
  13137. +EXPORT_SYMBOL_GPL(dect_build_rfpi);
  13138. +
  13139. +bool dect_rfpi_cmp(const struct dect_idi *i1, const struct dect_idi *i2)
  13140. +{
  13141. + return dect_ari_cmp(&i1->pari, &i2->pari) ||
  13142. + i1->rpn != i2->rpn ||
  13143. + i1->e != i2->e;
  13144. +}
  13145. +EXPORT_SYMBOL_GPL(dect_rfpi_cmp);
  13146. +
  13147. +u16 dect_build_fmid(const struct dect_idi *idi)
  13148. +{
  13149. + u64 rfpi;
  13150. +
  13151. + rfpi = dect_build_rfpi(idi);
  13152. + rfpi >>= (sizeof(rfpi) - DECT_NT_ID_RFPI_LEN - 1) * BITS_PER_BYTE;
  13153. + return rfpi & DECT_FMID_MASK;
  13154. +}
  13155. +EXPORT_SYMBOL_GPL(dect_build_fmid);
  13156. +
  13157. +/*
  13158. + * PMID (Portable MAC Identity)
  13159. + */
  13160. +
  13161. +void dect_parse_pmid(struct dect_pmid *pmid, u32 p)
  13162. +{
  13163. + if ((p & DECT_PMID_DEFAULT_ID_MASK) == DECT_PMID_DEFAULT_ID) {
  13164. + pmid->type = DECT_PMID_DEFAULT;
  13165. + pmid->num = p & DECT_PMID_DEFAULT_NUM_MASK;
  13166. + } else if ((p & DECT_PMID_EMERGENCY_ID_MASK) == DECT_PMID_EMERGENCY_ID) {
  13167. + pmid->type = DECT_PMID_EMERGENCY;
  13168. + pmid->tpui = p & DECT_PMID_EMERGENCY_TPUI_MASK;
  13169. + } else {
  13170. + pmid->type = DECT_PMID_ASSIGNED;
  13171. + pmid->tpui = p & DECT_PMID_ASSIGNED_TPUI_MASK;
  13172. + }
  13173. +}
  13174. +EXPORT_SYMBOL_GPL(dect_parse_pmid);
  13175. +
  13176. +u32 dect_build_pmid(const struct dect_pmid *pmid)
  13177. +{
  13178. + u32 p = 0;
  13179. +
  13180. + switch (pmid->type) {
  13181. + case DECT_PMID_DEFAULT:
  13182. + p |= DECT_PMID_DEFAULT_ID;
  13183. + p |= pmid->tpui;
  13184. + break;
  13185. + case DECT_PMID_EMERGENCY:
  13186. + p |= DECT_PMID_EMERGENCY_ID;
  13187. + p |= pmid->tpui;
  13188. + break;
  13189. + case DECT_PMID_ASSIGNED:
  13190. + p |= pmid->tpui;
  13191. + break;
  13192. + }
  13193. + return p;
  13194. +}
  13195. +EXPORT_SYMBOL_GPL(dect_build_pmid);
  13196. +
  13197. +bool dect_pmid_cmp(const struct dect_pmid *p1, const struct dect_pmid *p2)
  13198. +{
  13199. + return memcmp(p1, p2, sizeof(*p1));
  13200. +}
  13201. +EXPORT_SYMBOL(dect_pmid_cmp);
  13202. +
  13203. +/**
  13204. + * dect_parse_mci - Extract the MCI elements from a packed MCI in a
  13205. + * struct sockaddr_dect_lu
  13206. + *
  13207. + * The packed MCI is build from ARI + PMID + LCN
  13208. + */
  13209. +int dect_parse_mci(struct dect_mci *mci, u64 m)
  13210. +{
  13211. + u32 p;
  13212. + u8 len;
  13213. +
  13214. + len = dect_parse_ari(&mci->ari, m);
  13215. +
  13216. + len += DECT_PMID_SIZE;
  13217. + p = (m >> (sizeof(m) * BITS_PER_BYTE - len)) & DECT_PMID_MASK;
  13218. + dect_parse_pmid(&mci->pmid, p);
  13219. +
  13220. + len += DECT_ECN_SIZE;
  13221. + mci->lcn = (m >> (sizeof(m) * BITS_PER_BYTE - len)) & DECT_LCN_MASK;
  13222. + return 0;
  13223. +}
  13224. +
  13225. +u64 dect_build_mci(const struct dect_mci *mci)
  13226. +{
  13227. + return 0;
  13228. +}
  13229. diff --git a/net/dect/mac_ccf.c b/net/dect/mac_ccf.c
  13230. new file mode 100644
  13231. index 0000000..0532648
  13232. --- /dev/null
  13233. +++ b/net/dect/mac_ccf.c
  13234. @@ -0,0 +1,2104 @@
  13235. +/*
  13236. + * DECT MAC Cluster Control Functions
  13237. + *
  13238. + * Copyright (c) 2009-2011 Patrick McHardy <[email protected]>
  13239. + *
  13240. + * This program is free software; you can redistribute it and/or modify
  13241. + * it under the terms of the GNU General Public License version 2 as
  13242. + * published by the Free Software Foundation.
  13243. + */
  13244. +
  13245. +#ifdef CONFIG_DECT_DEBUG
  13246. +#define DEBUG
  13247. +#endif
  13248. +
  13249. +#include <linux/kernel.h>
  13250. +#include <linux/module.h>
  13251. +#include <linux/init.h>
  13252. +#include <linux/list.h>
  13253. +#include <linux/skbuff.h>
  13254. +#include <linux/net.h>
  13255. +#include <linux/dect.h>
  13256. +#include <net/dect/dect.h>
  13257. +#include <net/dect/mac_ccf.h>
  13258. +#include <net/dect/mac_csf.h>
  13259. +#include <net/dect/ccp.h>
  13260. +
  13261. +static void dect_llme_scan_result_notify(const struct dect_cluster *cl,
  13262. + const struct dect_scan_result *res);
  13263. +static void dect_llme_mac_info_ind(const struct dect_cluster *cl,
  13264. + const struct dect_idi *idi,
  13265. + const struct dect_si *si);
  13266. +
  13267. +u8 dect_b_field_size(enum dect_slot_types slot)
  13268. +{
  13269. + static const u8 b_field_size[] = {
  13270. + [DECT_FULL_SLOT] = 40,
  13271. + [DECT_DOUBLE_SLOT] = 100,
  13272. + [DECT_LONG_SLOT_640] = 80,
  13273. + };
  13274. + return b_field_size[slot];
  13275. +}
  13276. +EXPORT_SYMBOL_GPL(dect_b_field_size);
  13277. +
  13278. +static struct dect_cluster *dect_cluster_get_by_name(const struct nlattr *nla)
  13279. +{
  13280. + struct dect_cluster *cl;
  13281. +
  13282. + list_for_each_entry(cl, &dect_cluster_list, list) {
  13283. + if (!nla_strcmp(nla, cl->name))
  13284. + return cl;
  13285. + }
  13286. + return NULL;
  13287. +}
  13288. +
  13289. +static struct dect_cluster *dect_cluster(const struct dect_cluster_handle *clh)
  13290. +{
  13291. + return container_of(clh, struct dect_cluster, handle);
  13292. +}
  13293. +
  13294. +static struct dect_cell_handle *
  13295. +dect_cluster_get_cell_by_rpn(struct dect_cluster *cl, u8 rpn)
  13296. +{
  13297. + struct dect_cell_handle *ch;
  13298. +
  13299. + list_for_each_entry(ch, &cl->cells, list) {
  13300. + if (ch->rpn == rpn)
  13301. + return ch;
  13302. + }
  13303. + return NULL;
  13304. +}
  13305. +
  13306. +/*
  13307. + * MAC CCF layer timers
  13308. + */
  13309. +
  13310. +static u8 dect_framenum(const struct dect_cluster *cl, enum dect_timer_bases b)
  13311. +{
  13312. + return __dect_framenum(&cl->timer_base[b]);
  13313. +}
  13314. +
  13315. +static void dect_run_timers(struct dect_cluster *cl, enum dect_timer_bases b)
  13316. +{
  13317. + __dect_run_timers(cl->name, &cl->timer_base[b]);
  13318. +}
  13319. +
  13320. +static void dect_timer_base_update(struct dect_cluster *cl,
  13321. + enum dect_timer_bases base,
  13322. + u32 mfn, u8 framenum, u8 slot)
  13323. +{
  13324. + cl->timer_base[base].mfn = mfn;
  13325. + cl->timer_base[base].framenum = framenum;
  13326. + cl->timer_base[base].slot = slot;
  13327. +}
  13328. +
  13329. +static void dect_timer_add(struct dect_cluster *cl, struct dect_timer *timer,
  13330. + enum dect_timer_bases b, u32 frame, u8 slot)
  13331. +{
  13332. + timer->cluster = cl;
  13333. + __dect_timer_add(cl->name, &cl->timer_base[b], timer, frame, slot);
  13334. +}
  13335. +
  13336. +static void dect_timer_setup(struct dect_timer *timer,
  13337. + void (*func)(struct dect_cluster *, void *),
  13338. + void *data)
  13339. +{
  13340. + dect_timer_init(timer);
  13341. + timer->cb.cluster = func;
  13342. + timer->data = data;
  13343. +}
  13344. +
  13345. +static void dect_ccf_time_ind(struct dect_cluster_handle *clh,
  13346. + enum dect_timer_bases base,
  13347. + u32 mfn, u8 framenum, u8 slot)
  13348. +{
  13349. + struct dect_cluster *cl = dect_cluster(clh);
  13350. +
  13351. + if (base == DECT_TIMER_TX) {
  13352. + dect_timer_base_update(cl, base, mfn, framenum, slot);
  13353. + dect_run_timers(cl, base);
  13354. + } else {
  13355. + dect_run_timers(cl, base);
  13356. + dect_timer_base_update(cl, base, mfn, framenum, slot);
  13357. + }
  13358. +}
  13359. +
  13360. +static void dect_scan_report(const struct dect_cluster_handle *clh,
  13361. + const struct dect_scan_result *res)
  13362. +{
  13363. + struct dect_cluster *cl = dect_cluster(clh);
  13364. +
  13365. + dect_llme_scan_result_notify(cl, res);
  13366. +}
  13367. +
  13368. +static void dect_mac_info_ind(const struct dect_cluster_handle *clh,
  13369. + const struct dect_idi *idi,
  13370. + const struct dect_si *si)
  13371. +{
  13372. + struct dect_cluster *cl = dect_cluster(clh);
  13373. +
  13374. + pr_debug("cl %p: MAC_INFO-ind: rpn: %u\n", cl, idi->rpn);
  13375. + cl->si = *si;
  13376. + cl->rpn = idi->rpn;
  13377. +
  13378. + dect_llme_mac_info_ind(cl, idi, &cl->si);
  13379. +}
  13380. +
  13381. +/*
  13382. + * Broadcast message control
  13383. + */
  13384. +
  13385. +/**
  13386. + * dect_bmc_mac_page_req - queue one segment of B_S channel data
  13387. + *
  13388. + * @cl: DECT cluster
  13389. + * @skb: SDU
  13390. + */
  13391. +void dect_bmc_mac_page_req(struct dect_cluster *cl, struct sk_buff *skb)
  13392. +{
  13393. + const struct dect_cell_handle *ch, *prev = NULL;
  13394. + struct sk_buff *clone;
  13395. +
  13396. + BUG_ON(cl->mode != DECT_MODE_FP);
  13397. +
  13398. + list_for_each_entry(ch, &cl->cells, list) {
  13399. + if (prev != NULL) {
  13400. + clone = skb_clone(skb, GFP_ATOMIC);
  13401. + if (clone != NULL)
  13402. + prev->ops->page_req(prev, clone);
  13403. + }
  13404. + prev = ch;
  13405. + }
  13406. + if (prev != NULL)
  13407. + prev->ops->page_req(prev, skb);
  13408. +}
  13409. +
  13410. +static void dect_bmc_page_ind(const struct dect_cluster_handle *clh,
  13411. + struct sk_buff *skb)
  13412. +{
  13413. + struct dect_cluster *cl = dect_cluster(clh);
  13414. +
  13415. + return dect_mac_page_ind(cl, skb);
  13416. +}
  13417. +
  13418. +/*
  13419. + * Multi-Bearer Control
  13420. + */
  13421. +
  13422. +#define mbc_debug(mbc, fmt, args...) \
  13423. + pr_debug("MBC (MCEI %u/%s): " fmt, \
  13424. + (mbc)->id.mcei, dect_mbc_states[(mbc)->state], ## args);
  13425. +
  13426. +static const char * const dect_mbc_states[] = {
  13427. + [DECT_MBC_NONE] = "NONE",
  13428. + [DECT_MBC_INITIATED] = "INITIATED",
  13429. + [DECT_MBC_ESTABLISHED] = "ESTABLISHED",
  13430. + [DECT_MBC_RELEASED] = "RELEASED",
  13431. +};
  13432. +
  13433. +static void dect_mbc_hold(struct dect_mbc *mbc)
  13434. +{
  13435. + mbc->refcnt++;
  13436. +}
  13437. +
  13438. +static void dect_mbc_put(struct dect_mbc *mbc)
  13439. +{
  13440. + if (--mbc->refcnt > 0)
  13441. + return;
  13442. + kfree(mbc);
  13443. +}
  13444. +
  13445. +static struct dect_tb *dect_mbc_tb_get_by_tbei(const struct dect_mbc *mbc,
  13446. + const struct dect_tbc_id *id)
  13447. +{
  13448. + struct dect_tb *tb;
  13449. +
  13450. + list_for_each_entry(tb, &mbc->tbs, list) {
  13451. + if (tb->id.tbei == id->tbei)
  13452. + return tb;
  13453. + }
  13454. + return NULL;
  13455. +}
  13456. +
  13457. +static struct dect_mbc *dect_mbc_get_by_tbc_id(const struct dect_cluster *cl,
  13458. + const struct dect_tbc_id *id)
  13459. +{
  13460. + struct dect_mbc *mbc;
  13461. +
  13462. + list_for_each_entry(mbc, &cl->mbcs, list) {
  13463. + if (!memcmp(&mbc->id.ari, &id->ari, sizeof(id->ari)) &&
  13464. + !memcmp(&mbc->id.pmid, &id->pmid, sizeof(id->pmid)) &&
  13465. + mbc->id.ecn == id->ecn)
  13466. + return mbc;
  13467. + }
  13468. + return NULL;
  13469. +}
  13470. +
  13471. +static struct dect_mbc *dect_mbc_get_by_mcei(const struct dect_cluster *cl, u32 mcei)
  13472. +{
  13473. + struct dect_mbc *mbc;
  13474. +
  13475. + list_for_each_entry(mbc, &cl->mbcs, list) {
  13476. + if (mbc->id.mcei == mcei)
  13477. + return mbc;
  13478. + }
  13479. + return NULL;
  13480. +}
  13481. +
  13482. +u32 dect_mbc_alloc_mcei(struct dect_cluster *cl)
  13483. +{
  13484. + u32 mcei;
  13485. +
  13486. + while (1) {
  13487. + mcei = ++cl->mcei_rover;
  13488. + if (mcei == 0)
  13489. + continue;
  13490. + if (dect_mbc_get_by_mcei(cl, mcei))
  13491. + continue;
  13492. + return mcei;
  13493. + }
  13494. +}
  13495. +
  13496. +static bool dect_ct_tail_allowed(const struct dect_cluster *cl, u8 framenum)
  13497. +{
  13498. + if (cl->mode == DECT_MODE_FP)
  13499. + return (framenum & 0x1) == 0x1;
  13500. + else
  13501. + return (framenum & 0x1) == 0x0;
  13502. +}
  13503. +
  13504. +/*
  13505. + * MBC normal receive half frame timer:
  13506. + *
  13507. + * Deliver received data segments to the DLC at half frame boundaries.
  13508. + * Data is delivered for the following channels:
  13509. + *
  13510. + * - C_S after an ARQ window
  13511. + * - I_N normal delay
  13512. + *
  13513. + * Additionally in half frames that end an ARQ window, acknowledgment
  13514. + * of C_S segment reception of the preceeding transmit half frame is
  13515. + * verified.
  13516. + */
  13517. +static void dect_mbc_normal_rx_timer(struct dect_cluster *cl, void *data)
  13518. +{
  13519. + struct dect_mbc *mbc = data;
  13520. + struct dect_tb *tb;
  13521. + struct sk_buff *skb;
  13522. +
  13523. + mbc_debug(mbc, "Normal RX timer\n");
  13524. + dect_mbc_hold(mbc);
  13525. +
  13526. + if (mbc->cs_rx_skb != NULL) {
  13527. + skb = mbc->cs_rx_skb;
  13528. + mbc->cs_rx_skb = NULL;
  13529. + mbc->stats.cs_rx_bytes += skb->len;
  13530. + dect_mac_co_data_ind(cl, mbc->id.mcei, DECT_MC_C_S, skb);
  13531. +
  13532. + /* C-channel reception might trigger release of the MBC in case
  13533. + * it acknowledges the last outstanding LAPC I-frame. */
  13534. + if (mbc->state == DECT_MBC_RELEASED)
  13535. + goto out;
  13536. + }
  13537. +
  13538. + if (mbc->cs_tx_ok && mbc->cs_rx_ok) {
  13539. + mbc->stats.cs_tx_bytes += mbc->cs_tx_skb->len;
  13540. + kfree_skb(mbc->cs_tx_skb);
  13541. + mbc->cs_tx_skb = NULL;
  13542. + mbc->cs_tx_ok = false;
  13543. + }
  13544. + mbc->cs_rx_ok = false;
  13545. +
  13546. + list_for_each_entry(tb, &mbc->tbs, list) {
  13547. + if (tb->b_rx_skb == NULL)
  13548. + continue;
  13549. + skb = tb->b_rx_skb;
  13550. + tb->b_rx_skb = NULL;
  13551. + mbc->stats.i_rx_bytes += skb->len;
  13552. + dect_mac_co_data_ind(cl, mbc->id.mcei, DECT_MC_I_N, skb);
  13553. + }
  13554. +
  13555. + dect_timer_add(cl, &mbc->normal_rx_timer, DECT_TIMER_RX,
  13556. + 1, dect_normal_receive_end(cl->mode));
  13557. +out:
  13558. + dect_mbc_put(mbc);
  13559. +}
  13560. +
  13561. +/*
  13562. + * MBC slot based receive timer:
  13563. + *
  13564. + * Deliver received I_N minimal delay B-field segments to the DLC.
  13565. + */
  13566. +static void dect_mbc_slot_rx_timer(struct dect_cluster *cl, void *data)
  13567. +{
  13568. + struct dect_tb *tb = data;
  13569. + struct dect_mbc *mbc = tb->mbc;
  13570. + struct sk_buff *skb;
  13571. +
  13572. + mbc_debug(mbc, "Slot RX timer: TBEI: %u LBN: %u slot: %u\n",
  13573. + tb->id.tbei, tb->id.lbn, tb->rx_slot);
  13574. +
  13575. + if (tb->b_rx_skb != NULL) {
  13576. + skb = tb->b_rx_skb;
  13577. + tb->b_rx_skb = NULL;
  13578. + mbc->stats.i_rx_bytes += skb->len;
  13579. + dect_mac_co_data_ind(cl, mbc->id.mcei, DECT_MC_I_N, skb);
  13580. + }
  13581. +
  13582. + dect_timer_add(cl, &tb->slot_rx_timer, DECT_TIMER_RX, 1, tb->rx_slot);
  13583. +}
  13584. +
  13585. +/*
  13586. + * MBC normal transmit half frame timer:
  13587. + *
  13588. + * Request data from the DLC for the next frame. Data is requested for the
  13589. + * following channels:
  13590. + *
  13591. + * - C_S before an ARQ window starts
  13592. + * - I_N normal delay
  13593. + */
  13594. +static void dect_mbc_normal_tx_timer(struct dect_cluster *cl, void *data)
  13595. +{
  13596. + const struct dect_cell_handle *ch;
  13597. + struct dect_mbc *mbc = data;
  13598. + struct dect_tb *tb;
  13599. + struct sk_buff *skb;
  13600. +
  13601. + mbc_debug(mbc, "Normal TX timer\n");
  13602. +
  13603. + if (dect_ct_tail_allowed(cl, dect_framenum(cl, DECT_TIMER_TX))) {
  13604. + if (mbc->cs_tx_skb == NULL) {
  13605. + skb = dect_mac_co_dtr_ind(cl, mbc->id.mcei, DECT_MC_C_S);
  13606. + if (skb != NULL) {
  13607. + DECT_CS_CB(skb)->seq = mbc->cs_tx_seq;
  13608. + mbc->cs_tx_seq = !mbc->cs_tx_seq;
  13609. + mbc->cs_tx_skb = skb;
  13610. + }
  13611. + }
  13612. +
  13613. + if (mbc->cs_tx_skb != NULL) {
  13614. + list_for_each_entry(tb, &mbc->tbs, list) {
  13615. + skb = skb_clone(mbc->cs_tx_skb, GFP_ATOMIC);
  13616. + if (skb == NULL)
  13617. + continue;
  13618. + ch = tb->ch;
  13619. + ch->ops->tbc_data_req(ch, &tb->id, DECT_MC_C_S, skb);
  13620. + mbc->cs_tx_ok = true;
  13621. + }
  13622. + }
  13623. + }
  13624. +
  13625. + if (mbc->mcp.service != DECT_SERVICE_IN_MIN_DELAY) {
  13626. + list_for_each_entry(tb, &mbc->tbs, list) {
  13627. + ch = tb->ch;
  13628. + skb = dect_mac_co_dtr_ind(cl, mbc->id.mcei, DECT_MC_I_N);
  13629. + if (skb != NULL) {
  13630. + mbc->stats.i_tx_bytes += skb->len;
  13631. + ch->ops->tbc_data_req(ch, &tb->id, DECT_MC_I_N, skb);
  13632. + }
  13633. + }
  13634. + }
  13635. +
  13636. + dect_timer_add(cl, &mbc->normal_tx_timer, DECT_TIMER_TX,
  13637. + 1, dect_normal_transmit_base(cl->mode));
  13638. +}
  13639. +
  13640. +/*
  13641. + * MBC slot based transmit timer:
  13642. + *
  13643. + * Request data from the DLC for the I_N minimal delay channel.
  13644. + */
  13645. +static void dect_mbc_slot_tx_timer(struct dect_cluster *cl, void *data)
  13646. +{
  13647. + struct dect_tb *tb = data;
  13648. + struct dect_mbc *mbc = tb->mbc;
  13649. + const struct dect_cell_handle *ch = tb->ch;
  13650. + struct sk_buff *skb;
  13651. +
  13652. + mbc_debug(mbc, "Slot TX timer: TBEI: %u LBN: %u slot: %u\n",
  13653. + tb->id.tbei, tb->id.lbn, tb->tx_slot);
  13654. +
  13655. + skb = dect_mac_co_dtr_ind(cl, mbc->id.mcei, DECT_MC_I_N);
  13656. + if (skb != NULL) {
  13657. + mbc->stats.i_tx_bytes += skb->len;
  13658. + ch->ops->tbc_data_req(ch, &tb->id, DECT_MC_I_N, skb);
  13659. + }
  13660. + dect_timer_add(cl, &tb->slot_tx_timer, DECT_TIMER_TX, 1, tb->tx_slot);
  13661. +}
  13662. +
  13663. +static int dect_mbc_complete_setup(struct dect_cluster *cl, struct dect_mbc *mbc)
  13664. +{
  13665. + if (!del_timer(&mbc->timer))
  13666. + return 0;
  13667. +
  13668. + dect_timer_add(cl, &mbc->normal_rx_timer, DECT_TIMER_RX,
  13669. + 0, dect_normal_receive_end(cl->mode));
  13670. + dect_timer_add(cl, &mbc->normal_tx_timer, DECT_TIMER_TX,
  13671. + 0, dect_normal_transmit_base(cl->mode));
  13672. + mbc->state = DECT_MBC_ESTABLISHED;
  13673. +
  13674. + return 1;
  13675. +}
  13676. +
  13677. +static void dect_mbc_tb_release(struct dect_tb *tb);
  13678. +
  13679. +static void dect_mbc_tb_handover_timer(struct dect_cluster *cl, void *data)
  13680. +{
  13681. + struct dect_tb *tb = data, *tb1, *i;
  13682. + struct dect_mbc *mbc = tb->mbc;
  13683. +
  13684. + mbc_debug(mbc, "Handover timer: TBEI: %u LBN: %u\n",
  13685. + tb->id.tbei, tb->id.lbn);
  13686. +
  13687. + tb1 = NULL;
  13688. + list_for_each_entry(i, &mbc->tbs, list) {
  13689. + if (i->id.lbn == tb->id.lbn) {
  13690. + tb1 = i;
  13691. + break;
  13692. + }
  13693. + }
  13694. + if (tb1 == NULL)
  13695. + return;
  13696. +
  13697. + tb1->ch->ops->tbc_dis_req(tb1->ch, &tb1->id,
  13698. + DECT_REASON_BEARER_HANDOVER_COMPLETED);
  13699. + list_del(&tb1->list);
  13700. + dect_mbc_tb_release(tb1);
  13701. + mbc->stats.handovers++;
  13702. +}
  13703. +
  13704. +static void dect_mbc_tb_complete_setup(struct dect_cluster *cl, struct dect_tb *tb)
  13705. +{
  13706. + if (cl->mode == DECT_MODE_FP && tb->handover)
  13707. + dect_timer_add(cl, &tb->handover_timer, DECT_TIMER_RX,
  13708. + DECT_MBC_TB_HANDOVER_TIMEOUT, tb->rx_slot);
  13709. +
  13710. + if (tb->mbc->mcp.service == DECT_SERVICE_IN_MIN_DELAY) {
  13711. + dect_timer_add(cl, &tb->slot_rx_timer, DECT_TIMER_RX,
  13712. + 0, tb->rx_slot);
  13713. + dect_timer_add(cl, &tb->slot_tx_timer, DECT_TIMER_TX,
  13714. + 0, tb->tx_slot);
  13715. + }
  13716. +}
  13717. +
  13718. +static void dect_mbc_tb_release(struct dect_tb *tb)
  13719. +{
  13720. + dect_timer_del(&tb->handover_timer);
  13721. + dect_timer_del(&tb->slot_rx_timer);
  13722. + dect_timer_del(&tb->slot_tx_timer);
  13723. + kfree(tb);
  13724. +}
  13725. +
  13726. +static struct dect_tb *dect_mbc_tb_init(struct dect_mbc *mbc,
  13727. + const struct dect_cell_handle *ch, u8 lbn)
  13728. +{
  13729. + struct dect_tb *tb;
  13730. +
  13731. + tb = kzalloc(sizeof(*tb), GFP_ATOMIC);
  13732. + if (tb == NULL)
  13733. + return NULL;
  13734. +
  13735. + tb->mbc = mbc;
  13736. + tb->ch = ch;
  13737. + tb->id.ari = mbc->id.ari;
  13738. + tb->id.pmid = mbc->id.pmid;
  13739. + tb->id.ecn = 0;
  13740. + tb->id.lbn = lbn;
  13741. + tb->id.tbei = 0;
  13742. + tb->handover = false;
  13743. + tb->rx_slot = 0;
  13744. + tb->tx_slot = 0;
  13745. +
  13746. + dect_timer_setup(&tb->handover_timer, dect_mbc_tb_handover_timer, tb);
  13747. + dect_timer_setup(&tb->slot_rx_timer, dect_mbc_slot_rx_timer, tb);
  13748. + dect_timer_setup(&tb->slot_tx_timer, dect_mbc_slot_tx_timer, tb);
  13749. +
  13750. + return tb;
  13751. +}
  13752. +
  13753. +static void dect_mbc_release(struct dect_mbc *mbc)
  13754. +{
  13755. + struct dect_tb *tb, *next;
  13756. +
  13757. + mbc_debug(mbc, "release\n");
  13758. + mbc->state = DECT_MBC_RELEASED;
  13759. + del_timer(&mbc->timer);
  13760. + list_del(&mbc->list);
  13761. +
  13762. + dect_timer_del(&mbc->normal_rx_timer);
  13763. + dect_timer_del(&mbc->normal_tx_timer);
  13764. +
  13765. + list_for_each_entry_safe(tb, next, &mbc->tbs, list)
  13766. + dect_mbc_tb_release(tb);
  13767. +
  13768. + kfree_skb(mbc->cs_rx_skb);
  13769. + kfree_skb(mbc->cs_tx_skb);
  13770. + dect_mbc_put(mbc);
  13771. +}
  13772. +
  13773. +static void dect_mbc_timeout(unsigned long data)
  13774. +{
  13775. + struct dect_mbc *mbc = (struct dect_mbc *)data;
  13776. + struct dect_tb *tb;
  13777. + enum dect_release_reasons reason;
  13778. +
  13779. + mbc_debug(mbc, "timeout\n");
  13780. + reason = DECT_REASON_BEARER_SETUP_OR_HANDOVER_FAILED;
  13781. +
  13782. + list_for_each_entry(tb, &mbc->tbs, list)
  13783. + tb->ch->ops->tbc_dis_req(tb->ch, &tb->id, reason);
  13784. +
  13785. + if (mbc->state != DECT_MBC_NONE)
  13786. + dect_mac_dis_ind(mbc->cl, mbc->id.mcei, reason);
  13787. +
  13788. + dect_mbc_release(mbc);
  13789. +}
  13790. +
  13791. +static struct dect_mbc *dect_mbc_init(struct dect_cluster *cl,
  13792. + const struct dect_mbc_id *id)
  13793. +{
  13794. + struct dect_mbc *mbc;
  13795. +
  13796. + mbc = kzalloc(sizeof(*mbc), GFP_ATOMIC);
  13797. + if (mbc == NULL)
  13798. + return NULL;
  13799. + mbc->refcnt = 1;
  13800. + mbc->cl = cl;
  13801. + mbc->id = *id;
  13802. + mbc->state = DECT_MBC_NONE;
  13803. + mbc->ho_stamp = jiffies - DECT_MBC_HANDOVER_TIMER;
  13804. +
  13805. + INIT_LIST_HEAD(&mbc->tbs);
  13806. + dect_timer_setup(&mbc->normal_rx_timer, dect_mbc_normal_rx_timer, mbc);
  13807. + dect_timer_setup(&mbc->normal_tx_timer, dect_mbc_normal_tx_timer, mbc);
  13808. +
  13809. + mbc->cs_tx_seq = 1;
  13810. + mbc->cs_rx_seq = 1;
  13811. +
  13812. + setup_timer(&mbc->timer, dect_mbc_timeout, (unsigned long)mbc);
  13813. + list_add_tail(&mbc->list, &cl->mbcs);
  13814. + return mbc;
  13815. +}
  13816. +
  13817. +static int dect_mbc_tb_setup(struct dect_mbc *mbc, struct dect_tb *tb)
  13818. +{
  13819. + const struct dect_cell_handle *ch = tb->ch;
  13820. + int err;
  13821. +
  13822. + err = ch->ops->tbc_establish_req(ch, &tb->id, &mbc->mcp,
  13823. + tb->handover);
  13824. + if (err < 0)
  13825. + return err;
  13826. +
  13827. + mbc->setup_cnt++;
  13828. + return 0;
  13829. +}
  13830. +
  13831. +/**
  13832. + * dect_mac_con_req - request a new MAC connection
  13833. + *
  13834. + * @cl: DECT cluster
  13835. + * @id: MBC identifier
  13836. + */
  13837. +int dect_mac_con_req(struct dect_cluster *cl, const struct dect_mbc_id *id,
  13838. + const struct dect_mac_conn_params *mcp)
  13839. +{
  13840. + struct dect_cell_handle *ch;
  13841. + struct dect_mbc *mbc;
  13842. + struct dect_tb *tb;
  13843. + int err;
  13844. +
  13845. + err = -EHOSTUNREACH;
  13846. + ch = dect_cluster_get_cell_by_rpn(cl, 0);
  13847. + if (ch == NULL)
  13848. + goto err1;
  13849. +
  13850. + err = -ENOMEM;
  13851. + mbc = dect_mbc_init(cl, id);
  13852. + if (mbc == NULL)
  13853. + goto err1;
  13854. + mbc->state = DECT_MBC_INITIATED;
  13855. + mbc->mcp = *mcp;
  13856. + if (mcp->service != DECT_SERVICE_IN_MIN_DELAY ||
  13857. + mcp->slot != DECT_FULL_SLOT)
  13858. + mbc->mcp.type = DECT_MAC_CONN_ADVANCED;
  13859. + mbc_debug(mbc, "MAC_CON-req\n");
  13860. +
  13861. + tb = dect_mbc_tb_init(mbc, ch, 0xf);
  13862. + if (tb == NULL)
  13863. + goto err2;
  13864. +
  13865. + err = dect_mbc_tb_setup(mbc, tb);
  13866. + if (err < 0)
  13867. + goto err3;
  13868. +
  13869. + list_add_tail(&tb->list, &mbc->tbs);
  13870. + mod_timer(&mbc->timer, jiffies + DECT_MBC_SETUP_TIMEOUT);
  13871. + return 0;
  13872. +
  13873. +err3:
  13874. + dect_mbc_tb_release(tb);
  13875. +err2:
  13876. + dect_mbc_release(mbc);
  13877. +err1:
  13878. + return err;
  13879. +}
  13880. +
  13881. +void dect_mac_dis_req(struct dect_cluster *cl, u32 mcei)
  13882. +{
  13883. + const struct dect_cell_handle *ch;
  13884. + struct dect_mbc *mbc;
  13885. + struct dect_tb *tb;
  13886. +
  13887. + mbc = dect_mbc_get_by_mcei(cl, mcei);
  13888. + if (mbc == NULL)
  13889. + return;
  13890. + mbc_debug(mbc, "MAC_DIS-req\n");
  13891. +
  13892. + list_for_each_entry(tb, &mbc->tbs, list) {
  13893. + ch = tb->ch;
  13894. + ch->ops->tbc_dis_req(ch, &tb->id, DECT_REASON_CONNECTION_RELEASE);
  13895. + }
  13896. +
  13897. + dect_mbc_release(mbc);
  13898. +}
  13899. +
  13900. +/* TBC establishment indication from CSF */
  13901. +static int dect_tbc_establish_ind(const struct dect_cluster_handle *clh,
  13902. + const struct dect_cell_handle *ch,
  13903. + const struct dect_tbc_id *id,
  13904. + const struct dect_mac_conn_params *mcp,
  13905. + bool handover)
  13906. +{
  13907. + struct dect_cluster *cl = dect_cluster(clh);
  13908. + struct dect_mbc_id mid;
  13909. + struct dect_mbc *mbc;
  13910. + struct dect_tb *tb;
  13911. + unsigned int cnt;
  13912. + int err;
  13913. +
  13914. + mbc = dect_mbc_get_by_tbc_id(cl, id);
  13915. + if (mbc == NULL) {
  13916. + if (handover)
  13917. + return -ENOENT;
  13918. +
  13919. + mid.mcei = dect_mbc_alloc_mcei(cl);
  13920. + mid.ari = id->ari;
  13921. + mid.pmid = id->pmid;
  13922. + mid.ecn = id->ecn;
  13923. +
  13924. + err = -ENOMEM;
  13925. + mbc = dect_mbc_init(cl, &mid);
  13926. + if (mbc == NULL)
  13927. + goto err1;
  13928. + mbc->mcp = *mcp;
  13929. + } else {
  13930. + if (!handover)
  13931. + return -EEXIST;
  13932. +
  13933. + cnt = 0;
  13934. + list_for_each_entry(tb, &mbc->tbs, list) {
  13935. + if (tb->id.lbn == id->lbn)
  13936. + cnt++;
  13937. + }
  13938. + if (cnt > 1)
  13939. + return -EEXIST;
  13940. +
  13941. + if (mbc->cipher_state == DECT_CIPHER_ENABLED) {
  13942. + err = ch->ops->tbc_enc_req(ch, id, mbc->ck);
  13943. + if (err < 0)
  13944. + return err;
  13945. + }
  13946. + }
  13947. +
  13948. + mbc_debug(mbc, "TBC_ESTABLISH-ind: TBEI: %u LBN: %u H/O: %u\n",
  13949. + id->tbei, id->lbn, handover);
  13950. +
  13951. + err = -ENOMEM;
  13952. + tb = dect_mbc_tb_init(mbc, ch, id->lbn);
  13953. + if (tb == NULL)
  13954. + goto err2;
  13955. + tb->handover = handover;
  13956. +
  13957. + err = ch->ops->tbc_establish_res(ch, id);
  13958. + if (err < 0)
  13959. + goto err3;
  13960. +
  13961. + list_add_tail(&tb->list, &mbc->tbs);
  13962. + if (!handover)
  13963. + mod_timer(&mbc->timer, jiffies + DECT_MBC_SETUP_TIMEOUT);
  13964. + return 0;
  13965. +
  13966. +err3:
  13967. + dect_mbc_tb_release(tb);
  13968. +err2:
  13969. + dect_mbc_release(mbc);
  13970. +err1:
  13971. + return err;
  13972. +}
  13973. +
  13974. +static int dect_tbc_establish_cfm(const struct dect_cluster_handle *clh,
  13975. + const struct dect_tbc_id *id, bool success,
  13976. + u8 rx_slot)
  13977. +{
  13978. + struct dect_cluster *cl = dect_cluster(clh);
  13979. + const struct dect_cell_handle *ch;
  13980. + struct dect_mbc *mbc;
  13981. + struct dect_tb *tb, *i;
  13982. +
  13983. + mbc = dect_mbc_get_by_tbc_id(cl, id);
  13984. + if (mbc == NULL)
  13985. + return -ENOENT;
  13986. +
  13987. + mbc_debug(mbc, "TBC_ESTABLISH-cfm: TBEI: %u LBN: %u success: %d\n",
  13988. + id->tbei, id->lbn, success);
  13989. +
  13990. + tb = NULL;
  13991. + list_for_each_entry(i, &mbc->tbs, list) {
  13992. + if (i->id.lbn == id->lbn &&
  13993. + i->id.tbei == 0) {
  13994. + tb = i;
  13995. + break;
  13996. + }
  13997. + }
  13998. + if (tb == NULL)
  13999. + return -ENOENT;
  14000. +
  14001. + if (success) {
  14002. + tb->id.tbei = id->tbei;
  14003. + tb->rx_slot = rx_slot;
  14004. + tb->tx_slot = dect_tdd_slot(rx_slot);
  14005. +
  14006. + switch (mbc->state) {
  14007. + case DECT_MBC_NONE:
  14008. + if (!dect_mbc_complete_setup(cl, mbc))
  14009. + return 0;
  14010. + dect_mbc_tb_complete_setup(cl, tb);
  14011. +
  14012. + return dect_mac_con_ind(cl, &mbc->id, &mbc->mcp);
  14013. + case DECT_MBC_INITIATED:
  14014. + if (!dect_mbc_complete_setup(cl, mbc))
  14015. + return 0;
  14016. + dect_mbc_tb_complete_setup(cl, tb);
  14017. +
  14018. + return dect_mac_con_cfm(cl, mbc->id.mcei, &mbc->mcp);
  14019. + case DECT_MBC_ESTABLISHED:
  14020. + ch = tb->ch;
  14021. + if (mbc->cipher_state == DECT_CIPHER_ENABLED &&
  14022. + ch->ops->tbc_enc_req(ch, id, mbc->ck) < 0) {
  14023. + ch->ops->tbc_dis_req(ch, id, DECT_REASON_UNKNOWN);
  14024. + return -1;
  14025. + }
  14026. + dect_mbc_tb_complete_setup(cl, tb);
  14027. + return 0;
  14028. + default:
  14029. + return WARN_ON(-1);
  14030. + }
  14031. + } else {
  14032. + switch (mbc->state) {
  14033. + case DECT_MBC_NONE:
  14034. + dect_mbc_release(mbc);
  14035. + return 0;
  14036. + case DECT_MBC_INITIATED:
  14037. + if (mbc->setup_cnt > DECT_MBC_SETUP_MAX_ATTEMPTS ||
  14038. + dect_mbc_tb_setup(mbc, tb) < 0) {
  14039. + dect_mac_dis_ind(cl, mbc->id.mcei,
  14040. + DECT_REASON_BEARER_SETUP_OR_HANDOVER_FAILED);
  14041. + dect_mbc_release(mbc);
  14042. + }
  14043. + return 0;
  14044. + case DECT_MBC_ESTABLISHED:
  14045. + list_del(&tb->list);
  14046. + dect_mbc_tb_release(tb);
  14047. + return 0;
  14048. + default:
  14049. + return WARN_ON(-1);
  14050. + }
  14051. + }
  14052. +}
  14053. +
  14054. +static int dect_tbc_event_ind(const struct dect_cluster_handle *clh,
  14055. + const struct dect_tbc_id *id,
  14056. + enum dect_tbc_event event)
  14057. +{
  14058. + struct dect_cluster *cl = dect_cluster(clh);
  14059. + struct dect_mbc *mbc;
  14060. + struct dect_tb *tb;
  14061. +
  14062. + mbc = dect_mbc_get_by_tbc_id(cl, id);
  14063. + if (mbc == NULL)
  14064. + return -ENOENT;
  14065. + mbc_debug(mbc, "TBC_EVENT-ind: TBEI: %u LBN: %u event: %u\n",
  14066. + id->tbei, id->lbn, event);
  14067. +
  14068. + tb = dect_mbc_tb_get_by_tbei(mbc, id);
  14069. + if (tb == NULL)
  14070. + return -ENOENT;
  14071. +
  14072. + switch (event) {
  14073. + case DECT_TBC_ACK_RECEIVED:
  14074. + mbc->cs_rx_ok = true;
  14075. + return 0;
  14076. + case DECT_TBC_CIPHER_ENABLED:
  14077. + mbc->cipher_state = DECT_TBC_CIPHER_ENABLED;
  14078. + dect_mac_enc_eks_ind(cl, mbc->id.mcei, DECT_CIPHER_ENABLED);
  14079. + return 0;
  14080. + case DECT_TBC_CIPHER_DISABLED:
  14081. + mbc->cipher_state = DECT_TBC_CIPHER_DISABLED;
  14082. + dect_mac_enc_eks_ind(cl, mbc->id.mcei, DECT_CIPHER_DISABLED);
  14083. + return 0;
  14084. + default:
  14085. + return WARN_ON(-1);
  14086. + }
  14087. +}
  14088. +
  14089. +static int dect_tbc_handover_req(const struct dect_cluster_handle *clh,
  14090. + const struct dect_tbc_id *id)
  14091. +{
  14092. + struct dect_cluster *cl = dect_cluster(clh);
  14093. + struct dect_cell_handle *ch;
  14094. + struct dect_mbc *mbc;
  14095. + struct dect_tb *tb;
  14096. + unsigned int cnt;
  14097. + int err;
  14098. +
  14099. + mbc = dect_mbc_get_by_tbc_id(cl, id);
  14100. + if (mbc == NULL)
  14101. + return -ENOENT;
  14102. + mbc_debug(mbc, "TBC_HANDOVER-req: TBEI: %u LBN: %u\n",
  14103. + id->tbei, id->lbn);
  14104. +
  14105. + /* Handover already in progress or two bearers active?? */
  14106. + cnt = 0;
  14107. + list_for_each_entry(tb, &mbc->tbs, list) {
  14108. + if (tb->id.lbn != id->lbn)
  14109. + continue;
  14110. + if (tb->id.tbei == 0)
  14111. + return 0;
  14112. + cnt++;
  14113. + }
  14114. + if (cnt > 1)
  14115. + return 0;
  14116. +
  14117. + /* Handover rate-limiting */
  14118. + if (mbc->ho_tokens == 0) {
  14119. + if (time_after_eq(jiffies, mbc->ho_stamp + DECT_MBC_HANDOVER_TIMER)) {
  14120. + mbc->ho_tokens = DECT_MBC_HANDOVER_LIMIT;
  14121. + mbc->ho_stamp = jiffies;
  14122. + }
  14123. + mbc_debug(mbc, "handover: tokens: %u\n", mbc->ho_tokens);
  14124. + if (mbc->ho_tokens == 0)
  14125. + return 0;
  14126. + }
  14127. +
  14128. + ch = dect_cluster_get_cell_by_rpn(cl, 0);
  14129. + if (ch == NULL)
  14130. + return -EHOSTUNREACH;
  14131. +
  14132. + tb = dect_mbc_tb_init(mbc, ch, id->lbn);
  14133. + if (tb == NULL)
  14134. + return -ENOMEM;
  14135. + tb->handover = true;
  14136. +
  14137. + err = dect_mbc_tb_setup(mbc, tb);
  14138. + if (err < 0)
  14139. + goto err1;
  14140. +
  14141. + list_add_tail(&tb->list, &mbc->tbs);
  14142. + mbc->ho_tokens--;
  14143. + return 0;
  14144. +
  14145. +err1:
  14146. + dect_mbc_tb_release(tb);
  14147. + return err;
  14148. +}
  14149. +
  14150. +/* TBC release indication from CSF */
  14151. +static void dect_tbc_dis_ind(const struct dect_cluster_handle *clh,
  14152. + const struct dect_tbc_id *id,
  14153. + enum dect_release_reasons reason)
  14154. +{
  14155. + struct dect_cluster *cl = dect_cluster(clh);
  14156. + struct dect_mbc *mbc;
  14157. + struct dect_tb *tb;
  14158. +
  14159. + mbc = dect_mbc_get_by_tbc_id(cl, id);
  14160. + if (mbc == NULL)
  14161. + return;
  14162. + mbc_debug(mbc, "TBC_DIS-ind: TBEI: %u LBN: %u reason: %u\n",
  14163. + id->tbei, id->lbn, reason);
  14164. +
  14165. + tb = dect_mbc_tb_get_by_tbei(mbc, id);
  14166. + if (tb == NULL)
  14167. + return;
  14168. +
  14169. + list_del(&tb->list);
  14170. + dect_mbc_tb_release(tb);
  14171. + if (!list_empty(&mbc->tbs))
  14172. + return;
  14173. +
  14174. + dect_mac_dis_ind(cl, mbc->id.mcei, reason);
  14175. + dect_mbc_release(mbc);
  14176. +}
  14177. +
  14178. +/* Set Encryption key request from DLC */
  14179. +int dect_mac_enc_key_req(const struct dect_cluster *cl, u32 mcei, u64 ck)
  14180. +{
  14181. + struct dect_mbc *mbc;
  14182. + struct dect_tb *tb;
  14183. + int err;
  14184. +
  14185. + mbc = dect_mbc_get_by_mcei(cl, mcei);
  14186. + if (mbc == NULL)
  14187. + return -ENOENT;
  14188. + mbc_debug(mbc, "MAC_ENC_KEY-req: key: %016llx\n", (unsigned long long)ck);
  14189. +
  14190. + mbc->ck = ck;
  14191. + list_for_each_entry(tb, &mbc->tbs, list) {
  14192. + err = tb->ch->ops->tbc_enc_key_req(tb->ch, &tb->id, ck);
  14193. + if (err < 0)
  14194. + return err;
  14195. + }
  14196. +
  14197. + return 0;
  14198. +}
  14199. +
  14200. +/* Change encryption status requst from DLC */
  14201. +int dect_mac_enc_eks_req(const struct dect_cluster *cl, u32 mcei,
  14202. + enum dect_cipher_states status)
  14203. +{
  14204. + struct dect_mbc *mbc;
  14205. + struct dect_tb *tb;
  14206. + int err;
  14207. +
  14208. + mbc = dect_mbc_get_by_mcei(cl, mcei);
  14209. + if (mbc == NULL)
  14210. + return -ENOENT;
  14211. + mbc_debug(mbc, "MAC_ENC_EKS-req: status: %d\n", status);
  14212. +
  14213. + if (mbc->cipher_state == status)
  14214. + return 0;
  14215. +
  14216. + list_for_each_entry(tb, &mbc->tbs, list) {
  14217. + err = tb->ch->ops->tbc_enc_eks_req(tb->ch, &tb->id, status);
  14218. + if (err < 0)
  14219. + return err;
  14220. + }
  14221. + return 0;
  14222. +}
  14223. +
  14224. +static void dect_tbc_data_ind(const struct dect_cluster_handle *clh,
  14225. + const struct dect_tbc_id *id,
  14226. + enum dect_data_channels chan,
  14227. + struct sk_buff *skb)
  14228. +{
  14229. + const struct dect_cluster *cl = dect_cluster(clh);
  14230. + struct dect_mbc *mbc;
  14231. + struct dect_tb *tb;
  14232. +
  14233. + mbc = dect_mbc_get_by_tbc_id(cl, id);
  14234. + if (mbc == NULL)
  14235. + goto err;
  14236. + mbc_debug(mbc, "TBC_DATA-ind: TBEI: %u LBN: %u chan: %u len: %u\n",
  14237. + id->tbei, id->lbn, chan, skb->len);
  14238. +
  14239. + switch (chan) {
  14240. + case DECT_MC_C_S:
  14241. + /* Drop duplicate segments */
  14242. + if (DECT_CS_CB(skb)->seq != mbc->cs_rx_seq)
  14243. + goto err;
  14244. + if (mbc->cs_rx_skb != NULL)
  14245. + goto err;
  14246. + mbc->cs_rx_seq = !mbc->cs_rx_seq;
  14247. + mbc->cs_rx_skb = skb;
  14248. + return;
  14249. + case DECT_MC_I_N:
  14250. + tb = dect_mbc_tb_get_by_tbei(mbc, id);
  14251. + if (tb == NULL)
  14252. + goto err;
  14253. + tb->b_rx_skb = skb;
  14254. + return;
  14255. + default:
  14256. + break;
  14257. + }
  14258. +err:
  14259. + kfree_skb(skb);
  14260. +}
  14261. +
  14262. +static void dect_cluster_unbind_cell(struct dect_cluster_handle *clh,
  14263. + struct dect_cell_handle *ch)
  14264. +{
  14265. + list_del(&ch->list);
  14266. +}
  14267. +
  14268. +static int dect_cluster_enable_cell(struct dect_cluster *cl,
  14269. + struct dect_cell_handle *ch)
  14270. +{
  14271. + int err;
  14272. +
  14273. + err = ch->ops->preload(ch, &cl->pari, ch->rpn, &cl->si);
  14274. + if (err < 0)
  14275. + return err;
  14276. +
  14277. + err = ch->ops->enable(ch);
  14278. + if (err < 0)
  14279. + return err;
  14280. + return 0;
  14281. +}
  14282. +
  14283. +static int dect_cluster_bind_cell(struct dect_cluster_handle *clh,
  14284. + struct dect_cell_handle *ch)
  14285. +{
  14286. + struct dect_cluster *cl = dect_cluster(clh);
  14287. + u8 rpn, max;
  14288. + int err;
  14289. +
  14290. + /* Allocate RPN for the cell */
  14291. + max = 8;
  14292. + for (rpn = 0; rpn < max; rpn++) {
  14293. + if (!dect_cluster_get_cell_by_rpn(cl, rpn))
  14294. + break;
  14295. + }
  14296. + if (rpn == max)
  14297. + return -EMFILE;
  14298. +
  14299. + ch->clh = clh;
  14300. + ch->rpn = rpn;
  14301. +
  14302. + err = ch->ops->set_mode(ch, cl->mode);
  14303. + if (err < 0)
  14304. + return err;
  14305. +
  14306. + err = dect_cluster_enable_cell(cl, ch);
  14307. + if (err < 0)
  14308. + return err;
  14309. +
  14310. + list_add_tail(&ch->list, &cl->cells);
  14311. + return 0;
  14312. +}
  14313. +
  14314. +static const struct dect_ccf_ops dect_ccf_ops = {
  14315. + .bind = dect_cluster_bind_cell,
  14316. + .unbind = dect_cluster_unbind_cell,
  14317. + .time_ind = dect_ccf_time_ind,
  14318. + .scan_report = dect_scan_report,
  14319. + .mac_info_ind = dect_mac_info_ind,
  14320. + .tbc_establish_ind = dect_tbc_establish_ind,
  14321. + .tbc_establish_cfm = dect_tbc_establish_cfm,
  14322. + .tbc_event_ind = dect_tbc_event_ind,
  14323. + .tbc_handover_req = dect_tbc_handover_req,
  14324. + .tbc_dis_ind = dect_tbc_dis_ind,
  14325. + .tbc_data_ind = dect_tbc_data_ind,
  14326. + .bmc_page_ind = dect_bmc_page_ind,
  14327. +};
  14328. +
  14329. +static int dect_cluster_preload(struct dect_cluster *cl,
  14330. + const struct dect_ari *pari,
  14331. + const struct dect_si *si)
  14332. +{
  14333. + const struct dect_cell_handle *ch;
  14334. + int err = 0;
  14335. +
  14336. + list_for_each_entry(ch, &cl->cells, list) {
  14337. + err = ch->ops->preload(ch, pari, ch->rpn, si);
  14338. + if (err < 0)
  14339. + return err;
  14340. + }
  14341. +
  14342. + cl->pari = *pari;
  14343. + cl->si = *si;
  14344. + return 0;
  14345. +}
  14346. +
  14347. +static int dect_cluster_scan(struct dect_cluster *cl,
  14348. + const struct dect_llme_req *lreq,
  14349. + const struct dect_ari *pari,
  14350. + const struct dect_ari *pari_mask)
  14351. +{
  14352. + struct dect_cell_handle *ch;
  14353. +
  14354. + ch = dect_cluster_get_cell_by_rpn(cl, 0);
  14355. + if (ch == NULL)
  14356. + return -ENOENT;
  14357. + return ch->ops->scan(ch, lreq, pari, pari_mask);
  14358. +}
  14359. +
  14360. +static void dect_fp_init_si(struct dect_cluster *cl)
  14361. +{
  14362. + struct dect_si *si = &cl->si;
  14363. +
  14364. + /* Make phone not go into "call technician" mode :) */
  14365. + si->fpc.fpc = DECT_FPC_FULL_SLOT |
  14366. + DECT_FPC_CO_SETUP_ON_DUMMY |
  14367. + DECT_FPC_CL_UPLINK |
  14368. + DECT_FPC_CL_DOWNLINK |
  14369. + DECT_FPC_BASIC_A_FIELD_SETUP |
  14370. + DECT_FPC_ADV_A_FIELD_SETUP |
  14371. + DECT_FPC_CF_MESSAGES |
  14372. + DECT_FPC_IN_MIN_DELAY |
  14373. + DECT_FPC_IN_NORM_DELAY |
  14374. + DECT_FPC_IP_ERROR_DETECTION |
  14375. + DECT_FPC_IP_ERROR_CORRECTION |
  14376. + DECT_FPC_EXTENDED_FP_INFO;
  14377. + si->efpc.fpc = DECT_EFPC_EXTENDED_FP_INFO2;
  14378. + si->efpc2.fpc = DECT_EFPC2_LONG_SLOT_J640;
  14379. + si->fpc.hlc = DECT_HLC_ADPCM_G721_VOICE |
  14380. + DECT_HLC_GAP_PAP_BASIC_SPEECH |
  14381. + DECT_HLC_CISS_SERVICE |
  14382. + DECT_HLC_CLMS_SERVICE |
  14383. + DECT_HLC_COMS_SERVICE |
  14384. + DECT_HLC_LOCATION_REGISTRATION |
  14385. + DECT_HLC_ACCESS_RIGHTS_REQUESTS |
  14386. + DECT_HLC_STANDARD_AUTHENTICATION |
  14387. + DECT_HLC_STANDARD_CIPHERING;
  14388. +}
  14389. +
  14390. +static int dect_cluster_init(struct dect_cluster *cl)
  14391. +{
  14392. + spin_lock_init(&cl->lock);
  14393. + INIT_LIST_HEAD(&cl->bmc.bcs);
  14394. + INIT_LIST_HEAD(&cl->mbcs);
  14395. + INIT_LIST_HEAD(&cl->cells);
  14396. + INIT_LIST_HEAD(&cl->mac_connections);
  14397. + dect_timer_base_init(cl->timer_base, DECT_TIMER_TX);
  14398. + dect_timer_base_init(cl->timer_base, DECT_TIMER_RX);
  14399. +
  14400. + if (cl->mode == DECT_MODE_FP)
  14401. + dect_fp_init_si(cl);
  14402. +
  14403. + cl->handle.ops = &dect_ccf_ops;
  14404. + cl->handle.index = cl->index;
  14405. +
  14406. + return dect_ccp_cluster_init(cl);
  14407. +}
  14408. +
  14409. +static void dect_cluster_shutdown(struct dect_cluster *cl)
  14410. +{
  14411. + struct dect_cell_handle *ch, *ch_next;
  14412. + struct dect_mbc *mbc, *mbc_next;
  14413. +
  14414. + list_for_each_entry_safe(mbc, mbc_next, &cl->mbcs, list) {
  14415. + dect_mac_dis_ind(cl, mbc->id.mcei, DECT_REASON_UNKNOWN);
  14416. + dect_mbc_release(mbc);
  14417. + }
  14418. +
  14419. + list_for_each_entry_safe(ch, ch_next, &cl->cells, list)
  14420. + dect_cluster_unbind_cell(&cl->handle, ch);
  14421. +
  14422. + dect_ccp_cluster_shutdown(cl);
  14423. +}
  14424. +
  14425. +/*
  14426. + * LLME netlink interface
  14427. + */
  14428. +
  14429. +static struct sk_buff *dect_llme_fill(const struct dect_cluster *cl,
  14430. + const struct dect_llme_req *lreq,
  14431. + u8 op, u8 type,
  14432. + int (*fill)(const struct dect_cluster *,
  14433. + struct sk_buff *, const void *),
  14434. + const void *data);
  14435. +
  14436. +static void dect_llme_req_init(struct dect_llme_req *lreq,
  14437. + const struct nlmsghdr *nlh,
  14438. + const struct sk_buff *skb)
  14439. +{
  14440. + memcpy(&lreq->nlh, nlh, sizeof(lreq->nlh));
  14441. + lreq->nlportid = NETLINK_CB(skb).portid;
  14442. +}
  14443. +
  14444. +static int dect_fill_ari(struct sk_buff *skb, const struct dect_ari *ari, int attr)
  14445. +{
  14446. + struct nlattr *nla;
  14447. +
  14448. + nla = nla_nest_start(skb, attr);
  14449. + if (nla == NULL)
  14450. + goto nla_put_failure;
  14451. +
  14452. + if (nla_put_u8(skb, DECTA_ARI_CLASS, ari->arc) ||
  14453. + nla_put_u32(skb, DECTA_ARI_FPN, ari->fpn))
  14454. + goto nla_put_failure;
  14455. +
  14456. + switch (ari->arc) {
  14457. + case DECT_ARC_A:
  14458. + if (nla_put_u16(skb, DECTA_ARI_EMC, ari->emc))
  14459. + goto nla_put_failure;
  14460. + break;
  14461. + case DECT_ARC_B:
  14462. + if (nla_put_u16(skb, DECTA_ARI_EIC, ari->eic) ||
  14463. + nla_put_u32(skb, DECTA_ARI_FPS, ari->fps))
  14464. + goto nla_put_failure;
  14465. + break;
  14466. + case DECT_ARC_C:
  14467. + if (nla_put_u16(skb, DECTA_ARI_POC, ari->poc) ||
  14468. + nla_put_u32(skb, DECTA_ARI_FPS, ari->fps))
  14469. + goto nla_put_failure;
  14470. + break;
  14471. + case DECT_ARC_D:
  14472. + if (nla_put_u32(skb, DECTA_ARI_GOP, ari->gop))
  14473. + goto nla_put_failure;
  14474. + break;
  14475. + case DECT_ARC_E:
  14476. + if (nla_put_u16(skb, DECTA_ARI_FIL, ari->fil))
  14477. + goto nla_put_failure;
  14478. + break;
  14479. + }
  14480. + nla_nest_end(skb, nla);
  14481. + return 0;
  14482. +
  14483. +nla_put_failure:
  14484. + return -1;
  14485. +}
  14486. +
  14487. +static const struct nla_policy dect_ari_policy[DECTA_ARI_MAX + 1] = {
  14488. + [DECTA_ARI_CLASS] = { .type = NLA_U8 },
  14489. + [DECTA_ARI_FPN] = { .type = NLA_U32 },
  14490. + [DECTA_ARI_FPS] = { .type = NLA_U32 },
  14491. + [DECTA_ARI_EMC] = { .type = NLA_U16 },
  14492. + [DECTA_ARI_EIC] = { .type = NLA_U16 },
  14493. + [DECTA_ARI_POC] = { .type = NLA_U16 },
  14494. + [DECTA_ARI_GOP] = { .type = NLA_U32 },
  14495. + [DECTA_ARI_FIL] = { .type = NLA_U32 },
  14496. +};
  14497. +
  14498. +static const u32 dect_ari_valid_attrs[] = {
  14499. + [DECT_ARC_A] = (1 << DECTA_ARI_EMC),
  14500. + [DECT_ARC_B] = (1 << DECTA_ARI_EIC) | (1 << DECTA_ARI_FPS),
  14501. + [DECT_ARC_C] = (1 << DECTA_ARI_POC) | (1 << DECTA_ARI_FPS),
  14502. + [DECT_ARC_D] = (1 << DECTA_ARI_GOP),
  14503. + [DECT_ARC_E] = (1 << DECTA_ARI_FIL),
  14504. +};
  14505. +
  14506. +static int dect_nla_parse_ari(struct dect_ari *ari, const struct nlattr *nla)
  14507. +{
  14508. + struct nlattr *tb[DECTA_ARI_MAX + 1];
  14509. + unsigned int attr;
  14510. + int err;
  14511. +
  14512. + err = nla_parse_nested(tb, DECTA_ARI_MAX, nla, dect_ari_policy);
  14513. + if (err < 0)
  14514. + return err;
  14515. +
  14516. + if (tb[DECTA_ARI_CLASS] == NULL)
  14517. + return -EINVAL;
  14518. +
  14519. + memset(ari, 0, sizeof(ari));
  14520. + ari->arc = nla_get_u8(tb[DECTA_ARI_CLASS]);
  14521. + if (ari->arc > DECT_ARC_E)
  14522. + return -EINVAL;
  14523. +
  14524. + for (attr = DECTA_ARI_UNSPEC + 1; attr <= DECTA_ARI_MAX; attr++) {
  14525. + if (tb[attr] == NULL)
  14526. + continue;
  14527. +
  14528. + switch (attr) {
  14529. + case DECTA_ARI_CLASS:
  14530. + case DECTA_ARI_FPN:
  14531. + /* always valid */
  14532. + break;
  14533. + default:
  14534. + if (!(dect_ari_valid_attrs[ari->arc] & (1 << attr)))
  14535. + return -EINVAL;
  14536. + break;
  14537. + }
  14538. + }
  14539. +
  14540. + if (tb[DECTA_ARI_FPN] != NULL)
  14541. + ari->fpn = nla_get_u32(tb[DECTA_ARI_FPN]);
  14542. + if (tb[DECTA_ARI_FPS] != NULL)
  14543. + ari->fps = nla_get_u32(tb[DECTA_ARI_FPS]);
  14544. +
  14545. + switch (ari->arc) {
  14546. + case DECT_ARC_A:
  14547. + if (tb[DECTA_ARI_EMC] != NULL)
  14548. + ari->emc = nla_get_u16(tb[DECTA_ARI_EMC]);
  14549. + break;
  14550. + case DECT_ARC_B:
  14551. + if (tb[DECTA_ARI_EIC] != NULL)
  14552. + ari->eic = nla_get_u16(tb[DECTA_ARI_EIC]);
  14553. + break;
  14554. + case DECT_ARC_C:
  14555. + if (tb[DECTA_ARI_POC] != NULL)
  14556. + ari->poc = nla_get_u16(tb[DECTA_ARI_POC]);
  14557. + break;
  14558. + case DECT_ARC_D:
  14559. + if (tb[DECTA_ARI_GOP] != NULL)
  14560. + ari->gop = nla_get_u32(tb[DECTA_ARI_GOP]);
  14561. + break;
  14562. + case DECT_ARC_E:
  14563. + if (tb[DECTA_ARI_FIL] != NULL)
  14564. + ari->fil = nla_get_u16(tb[DECTA_ARI_FIL]);
  14565. + break;
  14566. + }
  14567. + return 0;
  14568. +}
  14569. +
  14570. +static int dect_fill_sari(struct sk_buff *skb, const struct dect_sari *sari,
  14571. + int attr)
  14572. +{
  14573. + struct nlattr *nla;
  14574. +
  14575. + nla = nla_nest_start(skb, attr);
  14576. + if (nla == NULL)
  14577. + goto nla_put_failure;
  14578. + if (dect_fill_ari(skb, &sari->ari, DECTA_SARI_ARI) < 0)
  14579. + goto nla_put_failure;
  14580. + if (sari->black &&
  14581. + nla_put_flag(skb, DECTA_SARI_BLACK))
  14582. + goto nla_put_failure;
  14583. + if (sari->tari &&
  14584. + nla_put_flag(skb, DECTA_SARI_TARI))
  14585. + goto nla_put_failure;
  14586. + nla_nest_end(skb, nla);
  14587. + return 0;
  14588. +
  14589. +nla_put_failure:
  14590. + return -1;
  14591. +}
  14592. +
  14593. +static int dect_llme_fill_mac_info(const struct dect_cluster *cl,
  14594. + struct sk_buff *skb, const void *data)
  14595. +{
  14596. + const struct dect_si *si = data;
  14597. + struct nlattr *nla;
  14598. + unsigned int i;
  14599. +
  14600. + if (si->mask & (1 << DECT_TM_TYPE_SARI) && si->num_saris > 0) {
  14601. + nla = nla_nest_start(skb, DECTA_MAC_INFO_SARI_LIST);
  14602. + if (nla == NULL)
  14603. + goto nla_put_failure;
  14604. + for (i = 0; i < si->num_saris; i++) {
  14605. + if (dect_fill_sari(skb, &si->sari[i],
  14606. + DECTA_LIST_ELEM) < 0)
  14607. + goto nla_put_failure;
  14608. + }
  14609. + nla_nest_end(skb, nla);
  14610. + }
  14611. +
  14612. + if (nla_put_u8(skb, DECTA_MAC_INFO_RPN, cl->rpn))
  14613. + goto nla_put_failure;
  14614. +
  14615. + if (si->mask & (1 << DECT_TM_TYPE_FPC)) {
  14616. + if (nla_put_u32(skb, DECTA_MAC_INFO_FPC, si->fpc.fpc) ||
  14617. + nla_put_u16(skb, DECTA_MAC_INFO_HLC, si->fpc.hlc))
  14618. + goto nla_put_failure;
  14619. + }
  14620. +
  14621. + if (si->mask & (1 << DECT_TM_TYPE_EFPC)) {
  14622. + if (nla_put_u16(skb, DECTA_MAC_INFO_EFPC, si->efpc.fpc) ||
  14623. + nla_put_u32(skb, DECTA_MAC_INFO_EHLC, si->efpc.hlc))
  14624. + goto nla_put_failure;
  14625. + }
  14626. +
  14627. + if (si->mask & (1 << DECT_TM_TYPE_EFPC2)) {
  14628. + if (nla_put_u16(skb, DECTA_MAC_INFO_EFPC2, si->efpc2.fpc) ||
  14629. + nla_put_u32(skb, DECTA_MAC_INFO_EHLC2, si->efpc2.hlc))
  14630. + goto nla_put_failure;
  14631. + }
  14632. +
  14633. + return 0;
  14634. +
  14635. +nla_put_failure:
  14636. + return -EMSGSIZE;
  14637. +}
  14638. +
  14639. +static int dect_llme_fill_scan_result(const struct dect_cluster *cl,
  14640. + struct sk_buff *skb, const void *data)
  14641. +{
  14642. + const struct dect_scan_result *res = data;
  14643. + const struct dect_idi *idi = &res->idi;
  14644. + const struct dect_si *si = &res->si;
  14645. +
  14646. + if (nla_put_u8(skb, DECTA_MAC_INFO_RSSI,
  14647. + res->rssi >> DECT_RSSI_AVG_SCALE) ||
  14648. + dect_fill_ari(skb, &idi->pari, DECTA_MAC_INFO_PARI) < 0 ||
  14649. + nla_put_u8(skb, DECTA_MAC_INFO_RPN, idi->rpn))
  14650. + goto nla_put_failure;
  14651. +
  14652. + dect_llme_fill_mac_info(cl, skb, si);
  14653. + return 0;
  14654. +
  14655. +nla_put_failure:
  14656. + return -EMSGSIZE;
  14657. +}
  14658. +
  14659. +static void dect_llme_scan_result_notify(const struct dect_cluster *cl,
  14660. + const struct dect_scan_result *res)
  14661. +{
  14662. + struct sk_buff *skb;
  14663. + u32 portid = res->lreq.nlportid;
  14664. + int err = 0;
  14665. +
  14666. + skb = dect_llme_fill(cl, &res->lreq,
  14667. + DECT_LLME_INDICATE, DECT_LLME_MAC_INFO,
  14668. + dect_llme_fill_scan_result, res);
  14669. + if (IS_ERR(skb)) {
  14670. + err = PTR_ERR(skb);
  14671. + goto err;
  14672. + }
  14673. + nlmsg_notify(dect_nlsk, skb, portid, DECTNLGRP_LLME, 1, GFP_ATOMIC);
  14674. +err:
  14675. + if (err < 0)
  14676. + netlink_set_err(dect_nlsk, portid, DECTNLGRP_LLME, err);
  14677. +}
  14678. +
  14679. +static void dect_llme_mac_info_ind(const struct dect_cluster *cl,
  14680. + const struct dect_idi *idi,
  14681. + const struct dect_si *si)
  14682. +{
  14683. + struct sk_buff *skb;
  14684. + int err = 0;
  14685. +
  14686. + skb = dect_llme_fill(cl, NULL,
  14687. + DECT_LLME_INDICATE, DECT_LLME_MAC_INFO,
  14688. + dect_llme_fill_mac_info, si);
  14689. + if (IS_ERR(skb)) {
  14690. + err = PTR_ERR(skb);
  14691. + goto err;
  14692. + }
  14693. + nlmsg_notify(dect_nlsk, skb, 0, DECTNLGRP_LLME, 0, GFP_ATOMIC);
  14694. +err:
  14695. + if (err < 0)
  14696. + netlink_set_err(dect_nlsk, 0, DECTNLGRP_LLME, err);
  14697. +}
  14698. +
  14699. +static int dect_llme_mac_info_req(struct dect_cluster *cl,
  14700. + const struct sk_buff *skb_in,
  14701. + const struct nlmsghdr *nlh,
  14702. + const struct nlattr *tb[DECTA_MAC_INFO_MAX + 1])
  14703. +{
  14704. + struct dect_llme_req lreq;
  14705. + struct sk_buff *skb;
  14706. +
  14707. + dect_llme_req_init(&lreq, nlh, skb_in);
  14708. + skb = dect_llme_fill(cl, &lreq,
  14709. + DECT_LLME_INDICATE, DECT_LLME_MAC_INFO,
  14710. + dect_llme_fill_mac_info, &cl->si);
  14711. + if (IS_ERR(skb))
  14712. + return PTR_ERR(skb);
  14713. +
  14714. + return nlmsg_unicast(dect_nlsk, skb, lreq.nlportid);
  14715. +}
  14716. +
  14717. +static int dect_llme_mac_info_res(struct dect_cluster *cl,
  14718. + const struct sk_buff *skb_in,
  14719. + const struct nlmsghdr *nlh,
  14720. + const struct nlattr *tb[DECTA_MAC_INFO_MAX + 1])
  14721. +{
  14722. + struct dect_cell_handle *ch;
  14723. + struct dect_ari pari;
  14724. + int err;
  14725. +
  14726. + if (cl->mode != DECT_MODE_PP)
  14727. + return -EOPNOTSUPP;
  14728. +
  14729. + if (tb[DECTA_MAC_INFO_PARI] != NULL) {
  14730. + err = dect_nla_parse_ari(&pari, tb[DECTA_MAC_INFO_PARI]);
  14731. + if (err < 0)
  14732. + return err;
  14733. + } else
  14734. + return -EINVAL;
  14735. +
  14736. + ch = dect_cluster_get_cell_by_rpn(cl, 0);
  14737. + if (ch == NULL)
  14738. + return -EHOSTUNREACH;
  14739. +
  14740. + cl->pari = pari;
  14741. + memset(&cl->si, 0, sizeof(cl->si));
  14742. +
  14743. + return dect_cluster_enable_cell(cl, ch);
  14744. +}
  14745. +
  14746. +static const struct nla_policy dect_llme_mac_info_policy[DECTA_MAC_INFO_MAX + 1] = {
  14747. + [DECTA_MAC_INFO_PARI] = { .type = NLA_NESTED },
  14748. + [DECTA_MAC_INFO_RPN] = { .type = NLA_U8 },
  14749. + [DECTA_MAC_INFO_RSSI] = { .type = NLA_U8 },
  14750. + [DECTA_MAC_INFO_SARI_LIST] = { .type = NLA_NESTED },
  14751. + [DECTA_MAC_INFO_FPC] = { .type = NLA_U32 },
  14752. + [DECTA_MAC_INFO_HLC] = { .type = NLA_U16 },
  14753. + [DECTA_MAC_INFO_EFPC] = { .type = NLA_U16 },
  14754. + [DECTA_MAC_INFO_EHLC] = { .type = NLA_U32 },
  14755. + [DECTA_MAC_INFO_EFPC2] = { .type = NLA_U16 },
  14756. + [DECTA_MAC_INFO_EHLC2] = { .type = NLA_U32 },
  14757. +};
  14758. +
  14759. +static int dect_llme_scan_request(struct dect_cluster *cl,
  14760. + const struct sk_buff *skb,
  14761. + const struct nlmsghdr *nlh,
  14762. + const struct nlattr *tb[DECTA_MAC_INFO_MAX + 1])
  14763. +{
  14764. + struct dect_llme_req lreq;
  14765. + struct dect_ari pari, pari_mask;
  14766. + int err;
  14767. +
  14768. + if (tb[DECTA_MAC_INFO_PARI] != NULL) {
  14769. + err = dect_nla_parse_ari(&pari, tb[DECTA_MAC_INFO_PARI]);
  14770. + if (err < 0)
  14771. + return err;
  14772. + } else
  14773. + memset(&pari, 0, sizeof(pari));
  14774. + memset(&pari_mask, 0, sizeof(pari_mask));
  14775. +
  14776. + dect_llme_req_init(&lreq, nlh, skb);
  14777. + return dect_cluster_scan(cl, &lreq, &pari, &pari_mask);
  14778. +}
  14779. +
  14780. +static int dect_llme_mac_rfp_preload(struct dect_cluster *cl,
  14781. + const struct sk_buff *skb,
  14782. + const struct nlmsghdr *nlh,
  14783. + const struct nlattr *tb[DECTA_MAC_INFO_MAX + 1])
  14784. +{
  14785. + struct dect_ari pari;
  14786. + struct dect_si si;
  14787. + int err = 0;
  14788. + u32 num;
  14789. +
  14790. + if (cl->mode != DECT_MODE_FP)
  14791. + return -EINVAL;
  14792. +
  14793. + if (tb[DECTA_MAC_INFO_PARI] != NULL) {
  14794. + err = dect_nla_parse_ari(&pari, tb[DECTA_MAC_INFO_PARI]);
  14795. + if (err < 0)
  14796. + return err;
  14797. + } else
  14798. + pari = cl->pari;
  14799. +
  14800. + si = cl->si;
  14801. + if (tb[DECTA_MAC_INFO_HLC])
  14802. + si.fpc.hlc = nla_get_u16(tb[DECTA_MAC_INFO_HLC]);
  14803. + if (tb[DECTA_MAC_INFO_EHLC])
  14804. + si.efpc.hlc = nla_get_u32(tb[DECTA_MAC_INFO_EHLC]);
  14805. + if (tb[DECTA_MAC_INFO_EHLC2])
  14806. + si.efpc2.hlc = nla_get_u32(tb[DECTA_MAC_INFO_EHLC2]);
  14807. +
  14808. + if (si.efpc2.fpc || si.efpc2.hlc)
  14809. + si.efpc.fpc |= DECT_EFPC_EXTENDED_FP_INFO2;
  14810. + else
  14811. + si.efpc.fpc &= ~DECT_EFPC_EXTENDED_FP_INFO2;
  14812. +
  14813. + if (si.efpc.fpc || si.efpc.hlc)
  14814. + si.fpc.fpc |= DECT_FPC_EXTENDED_FP_INFO;
  14815. + else
  14816. + si.fpc.fpc &= ~DECT_FPC_EXTENDED_FP_INFO;
  14817. +
  14818. + if (tb[DECTA_MAC_INFO_MFN]) {
  14819. + num = nla_get_u32(tb[DECTA_MAC_INFO_MFN]);
  14820. + if (num >= (1 << 24))
  14821. + return -EINVAL;
  14822. + si.mfn.num = num;
  14823. + }
  14824. +
  14825. + return dect_cluster_preload(cl, &pari, &si);
  14826. +}
  14827. +
  14828. +static struct sk_buff *dect_llme_fill(const struct dect_cluster *cl,
  14829. + const struct dect_llme_req *lreq,
  14830. + u8 op, u8 type,
  14831. + int (*fill)(const struct dect_cluster *,
  14832. + struct sk_buff *, const void *),
  14833. + const void *data)
  14834. +{
  14835. + struct sk_buff *skb;
  14836. + struct nlmsghdr *nlh;
  14837. + struct dectmsg *dm;
  14838. + struct nlattr *nest;
  14839. + u32 seq = lreq ? lreq->nlh.nlmsg_seq : 0;
  14840. + int err = -ENOBUFS;
  14841. +
  14842. + skb = nlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC);
  14843. + if (skb == NULL)
  14844. + goto err1;
  14845. +
  14846. + nlh = nlmsg_put(skb, 0, seq, DECT_LLME_MSG, sizeof(*dm), NLMSG_DONE);
  14847. + if (nlh == NULL) {
  14848. + err = -EMSGSIZE;
  14849. + goto err2;
  14850. + }
  14851. +
  14852. + dm = nlmsg_data(nlh);
  14853. + dm->dm_index = cl->index;
  14854. +
  14855. + if (nla_put_u8(skb, DECTA_LLME_OP, op) ||
  14856. + nla_put_u8(skb, DECTA_LLME_TYPE, type))
  14857. + goto nla_put_failure;
  14858. +
  14859. + nest = nla_nest_start(skb, DECTA_LLME_DATA);
  14860. + if (nest == NULL)
  14861. + goto nla_put_failure;
  14862. + if (fill(cl, skb, data) < 0)
  14863. + goto nla_put_failure;
  14864. + nla_nest_end(skb, nest);
  14865. +
  14866. + nlmsg_end(skb, nlh);
  14867. + return skb;
  14868. +
  14869. +nla_put_failure:
  14870. +err2:
  14871. + kfree_skb(skb);
  14872. +err1:
  14873. + return ERR_PTR(err);
  14874. +}
  14875. +
  14876. +static const struct dect_llme_link {
  14877. + struct {
  14878. + int (*doit)(struct dect_cluster *cl, const struct sk_buff *,
  14879. + const struct nlmsghdr *, const struct nlattr *[]);
  14880. + } ops[DECT_LLME_MAX + 1];
  14881. + const struct nla_policy *policy;
  14882. + unsigned int maxtype;
  14883. +} dect_llme_dispatch[DECT_LLME_MAX + 1] = {
  14884. + [DECT_LLME_SCAN] = {
  14885. + .policy = dect_llme_mac_info_policy,
  14886. + .maxtype = DECTA_MAC_INFO_MAX,
  14887. + .ops = {
  14888. + [DECT_LLME_REQUEST].doit = dect_llme_scan_request,
  14889. + },
  14890. + },
  14891. + [DECT_LLME_MAC_INFO] = {
  14892. + .policy = dect_llme_mac_info_policy,
  14893. + .maxtype = DECTA_MAC_INFO_MAX,
  14894. + .ops = {
  14895. + [DECT_LLME_REQUEST].doit = dect_llme_mac_info_req,
  14896. + [DECT_LLME_RESPONSE].doit = dect_llme_mac_info_res,
  14897. + },
  14898. + },
  14899. + [DECT_LLME_MAC_RFP_PRELOAD] = {
  14900. + .policy = dect_llme_mac_info_policy,
  14901. + .maxtype = DECTA_MAC_INFO_MAX,
  14902. + .ops = {
  14903. + [DECT_LLME_REQUEST].doit = dect_llme_mac_rfp_preload,
  14904. + },
  14905. + },
  14906. +};
  14907. +
  14908. +static const struct nla_policy dect_llme_policy[DECTA_LLME_MAX + 1] = {
  14909. + [DECTA_LLME_OP] = { .type = NLA_U8 },
  14910. + [DECTA_LLME_TYPE] = { .type = NLA_U8 },
  14911. + [DECTA_LLME_DATA] = { .type = NLA_NESTED },
  14912. +};
  14913. +
  14914. +static int dect_llme_msg(const struct sk_buff *skb,
  14915. + const struct nlmsghdr *nlh,
  14916. + const struct nlattr *tb[DECTA_LLME_MAX + 1])
  14917. +{
  14918. + const struct dect_llme_link *link;
  14919. + struct dect_cluster *cl;
  14920. + struct dectmsg *dm;
  14921. + enum dect_llme_msg_types type;
  14922. + enum dect_llme_ops op;
  14923. + int err;
  14924. +
  14925. + if (tb[DECTA_LLME_OP] == NULL ||
  14926. + tb[DECTA_LLME_TYPE] == NULL ||
  14927. + tb[DECTA_LLME_DATA] == NULL)
  14928. + return -EINVAL;
  14929. +
  14930. + dm = nlmsg_data(nlh);
  14931. + cl = dect_cluster_get_by_index(dm->dm_index);
  14932. + if (cl == NULL)
  14933. + return -ENODEV;
  14934. +
  14935. + type = nla_get_u8(tb[DECTA_LLME_TYPE]);
  14936. + if (type > DECT_LLME_MAX)
  14937. + return -EINVAL;
  14938. + link = &dect_llme_dispatch[type];
  14939. +
  14940. + op = nla_get_u8(tb[DECTA_LLME_OP]);
  14941. + switch (op) {
  14942. + case DECT_LLME_REQUEST:
  14943. + case DECT_LLME_INDICATE:
  14944. + case DECT_LLME_RESPONSE:
  14945. + case DECT_LLME_CONFIRM:
  14946. + if (link->ops[op].doit == NULL)
  14947. + return -EOPNOTSUPP;
  14948. + break;
  14949. + default:
  14950. + return -EINVAL;
  14951. + }
  14952. +
  14953. + if (1) {
  14954. + struct nlattr *nla[link->maxtype + 1];
  14955. +
  14956. + err = nla_parse_nested(nla, link->maxtype, tb[DECTA_LLME_DATA],
  14957. + link->policy);
  14958. + if (err < 0)
  14959. + return err;
  14960. + return link->ops[op].doit(cl, skb, nlh,
  14961. + (const struct nlattr **)nla);
  14962. + }
  14963. +}
  14964. +
  14965. +/*
  14966. + * Cluster netlink interface
  14967. + */
  14968. +
  14969. +static int dect_cluster_alloc_index(void)
  14970. +{
  14971. + static int index;
  14972. +
  14973. + for (;;) {
  14974. + if (++index <= 0)
  14975. + index = 1;
  14976. + if (!dect_cluster_get_by_index(index))
  14977. + return index;
  14978. + }
  14979. +}
  14980. +
  14981. +static int dect_fill_tb(struct sk_buff *skb, const struct dect_tb *tb)
  14982. +{
  14983. + struct nlattr *nest;
  14984. +
  14985. + nest = nla_nest_start(skb, DECTA_LIST_ELEM);
  14986. + if (nest == NULL)
  14987. + goto nla_put_failure;
  14988. + if (nla_put_u8(skb, DECTA_MBC_TB_LBN, tb->id.lbn) ||
  14989. + nla_put_u8(skb, DECTA_MBC_TB_ECN, tb->id.ecn) ||
  14990. + nla_put_u8(skb, DECTA_MBC_TB_CELL, tb->ch->rpn) ||
  14991. + nla_put_u8(skb, DECTA_MBC_TB_RX_SLOT, tb->rx_slot) ||
  14992. + nla_put_u8(skb, DECTA_MBC_TB_TX_SLOT, tb->tx_slot))
  14993. + goto nla_put_failure;
  14994. + nla_nest_end(skb, nest);
  14995. + return 0;
  14996. +
  14997. +nla_put_failure:
  14998. + return -EMSGSIZE;
  14999. +}
  15000. +
  15001. +static int dect_fill_mbc(struct sk_buff *skb, const struct dect_mbc *mbc)
  15002. +{
  15003. + struct nlattr *nest, *stats, *tbs;
  15004. + struct dect_tb *tb;
  15005. + int err;
  15006. +
  15007. + nest = nla_nest_start(skb, DECTA_LIST_ELEM);
  15008. + if (nest == NULL)
  15009. + goto nla_put_failure;
  15010. + if (nla_put_u32(skb, DECTA_MBC_MCEI, mbc->id.mcei) ||
  15011. + nla_put_u8(skb, DECTA_MBC_SERVICE, mbc->mcp.service) ||
  15012. + nla_put_u8(skb, DECTA_MBC_STATE, mbc->state) ||
  15013. + nla_put_u8(skb, DECTA_MBC_CIPHER_STATE, mbc->cipher_state))
  15014. + goto nla_put_failure;
  15015. +
  15016. + stats = nla_nest_start(skb, DECTA_MBC_STATS);
  15017. + if (stats == NULL)
  15018. + goto nla_put_failure;
  15019. + if (nla_put_u32(skb, DECTA_MBC_STATS_CS_RX_BYTES,
  15020. + mbc->stats.cs_rx_bytes) ||
  15021. + nla_put_u32(skb, DECTA_MBC_STATS_CS_TX_BYTES,
  15022. + mbc->stats.cs_tx_bytes) ||
  15023. + nla_put_u32(skb, DECTA_MBC_STATS_I_RX_BYTES,
  15024. + mbc->stats.i_rx_bytes) ||
  15025. + nla_put_u32(skb, DECTA_MBC_STATS_I_TX_BYTES,
  15026. + mbc->stats.i_tx_bytes) ||
  15027. + nla_put_u32(skb, DECTA_MBC_STATS_HANDOVERS,
  15028. + mbc->stats.handovers))
  15029. + goto nla_put_failure;
  15030. + nla_nest_end(skb, stats);
  15031. +
  15032. + tbs = nla_nest_start(skb, DECTA_MBC_TBS);
  15033. + if (tbs == NULL)
  15034. + goto nla_put_failure;
  15035. + list_for_each_entry(tb, &mbc->tbs, list) {
  15036. + err = dect_fill_tb(skb, tb);
  15037. + if (err < 0)
  15038. + goto nla_put_failure;
  15039. + }
  15040. + nla_nest_end(skb, tbs);
  15041. + nla_nest_end(skb, nest);
  15042. + return 0;
  15043. +
  15044. +nla_put_failure:
  15045. + return -EMSGSIZE;
  15046. +}
  15047. +
  15048. +static int dect_fill_cluster(struct sk_buff *skb,
  15049. + const struct dect_cluster *cl,
  15050. + u16 type, u32 portid, u32 seq, u16 flags)
  15051. +{
  15052. + struct nlmsghdr *nlh;
  15053. + struct dectmsg *dm;
  15054. + struct nlattr *nest;
  15055. + struct dect_cell_handle *ch;
  15056. + struct dect_mbc *mbc;
  15057. +
  15058. + nlh = nlmsg_put(skb, portid, seq, type, sizeof(*dm), flags);
  15059. + if (nlh == NULL)
  15060. + return -EMSGSIZE;
  15061. +
  15062. + dm = nlmsg_data(nlh);
  15063. + dm->dm_index = cl->index;
  15064. + if (nla_put_string(skb, DECTA_CLUSTER_NAME, cl->name) ||
  15065. + nla_put_u8(skb, DECTA_CLUSTER_MODE, cl->mode) ||
  15066. + dect_fill_ari(skb, &cl->pari, DECTA_CLUSTER_PARI) < 0)
  15067. + goto nla_put_failure;
  15068. +
  15069. + if (!list_empty(&cl->cells)) {
  15070. + nest = nla_nest_start(skb, DECTA_CLUSTER_CELLS);
  15071. + if (nest == NULL)
  15072. + goto nla_put_failure;
  15073. + list_for_each_entry(ch, &cl->cells, list)
  15074. + if (nla_put_u8(skb, DECTA_LIST_ELEM, ch->rpn))
  15075. + goto nla_put_failure;
  15076. + nla_nest_end(skb, nest);
  15077. + }
  15078. +
  15079. + if (!list_empty(&cl->mbcs)) {
  15080. + nest = nla_nest_start(skb, DECTA_CLUSTER_MBCS);
  15081. + if (nest == NULL)
  15082. + goto nla_put_failure;
  15083. +
  15084. + list_for_each_entry(mbc, &cl->mbcs, list)
  15085. + if (dect_fill_mbc(skb, mbc) < 0)
  15086. + goto nla_put_failure;
  15087. +
  15088. + nla_nest_end(skb, nest);
  15089. + }
  15090. +
  15091. + nlmsg_end(skb, nlh);
  15092. + return skb->len;
  15093. +
  15094. +nla_put_failure:
  15095. + nlmsg_cancel(skb, nlh);
  15096. + return -EMSGSIZE;
  15097. +}
  15098. +
  15099. +static int dect_dump_cluster(struct sk_buff *skb,
  15100. + struct netlink_callback *cb)
  15101. +{
  15102. + const struct dect_cluster *cl;
  15103. + unsigned int idx, s_idx;
  15104. +
  15105. + s_idx = cb->args[0];
  15106. + idx = 0;
  15107. + list_for_each_entry(cl, &dect_cluster_list, list) {
  15108. + if (idx < s_idx)
  15109. + goto cont;
  15110. + if (dect_fill_cluster(skb, cl, DECT_NEW_CLUSTER,
  15111. + NETLINK_CB(cb->skb).portid,
  15112. + cb->nlh->nlmsg_seq, NLM_F_MULTI) <= 0)
  15113. + break;
  15114. +cont:
  15115. + idx++;
  15116. + }
  15117. + cb->args[0] = idx;
  15118. +
  15119. + return skb->len;
  15120. +}
  15121. +
  15122. +static void dect_notify_cluster(u16 event, const struct dect_cluster *cl,
  15123. + const struct nlmsghdr *nlh, u32 portid)
  15124. +{
  15125. + struct sk_buff *skb;
  15126. + bool report = nlh ? nlmsg_report(nlh) : 0;
  15127. + u32 seq = nlh ? nlh->nlmsg_seq : 0;
  15128. + int err = -ENOBUFS;
  15129. +
  15130. + skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
  15131. + if (skb == NULL)
  15132. + goto err;
  15133. +
  15134. + err = dect_fill_cluster(skb, cl, event, portid, seq, NLMSG_DONE);
  15135. + if (err < 0) {
  15136. + WARN_ON(err == -EMSGSIZE);
  15137. + kfree_skb(skb);
  15138. + goto err;
  15139. + }
  15140. + nlmsg_notify(dect_nlsk, skb, portid, DECTNLGRP_CLUSTER, report,
  15141. + GFP_KERNEL);
  15142. +err:
  15143. + if (err < 0)
  15144. + netlink_set_err(dect_nlsk, portid, DECTNLGRP_CLUSTER, err);
  15145. +}
  15146. +
  15147. +static const struct nla_policy dect_cluster_policy[DECTA_CLUSTER_MAX + 1] = {
  15148. + [DECTA_CLUSTER_NAME] = { .type = NLA_STRING, .len = DECTNAMSIZ },
  15149. + [DECTA_CLUSTER_MODE] = { .type = NLA_U8 },
  15150. + [DECTA_CLUSTER_PARI] = { .len = NLA_NESTED },
  15151. +};
  15152. +
  15153. +static int dect_new_cluster(const struct sk_buff *skb,
  15154. + const struct nlmsghdr *nlh,
  15155. + const struct nlattr *tb[DECTA_CLUSTER_MAX + 1])
  15156. +{
  15157. + struct dect_cluster *cl;
  15158. + struct dect_ari pari;
  15159. + enum dect_cluster_modes uninitialized_var(mode);
  15160. + int err;
  15161. +
  15162. + if (tb[DECTA_CLUSTER_NAME] == NULL)
  15163. + return -EINVAL;
  15164. +
  15165. + if (tb[DECTA_CLUSTER_MODE] != NULL) {
  15166. + mode = nla_get_u8(tb[DECTA_CLUSTER_MODE]);
  15167. + switch (mode) {
  15168. + case DECT_MODE_FP:
  15169. + case DECT_MODE_PP:
  15170. + break;
  15171. + default:
  15172. + return -EINVAL;
  15173. + }
  15174. + }
  15175. +
  15176. + if (tb[DECTA_CLUSTER_PARI] != NULL) {
  15177. + err = dect_nla_parse_ari(&pari, tb[DECTA_CLUSTER_PARI]);
  15178. + if (err < 0)
  15179. + return err;
  15180. + }
  15181. +
  15182. + cl = dect_cluster_get_by_name(tb[DECTA_CLUSTER_NAME]);
  15183. + if (cl != NULL) {
  15184. + if (nlh->nlmsg_flags & NLM_F_EXCL)
  15185. + return -EEXIST;
  15186. +
  15187. + return 0;
  15188. + }
  15189. +
  15190. + if (!(nlh->nlmsg_flags & NLM_F_CREATE))
  15191. + return -ENOENT;
  15192. +
  15193. + if (tb[DECTA_CLUSTER_MODE] == NULL)
  15194. + return -EINVAL;
  15195. +
  15196. + cl = kzalloc(sizeof(*cl), GFP_KERNEL);
  15197. + if (cl == NULL)
  15198. + return -ENOMEM;
  15199. + nla_strlcpy(cl->name, tb[DECTA_CLUSTER_NAME], sizeof(cl->name));
  15200. +
  15201. + memcpy(&cl->pari, &pari, sizeof(cl->pari));
  15202. + cl->index = dect_cluster_alloc_index();
  15203. + cl->mode = mode;
  15204. +
  15205. + err = dect_cluster_init(cl);
  15206. + if (err < 0)
  15207. + goto err1;
  15208. +
  15209. + list_add_tail(&cl->list, &dect_cluster_list);
  15210. + dect_notify_cluster(DECT_NEW_CLUSTER, cl, nlh, NETLINK_CB(skb).portid);
  15211. + return 0;
  15212. +
  15213. +err1:
  15214. + kfree(cl);
  15215. + return err;
  15216. +}
  15217. +
  15218. +static int dect_del_cluster(const struct sk_buff *skb,
  15219. + const struct nlmsghdr *nlh,
  15220. + const struct nlattr *tb[DECTA_CLUSTER_MAX + 1])
  15221. +{
  15222. + struct dect_cluster *cl;
  15223. + struct dectmsg *dm;
  15224. +
  15225. + dm = nlmsg_data(nlh);
  15226. + if (dm->dm_index != 0)
  15227. + cl = dect_cluster_get_by_index(dm->dm_index);
  15228. + else if (tb[DECTA_CLUSTER_NAME] != NULL)
  15229. + cl = dect_cluster_get_by_name(tb[DECTA_CLUSTER_NAME]);
  15230. + else
  15231. + return -EINVAL;
  15232. + if (cl == NULL)
  15233. + return -ENODEV;
  15234. +
  15235. + dect_cluster_shutdown(cl);
  15236. + list_del(&cl->list);
  15237. +
  15238. + dect_notify_cluster(DECT_DEL_CLUSTER, cl, nlh, NETLINK_CB(skb).portid);
  15239. + kfree(cl);
  15240. + return 0;
  15241. +}
  15242. +
  15243. +static int dect_get_cluster(const struct sk_buff *in_skb,
  15244. + const struct nlmsghdr *nlh,
  15245. + const struct nlattr *tb[DECTA_CLUSTER_MAX + 1])
  15246. +{
  15247. + u32 portid = NETLINK_CB(in_skb).portid;
  15248. + const struct dect_cluster *cl;
  15249. + struct dectmsg *dm;
  15250. + struct sk_buff *skb;
  15251. + int err;
  15252. +
  15253. + dm = nlmsg_data(nlh);
  15254. + if (dm->dm_index != 0)
  15255. + cl = dect_cluster_get_by_index(dm->dm_index);
  15256. + else if (tb[DECTA_CLUSTER_NAME] != NULL)
  15257. + cl = dect_cluster_get_by_name(tb[DECTA_CLUSTER_NAME]);
  15258. + else
  15259. + return -EINVAL;
  15260. + if (cl == NULL)
  15261. + return -ENODEV;
  15262. +
  15263. + skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
  15264. + if (skb == NULL)
  15265. + return -ENOMEM;
  15266. + err = dect_fill_cluster(skb, cl, DECT_NEW_CLUSTER, portid,
  15267. + nlh->nlmsg_seq, NLMSG_DONE);
  15268. + if (err < 0)
  15269. + goto err1;
  15270. + return nlmsg_unicast(dect_nlsk, skb, portid);
  15271. +
  15272. +err1:
  15273. + kfree_skb(skb);
  15274. + return err;
  15275. +}
  15276. +
  15277. +static const struct dect_netlink_handler dect_cluster_handlers[] = {
  15278. + {
  15279. + /* DECT_NEW_CLUSTER */
  15280. + .policy = dect_cluster_policy,
  15281. + .maxtype = DECTA_CLUSTER_MAX,
  15282. + .doit = dect_new_cluster,
  15283. + },
  15284. + {
  15285. + /* DECT_DEL_CLUSTER */
  15286. + .policy = dect_cluster_policy,
  15287. + .maxtype = DECTA_CLUSTER_MAX,
  15288. + .doit = dect_del_cluster,
  15289. + },
  15290. + {
  15291. + /* DECT_GET_CLUSTER */
  15292. + .policy = dect_cluster_policy,
  15293. + .maxtype = DECTA_CLUSTER_MAX,
  15294. + .doit = dect_get_cluster,
  15295. + .dump = dect_dump_cluster,
  15296. + },
  15297. + {
  15298. + /* DECT_LLME_MSG */
  15299. + .policy = dect_llme_policy,
  15300. + .maxtype = DECTA_LLME_MAX,
  15301. + .doit = dect_llme_msg,
  15302. + },
  15303. +};
  15304. +
  15305. +static int __init dect_ccf_module_init(void)
  15306. +{
  15307. + int err;
  15308. +
  15309. + err = dect_bsap_module_init();
  15310. + if (err < 0)
  15311. + goto err1;
  15312. +
  15313. + err = dect_ssap_module_init();
  15314. + if (err < 0)
  15315. + goto err2;
  15316. +
  15317. + dect_netlink_register_handlers(dect_cluster_handlers, DECT_NEW_CLUSTER,
  15318. + ARRAY_SIZE(dect_cluster_handlers));
  15319. +
  15320. + return 0;
  15321. +
  15322. +err2:
  15323. + dect_bsap_module_exit();
  15324. +err1:
  15325. + return err;
  15326. +}
  15327. +
  15328. +static void __exit dect_ccf_module_exit(void)
  15329. +{
  15330. + dect_netlink_unregister_handlers(DECT_NEW_CLUSTER,
  15331. + ARRAY_SIZE(dect_cluster_handlers));
  15332. + dect_bsap_module_exit();
  15333. + dect_ssap_module_exit();
  15334. +}
  15335. +
  15336. +module_init(dect_ccf_module_init);
  15337. +module_exit(dect_ccf_module_exit);
  15338. +MODULE_LICENSE("GPL");
  15339. diff --git a/net/dect/mac_csf.c b/net/dect/mac_csf.c
  15340. new file mode 100644
  15341. index 0000000..dc98e94
  15342. --- /dev/null
  15343. +++ b/net/dect/mac_csf.c
  15344. @@ -0,0 +1,5357 @@
  15345. +/*
  15346. + * DECT MAC Cell Site Functions
  15347. + *
  15348. + * Copyright (c) 2009-2011 Patrick McHardy <[email protected]>
  15349. + *
  15350. + * This program is free software; you can redistribute it and/or modify
  15351. + * it under the terms of the GNU General Public License version 2 as
  15352. + * published by the Free Software Foundation.
  15353. + */
  15354. +
  15355. +#ifdef CONFIG_DECT_DEBUG
  15356. +#define DEBUG
  15357. +#endif
  15358. +
  15359. +#include <linux/kernel.h>
  15360. +#include <linux/module.h>
  15361. +#include <linux/init.h>
  15362. +#include <linux/list.h>
  15363. +#include <linux/skbuff.h>
  15364. +#include <linux/net.h>
  15365. +#include <linux/dect.h>
  15366. +#include <net/dect/dect.h>
  15367. +#include <net/dect/mac_csf.h>
  15368. +#include <net/dect/ccp.h>
  15369. +
  15370. +/* avoid <KERN_DEBUG> for continuation lines */
  15371. +#undef KERN_DEBUG
  15372. +#define KERN_DEBUG
  15373. +
  15374. +static void dect_notify_cell(u16 event, const struct dect_cell *cell,
  15375. + const struct nlmsghdr *nlh, u32 portid);
  15376. +static void dect_cell_schedule_page(struct dect_cell *cell, u32 mask);
  15377. +
  15378. +static const u8 dect_fp_preamble[] = { 0x55, 0x55, 0xe9, 0x8a};
  15379. +static const u8 dect_pp_preamble[] = { 0xaa, 0xaa, 0x16, 0x75};
  15380. +
  15381. +static const u8 dect_pkt_b_field_sizes[] = {
  15382. + [DECT_PACKET_P00] = 0,
  15383. + [DECT_PACKET_P32] = 40,
  15384. + [DECT_PACKET_P640j] = 80,
  15385. + [DECT_PACKET_P80] = 100,
  15386. +};
  15387. +
  15388. +static u8 dect_pkt_b_field_size(const struct dect_channel_desc *chd)
  15389. +{
  15390. + return dect_pkt_b_field_sizes[chd->pkt];
  15391. +}
  15392. +
  15393. +#define mac_debug(cell, base, fmt, args...) \
  15394. + pr_debug("%s %u.%.2u.%.2u: " fmt, \
  15395. + (base) == DECT_TIMER_TX ? "TX" : "RX", \
  15396. + cell->timer_base[(base)].mfn, cell->timer_base[(base)].framenum, \
  15397. + cell->timer_base[(base)].slot, ## args)
  15398. +
  15399. +#define rx_debug(cell, fmt, args...) \
  15400. + mac_debug(cell, DECT_TIMER_RX, fmt, ## args)
  15401. +#define tx_debug(cell, fmt, args...) \
  15402. + mac_debug(cell, DECT_TIMER_TX, fmt, ## args)
  15403. +
  15404. +static LIST_HEAD(dect_cell_list);
  15405. +
  15406. +struct dect_cell *dect_cell_get_by_index(u32 index)
  15407. +{
  15408. + struct dect_cell *cell;
  15409. +
  15410. + list_for_each_entry(cell, &dect_cell_list, list) {
  15411. + if (cell->index == index)
  15412. + return cell;
  15413. + }
  15414. + return NULL;
  15415. +}
  15416. +EXPORT_SYMBOL_GPL(dect_cell_get_by_index);
  15417. +
  15418. +static struct dect_cell *dect_cell_get_by_name(const struct nlattr *nla)
  15419. +{
  15420. + struct dect_cell *cell;
  15421. +
  15422. + list_for_each_entry(cell, &dect_cell_list, list) {
  15423. + if (!nla_strcmp(nla, cell->name))
  15424. + return cell;
  15425. + }
  15426. + return NULL;
  15427. +}
  15428. +
  15429. +static struct dect_cell *dect_cell(const struct dect_cell_handle *ch)
  15430. +{
  15431. + return container_of(ch, struct dect_cell, handle);
  15432. +}
  15433. +
  15434. +/*
  15435. + * MAC CSF layer timers
  15436. + */
  15437. +
  15438. +#if 0
  15439. +#define timer_debug(cell, base, fmt, args...) \
  15440. + mac_debug(cell, base, fmt, ## args)
  15441. +#else
  15442. +#define timer_debug(cell, base, fmt, args...)
  15443. +#endif
  15444. +
  15445. +static u8 dect_slotnum(const struct dect_cell *cell, enum dect_timer_bases b)
  15446. +{
  15447. + return __dect_slotnum(&cell->timer_base[b]);
  15448. +}
  15449. +
  15450. +static u8 dect_framenum(const struct dect_cell *cell, enum dect_timer_bases b)
  15451. +{
  15452. + return __dect_framenum(&cell->timer_base[b]);
  15453. +}
  15454. +
  15455. +static u32 dect_mfn(const struct dect_cell *cell, enum dect_timer_bases b)
  15456. +{
  15457. + return __dect_mfn(&cell->timer_base[b]);
  15458. +}
  15459. +
  15460. +/* Return whether the TX time is in the next frame relative to the RX time */
  15461. +static bool dect_tx_time_wrapped(const struct dect_cell *cell)
  15462. +{
  15463. + return dect_slotnum(cell, DECT_TIMER_TX) <
  15464. + dect_slotnum(cell, DECT_TIMER_RX);
  15465. +}
  15466. +
  15467. +/**
  15468. + * dect_timer_synchronize_framenum
  15469. + *
  15470. + * Synchronize the current frame number based on Q-channel reception.
  15471. + *
  15472. + * Q-channel information is transmitted only in frame 8 and serves as an
  15473. + * indirect indication. The TX frame number update needs to take the clock
  15474. + * difference into account.
  15475. + */
  15476. +static void dect_timer_synchronize_framenum(struct dect_cell *cell, u8 framenum)
  15477. +{
  15478. + cell->timer_base[DECT_TIMER_RX].framenum = framenum;
  15479. + if (dect_tx_time_wrapped(cell))
  15480. + framenum++;
  15481. + cell->timer_base[DECT_TIMER_TX].framenum = framenum;
  15482. +}
  15483. +
  15484. +static void dect_timer_synchronize_mfn(struct dect_cell *cell, u32 mfn)
  15485. +{
  15486. + cell->timer_base[DECT_TIMER_RX].mfn = mfn;
  15487. + cell->timer_base[DECT_TIMER_TX].mfn = mfn;
  15488. + cell->timer_sync_stamp = mfn;
  15489. +}
  15490. +
  15491. +static void dect_run_timers(struct dect_cell *cell, enum dect_timer_bases b)
  15492. +{
  15493. + __dect_run_timers(cell->name, &cell->timer_base[b]);
  15494. +}
  15495. +
  15496. +static void dect_timer_base_update(struct dect_cell *cell,
  15497. + enum dect_timer_bases b, u8 slot)
  15498. +{
  15499. + struct dect_timer_base *base = &cell->timer_base[b];
  15500. +
  15501. + base->slot = slot;
  15502. + if (base->slot == 0) {
  15503. + base->framenum = dect_next_framenum(base->framenum);
  15504. + if (base->framenum == 0)
  15505. + base->mfn = dect_next_mfn(base->mfn);
  15506. + }
  15507. + timer_debug(cell, base, "update time base\n");
  15508. +}
  15509. +
  15510. +/**
  15511. + * dect_timer_add - (re)schedule a timer
  15512. + *
  15513. + * Frame numbers are relative to the current time, slot positions are absolute.
  15514. + * A timer scheduled for (1, 2) will expire in slot 2 in the next frame.
  15515. + *
  15516. + * A frame number of zero will expire at the next occurence of the slot, which
  15517. + * can be within the same frame in case the slot is not already in the past, or
  15518. + * in the next frame in case it is.
  15519. + */
  15520. +static void dect_timer_add(struct dect_cell *cell, struct dect_timer *timer,
  15521. + enum dect_timer_bases base, u32 frame, u8 slot)
  15522. +{
  15523. + timer->cell = cell;
  15524. + __dect_timer_add(cell->name, &cell->timer_base[base], timer, frame, slot);
  15525. +}
  15526. +
  15527. +static void dect_timer_setup(struct dect_timer *timer,
  15528. + void (*func)(struct dect_cell *, void *),
  15529. + void *data)
  15530. +{
  15531. + dect_timer_init(timer);
  15532. + timer->cb.cell = func;
  15533. + timer->data = data;
  15534. +}
  15535. +
  15536. +/*
  15537. + * Basic Channel lists
  15538. + *
  15539. + * A channel list contains channel descriptions of all physical channels
  15540. + * able to carry the packet type, sorted into multiple bins based on the
  15541. + * maximum RSSI value of the TDD slot pair.
  15542. + *
  15543. + * At any time, only a single incomplete channel list exists that is updated
  15544. + * based on the RSSI measurements gathered by the individual IRC instances.
  15545. + * Once a list is complete, it is added to the list of active channel lists,
  15546. + * replacing the previous one for the same packet type, if any.
  15547. + */
  15548. +
  15549. +#if 1
  15550. +#define chl_debug(cell, chl, fmt, args...) \
  15551. + rx_debug(cell, "channel-list %s (%u): " fmt, \
  15552. + (chl)->pkt == DECT_PACKET_P00 ? "P00" : \
  15553. + (chl)->pkt == DECT_PACKET_P08 ? "P08" : \
  15554. + (chl)->pkt == DECT_PACKET_P32 ? "P32" : \
  15555. + (chl)->pkt == DECT_PACKET_P640j ? "P640j" : \
  15556. + (chl)->pkt == DECT_PACKET_P672j ? "P672j" : "?", \
  15557. + (chl)->available, ## args)
  15558. +#else
  15559. +#define chl_debug(cell, chl, fmt, args...)
  15560. +#endif
  15561. +
  15562. +static int dect_chl_schedule_update(struct dect_cell *cell,
  15563. + enum dect_packet_types pkt);
  15564. +
  15565. +static struct dect_channel_list *dect_chl_lookup(const struct dect_cell *cell,
  15566. + enum dect_packet_types pkt)
  15567. +{
  15568. + struct dect_channel_list *chl;
  15569. +
  15570. + list_for_each_entry(chl, &cell->chanlists, list) {
  15571. + if (chl->pkt == pkt)
  15572. + return chl;
  15573. + }
  15574. + return NULL;
  15575. +}
  15576. +
  15577. +static void dect_chl_timer(struct dect_cell *cell, void *data)
  15578. +{
  15579. + struct dect_channel_list *chl = data;
  15580. +
  15581. + if (dect_chl_schedule_update(cell, chl->pkt) < 0)
  15582. + dect_timer_add(cell, &chl->timer, DECT_TIMER_RX, 1, 0);
  15583. +}
  15584. +
  15585. +static void dect_chl_release(struct dect_channel_list *chl)
  15586. +{
  15587. + dect_timer_del(&chl->timer);
  15588. + kfree(chl);
  15589. +}
  15590. +
  15591. +static struct dect_channel_list *dect_chl_init(struct dect_cell *cell,
  15592. + enum dect_packet_types pkt)
  15593. +{
  15594. + struct dect_channel_list *chl;
  15595. + unsigned int entries, i;
  15596. +
  15597. + entries = DECT_CARRIER_NUM * DECT_HALF_FRAME_SIZE;
  15598. + chl = kzalloc(sizeof(*chl) + entries * sizeof(chl->entries[0]), GFP_ATOMIC);
  15599. + if (chl == NULL)
  15600. + return NULL;
  15601. + chl->pkt = pkt;
  15602. + dect_timer_setup(&chl->timer, dect_chl_timer, chl);
  15603. + for (i = 0; i < ARRAY_SIZE(chl->bins); i++)
  15604. + INIT_LIST_HEAD(&chl->bins[i]);
  15605. + for (i = 0; i < entries; i++)
  15606. + INIT_LIST_HEAD(&chl->entries[i].list);
  15607. + return chl;
  15608. +}
  15609. +
  15610. +static int dect_chl_schedule_update(struct dect_cell *cell,
  15611. + enum dect_packet_types pkt)
  15612. +{
  15613. + struct dect_channel_list *chl;
  15614. +
  15615. + list_for_each_entry(chl, &cell->chl_pending, list) {
  15616. + if (chl->pkt == pkt)
  15617. + return 0;
  15618. + }
  15619. +
  15620. + chl = dect_chl_init(cell, pkt);
  15621. + if (chl == NULL)
  15622. + return -ENOMEM;
  15623. + chl_debug(cell, chl, "schedule update\n");
  15624. + list_add_tail(&chl->list, &cell->chl_pending);
  15625. + return 0;
  15626. +}
  15627. +
  15628. +static struct dect_channel_list *dect_chl_get_pending(struct dect_cell *cell)
  15629. +{
  15630. + struct dect_channel_list *chl;
  15631. +
  15632. + if (list_empty(&cell->chl_pending))
  15633. + return NULL;
  15634. + chl = list_first_entry(&cell->chl_pending,
  15635. + struct dect_channel_list,
  15636. + list);
  15637. + list_del(&chl->list);
  15638. + return chl;
  15639. +}
  15640. +
  15641. +static void dect_chl_update(struct dect_cell *cell,
  15642. + struct dect_channel_list *chl,
  15643. + const struct dect_channel_desc *chd, u8 rssi)
  15644. +{
  15645. + struct dect_channel_list_entry *e;
  15646. + u8 slot, bin;
  15647. +
  15648. + if (rssi > dect_dbm_to_rssi(DECT_CHANNEL_LIST_MAX_DBM)) {
  15649. + chl_debug(cell, chl, "carrier %u slot %u: too much noise: RSSI %u\n",
  15650. + chd->carrier, chd->slot, rssi);
  15651. + return;
  15652. + }
  15653. +
  15654. + slot = chd->slot < 12 ? chd->slot : chd->slot - 12;
  15655. + chl_debug(cell, chl, "update carrier %u slot %u pos %u RSSI %u\n",
  15656. + chd->carrier, chd->slot, slot, rssi);
  15657. +
  15658. + e = &chl->entries[chd->carrier * DECT_HALF_FRAME_SIZE + slot];
  15659. + if (!list_empty(&e->list))
  15660. + return;
  15661. +
  15662. + if (chd->slot < DECT_HALF_FRAME_SIZE) {
  15663. + e->slot = slot;
  15664. + e->carrier = chd->carrier;
  15665. + e->rssi = rssi;
  15666. + } else if (e->rssi != 0) {
  15667. + e->rssi = max(e->rssi, rssi);
  15668. + bin = rssi * ARRAY_SIZE(chl->bins) / (DECT_RSSI_RANGE + 1);
  15669. +
  15670. + list_add_tail(&e->list, &chl->bins[bin]);
  15671. + chl->available++;
  15672. + }
  15673. +}
  15674. +
  15675. +static void dect_chl_update_carrier(struct dect_cell *cell, u8 carrier)
  15676. +{
  15677. + struct dect_channel_list *chl, *old;
  15678. +
  15679. + chl = cell->chl;
  15680. + chl_debug(cell, chl, "update status %03llx rfcars %03x carrier %u\n",
  15681. + (unsigned long long)chl->status, cell->si.ssi.rfcars, carrier);
  15682. +
  15683. + chl->status |= 1ULL << carrier;
  15684. + if (chl->status != cell->si.ssi.rfcars)
  15685. + return;
  15686. + cell->chl = NULL;
  15687. +
  15688. + chl_debug(cell, chl, "complete %u entries\n", chl->available);
  15689. + old = dect_chl_lookup(cell, chl->pkt);
  15690. + if (old != NULL) {
  15691. + list_del(&old->list);
  15692. + dect_chl_release(old);
  15693. + }
  15694. +
  15695. + dect_timer_add(cell, &chl->timer, DECT_TIMER_RX,
  15696. + DECT_CHANNEL_LIST_MAX_AGE * 2 / 3 *
  15697. + DECT_FRAMES_PER_SECOND, 0);
  15698. + list_add_tail(&chl->list, &cell->chanlists);
  15699. +}
  15700. +
  15701. +static void dect_chl_flush(struct dect_cell *cell)
  15702. +{
  15703. + struct dect_channel_list *chl, *next;
  15704. +
  15705. + list_for_each_entry_safe(chl, next, &cell->chanlists, list) {
  15706. + list_del(&chl->list);
  15707. + dect_chl_release(chl);
  15708. + }
  15709. +}
  15710. +
  15711. +/**
  15712. + * dect_channel_delay - calculate delay in frames until a channel is accessible
  15713. + *
  15714. + * Calculate the delay in frames until one of the remote sides' scans is on the
  15715. + * specified carrier.
  15716. + *
  15717. + * A FP maintains one to three scans, which lag behind each other by three
  15718. + * carriers, a PP maintains zero or one (fast-setup) scan. The PP fast-
  15719. + * setup scan leads the FP primary scan by one carrier.
  15720. + *
  15721. + * Setup needs at least one full frame, therefore a scan reaching a carrier
  15722. + * earlier than that must be treated as reachable one cycle later.
  15723. + */
  15724. +static u8 dect_channel_delay(const struct dect_cell *cell,
  15725. + const struct dect_channel_desc *chd)
  15726. +{
  15727. + u64 rfcars = cell->si.ssi.rfcars;
  15728. + u8 i, txs, scn, frames;
  15729. + s8 d;
  15730. +
  15731. + if (cell->mode == DECT_MODE_FP) {
  15732. + /* PP fast-setup scan */
  15733. + scn = dect_next_carrier(rfcars, cell->si.ssi.pscn);
  15734. + txs = 1;
  15735. + } else {
  15736. + /* FP primary scan */
  15737. + scn = dect_prev_carrier(rfcars, cell->si.ssi.pscn);
  15738. + txs = min(cell->si.ssi.txs + 1, 3);
  15739. + }
  15740. +
  15741. + frames = ~0;
  15742. + for (i = 0; i < txs; i++) {
  15743. + d = dect_carrier_distance(rfcars, scn, chd->carrier);
  15744. + /* More than two frames in the future? */
  15745. + if (d <= DECT_CHANNEL_MIN_DELAY)
  15746. + d += hweight64(rfcars);
  15747. +
  15748. + frames = min_t(u8, frames, d);
  15749. + pr_debug("rfcars %llx distance %u->%u slot %u: %u frames %u\n",
  15750. + (unsigned long long)rfcars, scn, chd->carrier,
  15751. + chd->slot, d, frames);
  15752. +
  15753. + scn = dect_carrier_sub(rfcars, scn, 3);
  15754. + }
  15755. +
  15756. + return frames;
  15757. +}
  15758. +
  15759. +static void dect_update_blind_full_slots(struct dect_cell *cell)
  15760. +{
  15761. + u16 bfs;
  15762. +
  15763. + bfs = ~(cell->trg.blind_full_slots | (cell->trg.blind_full_slots >> 12));
  15764. + cell->trg_blind_full_slots = bfs & ((1 << DECT_HALF_FRAME_SIZE) - 1);
  15765. +
  15766. + dect_cell_schedule_page(cell, 1 << DECT_TM_TYPE_BFS);
  15767. +}
  15768. +
  15769. +/**
  15770. + * dect_channel_reserve - reserve a channel on a transceiver
  15771. + *
  15772. + * Reserve the specified transceiver and schedule a blind-full-slots
  15773. + * page message if the visibility state changed.
  15774. + */
  15775. +static void dect_channel_reserve(struct dect_cell *cell,
  15776. + struct dect_transceiver *trx,
  15777. + const struct dect_channel_desc *chd)
  15778. +{
  15779. + if (!dect_transceiver_reserve(&cell->trg, trx, chd))
  15780. + return;
  15781. +
  15782. + dect_update_blind_full_slots(cell);
  15783. +}
  15784. +
  15785. +/**
  15786. + * dect_channel_release - release a channel on a transceiver
  15787. + *
  15788. + * Release the specified transceiver and schedule a blind-full-slots
  15789. + * page message if the visibility state changed.
  15790. + */
  15791. +static void dect_channel_release(struct dect_cell *cell,
  15792. + struct dect_transceiver *trx,
  15793. + const struct dect_channel_desc *chd)
  15794. +{
  15795. + if (!dect_transceiver_release(&cell->trg, trx, chd))
  15796. + return;
  15797. +
  15798. + dect_update_blind_full_slots(cell);
  15799. +}
  15800. +
  15801. +/**
  15802. + * dect_select_transceiver - select a transceiver for placing a bearer
  15803. + *
  15804. + * Select the lowest order transceiver that is able to operate on a physical
  15805. + * channel.
  15806. + */
  15807. +static struct dect_transceiver *
  15808. +dect_select_transceiver(const struct dect_cell *cell,
  15809. + const struct dect_channel_desc *chd)
  15810. +{
  15811. + struct dect_transceiver *trx;
  15812. +
  15813. + dect_foreach_transceiver_reverse(trx, &cell->trg) {
  15814. + if (trx->state != DECT_TRANSCEIVER_LOCKED)
  15815. + continue;
  15816. + if (!dect_transceiver_channel_available(trx, chd))
  15817. + continue;
  15818. + return trx;
  15819. + }
  15820. + return NULL;
  15821. +}
  15822. +
  15823. +/**
  15824. + * dect_select_channel - select a physical channel for bearer setup
  15825. + *
  15826. + * @cell: DECT cell
  15827. + * @trx: selected transceiver
  15828. + * @chd: channel description
  15829. + * @rssi: last measure RSSI value of selected channel
  15830. + * @quick: prefer quickly accessible channel
  15831. + *
  15832. + * This performs the common steps of channel selection based on channel lists.
  15833. + * In "quick" mode, the selected channel is the first channel accessible within
  15834. + * three TDMA frames from the lowest three available bands. When not in quick
  15835. + * mode or when no channel is accessible within three frames, the first
  15836. + * available channel from the lowest available band is selected.
  15837. + *
  15838. + * "quick" mode is used for setting up pilot bearers and for bearer handover.
  15839. + *
  15840. + * The returned channel description is within the normal transmit half
  15841. + * of the cell's mode.
  15842. + */
  15843. +static int dect_select_channel(struct dect_cell *cell,
  15844. + struct dect_transceiver **trxp,
  15845. + struct dect_channel_desc *chd, u8 *rssi,
  15846. + bool quick)
  15847. +{
  15848. + struct dect_channel_list_entry *e, *sel;
  15849. + struct dect_channel_list *chl;
  15850. + struct dect_transceiver *trx, *uninitialized_var(tsel);
  15851. + u8 bin, first, last;
  15852. +
  15853. + chl = dect_chl_lookup(cell, chd->pkt);
  15854. + if (chl == NULL)
  15855. + return -ENOENT;
  15856. +
  15857. + /* Find first non-empty bin */
  15858. + for (first = 0; first < ARRAY_SIZE(chl->bins); first++) {
  15859. + if (!list_empty(&chl->bins[first]))
  15860. + break;
  15861. + }
  15862. + if (first == ARRAY_SIZE(chl->bins))
  15863. + return -ENOSPC;
  15864. +
  15865. + sel = NULL;
  15866. +retry:
  15867. + last = max_t(u8, first + quick ? 3 : 1, ARRAY_SIZE(chl->bins));
  15868. + for (bin = first; sel == NULL && bin < last; bin++) {
  15869. + list_for_each_entry(e, &chl->bins[bin], list) {
  15870. + u8 n = DECT_HALF_FRAME_SIZE - 1 - e->slot;
  15871. +
  15872. + if (!(cell->trg_blind_full_slots & (1 << n)))
  15873. + continue;
  15874. +
  15875. + if (cell->mode == DECT_MODE_PP &&
  15876. + !(cell->blind_full_slots & (1 << n)))
  15877. + continue;
  15878. +
  15879. + chd->carrier = e->carrier;
  15880. + chd->slot = dect_normal_transmit_base(cell->mode) + e->slot;
  15881. + if (quick && dect_channel_delay(cell, chd) > 3)
  15882. + continue;
  15883. +
  15884. + trx = dect_select_transceiver(cell, chd);
  15885. + if (trx == NULL)
  15886. + continue;
  15887. + if (sel != NULL) {
  15888. + if (trx->index < tsel->index)
  15889. + continue;
  15890. + if (sel->rssi < e->rssi)
  15891. + continue;
  15892. + }
  15893. +
  15894. + sel = e;
  15895. + tsel = trx;
  15896. +
  15897. + /* Stop searching if this is the best possible choice */
  15898. + if (tsel->index == hweight16(cell->trg.trxmask))
  15899. + break;
  15900. + }
  15901. + }
  15902. +
  15903. + if (sel == NULL) {
  15904. + /* Check the first band again without considering delay when
  15905. + * no quickly accessible channel is available within the first
  15906. + * three bands. */
  15907. + if (quick) {
  15908. + quick = false;
  15909. + goto retry;
  15910. + }
  15911. + return -ENOSPC;
  15912. + }
  15913. +
  15914. + list_del_init(&sel->list);
  15915. + chl->available--;
  15916. + if (chl->available < DECT_CHANNEL_LIST_LOW_WATERMARK)
  15917. + dect_chl_schedule_update(cell, chl->pkt);
  15918. +
  15919. + chd->carrier = sel->carrier;
  15920. + chd->slot = dect_normal_transmit_base(cell->mode) + sel->slot;
  15921. + chl_debug(cell, chl, "select channel: carrier %u slot %u RSSI %u\n",
  15922. + chd->carrier, chd->slot, sel->rssi);
  15923. +
  15924. + *rssi = sel->rssi;
  15925. + *trxp = tsel;
  15926. + return 0;
  15927. +}
  15928. +
  15929. +static struct dect_dbc *dect_dbc_get(const struct dect_cell *cell)
  15930. +{
  15931. + if (list_empty(&cell->dbcs))
  15932. + return NULL;
  15933. + return list_first_entry(&cell->dbcs, struct dect_dbc, list);
  15934. +}
  15935. +
  15936. +
  15937. +/*
  15938. + * Tail message parsing/construction
  15939. + */
  15940. +
  15941. +static enum dect_tail_identifications dect_parse_tail(const struct sk_buff *skb)
  15942. +{
  15943. + return skb->data[DECT_HDR_TA_OFF] & DECT_HDR_TA_MASK;
  15944. +}
  15945. +
  15946. +static enum dect_b_identifications dect_parse_b_id(const struct sk_buff *skb)
  15947. +{
  15948. + return skb->data[DECT_HDR_TA_OFF] & DECT_HDR_BA_MASK;
  15949. +}
  15950. +
  15951. +static int dect_parse_identities_information(struct dect_tail_msg *tm, u64 t)
  15952. +{
  15953. + struct dect_idi *idi = &tm->idi;
  15954. + u8 ari_len, rpn_len;
  15955. +
  15956. + ari_len = dect_parse_ari(&idi->pari, t << DECT_RFPI_ARI_SHIFT);
  15957. + if (ari_len == 0)
  15958. + return -1;
  15959. + rpn_len = BITS_PER_BYTE * DECT_NT_ID_RFPI_LEN - 1 - ari_len;
  15960. +
  15961. + idi->e = (t & DECT_RFPI_E_FLAG);
  15962. + idi->rpn = (t >> DECT_RFPI_RPN_SHIFT) & ((1 << rpn_len) - 1);
  15963. + tm->type = DECT_TM_TYPE_ID;
  15964. +
  15965. + pr_debug("identities information: e: %u class: %u emc: %.4x "
  15966. + "fpn: %.5x rpn: %x\n", idi->e, idi->pari.arc,
  15967. + idi->pari.emc, idi->pari.fpn, idi->rpn);
  15968. + return 0;
  15969. +}
  15970. +
  15971. +static u64 dect_build_identities_information(const struct dect_idi *idi)
  15972. +{
  15973. + return dect_build_rfpi(idi);
  15974. +}
  15975. +
  15976. +static int dect_parse_static_system_information(struct dect_tail_msg *tm, u64 t)
  15977. +{
  15978. + struct dect_ssi *ssi = &tm->ssi;
  15979. +
  15980. + ssi->nr = (t & DECT_QT_SSI_NR_FLAG);
  15981. + ssi->sn = (t & DECT_QT_SSI_SN_MASK) >> DECT_QT_SSI_SN_SHIFT;
  15982. + ssi->sp = (t & DECT_QT_SSI_SP_MASK) >> DECT_QT_SSI_SP_SHIFT;
  15983. + ssi->txs = (t & DECT_QT_SSI_TXS_MASK) >> DECT_QT_SSI_TXS_SHIFT;
  15984. + ssi->mc = (t & DECT_QT_SSI_MC_FLAG);
  15985. + ssi->rfcars = (t & DECT_QT_SSI_RFCARS_MASK) >> DECT_QT_SSI_RFCARS_SHIFT;
  15986. + ssi->cn = (t & DECT_QT_SSI_CN_MASK) >> DECT_QT_SSI_CN_SHIFT;
  15987. + ssi->pscn = (t & DECT_QT_SSI_PSCN_MASK) >> DECT_QT_SSI_PSCN_SHIFT;
  15988. +
  15989. + if (ssi->sn > 11 || ssi->cn > 9 || ssi->pscn > 9 || ssi->rfcars == 0)
  15990. + return -1;
  15991. + tm->type = DECT_TM_TYPE_SSI;
  15992. +
  15993. + pr_debug("static system information: nr: %u sn: %u cn: %u pscn: %u\n",
  15994. + ssi->nr, ssi->sn, ssi->cn, ssi->pscn);
  15995. + return 0;
  15996. +}
  15997. +
  15998. +static u64 dect_build_static_system_information(const struct dect_ssi *ssi)
  15999. +{
  16000. + u64 t = 0;
  16001. +
  16002. + t |= ssi->nr ? DECT_QT_SSI_NR_FLAG : 0;
  16003. + t |= (u64)ssi->sn << DECT_QT_SSI_SN_SHIFT;
  16004. + t |= (u64)ssi->sp << DECT_QT_SSI_SP_SHIFT;
  16005. + t |= (u64)ssi->txs << DECT_QT_SSI_TXS_SHIFT;
  16006. + t |= (u64)ssi->cn << DECT_QT_SSI_CN_SHIFT;
  16007. + t |= ssi->mc ? DECT_QT_SSI_MC_FLAG : 0;
  16008. + t |= (u64)ssi->rfcars << DECT_QT_SSI_RFCARS_SHIFT;
  16009. + t |= (u64)ssi->pscn << DECT_QT_SSI_PSCN_SHIFT;
  16010. + t |= DECT_QT_SI_SSI;
  16011. + return t;
  16012. +}
  16013. +
  16014. +static int dect_parse_extended_rf_carrier_information(struct dect_tail_msg *tm, u64 t)
  16015. +{
  16016. + struct dect_erfc *erfc = &tm->erfc;
  16017. +
  16018. + erfc->rfcars = (t & DECT_QT_ERFC_RFCARS_MASK) >>
  16019. + DECT_QT_ERFC_RFCARS_SHIFT;
  16020. + erfc->band = (t & DECT_QT_ERFC_RFBAND_MASK) >>
  16021. + DECT_QT_ERFC_RFBAND_SHIFT;
  16022. + erfc->num_rfcars = (t & DECT_QT_ERFC_NUM_RFCARS_MASK) >
  16023. + DECT_QT_ERFC_NUM_RFCARS_SHIFT;
  16024. + tm->type = DECT_TM_TYPE_ERFC;
  16025. +
  16026. + pr_debug("extended rf carrier information: rfcars %.6x band %u num %u\n",
  16027. + erfc->rfcars, erfc->band, erfc->num_rfcars);
  16028. + return 0;
  16029. +}
  16030. +
  16031. +static u64 dect_build_extended_rf_carrier_information(const struct dect_erfc *erfc)
  16032. +{
  16033. + u64 t = 0;
  16034. +
  16035. + t |= (u64)erfc->rfcars << DECT_QT_ERFC_RFCARS_SHIFT;
  16036. + t |= (u64)erfc->band << DECT_QT_ERFC_RFBAND_SHIFT;
  16037. + t |= (u64)erfc->num_rfcars << DECT_QT_ERFC_NUM_RFCARS_SHIFT;
  16038. + t |= DECT_QT_SI_ERFC;
  16039. + return t;
  16040. +}
  16041. +
  16042. +static int dect_parse_fixed_part_capabilities(struct dect_tail_msg *tm, u64 t)
  16043. +{
  16044. + struct dect_fpc *fpc = &tm->fpc;
  16045. +
  16046. + fpc->fpc = (t & DECT_QT_FPC_CAPABILITY_MASK) >>
  16047. + DECT_QT_FPC_CAPABILITY_SHIFT;
  16048. + fpc->hlc = (t & DECT_QT_FPC_HLC_MASK) >> DECT_QT_FPC_HLC_SHIFT;
  16049. + tm->type = DECT_TM_TYPE_FPC;
  16050. +
  16051. + pr_debug("fixed part capabilities: fpc: %.5x hlc: %.4x\n",
  16052. + fpc->fpc, fpc->hlc);
  16053. + return 0;
  16054. +}
  16055. +
  16056. +static u64 dect_build_fixed_part_capabilities(const struct dect_fpc *fpc)
  16057. +{
  16058. + u64 t = 0;
  16059. +
  16060. + t |= (u64)fpc->fpc << DECT_QT_FPC_CAPABILITY_SHIFT;
  16061. + t |= (u64)fpc->hlc << DECT_QT_FPC_HLC_SHIFT;
  16062. + t |= DECT_QT_SI_FPC;
  16063. + return t;
  16064. +}
  16065. +
  16066. +static int dect_parse_extended_fixed_part_capabilities(struct dect_tail_msg *tm, u64 t)
  16067. +{
  16068. + struct dect_efpc *efpc = &tm->efpc;
  16069. +
  16070. + efpc->fpc = (t & DECT_QT_EFPC_EFPC_MASK) >> DECT_QT_EFPC_EFPC_SHIFT;
  16071. + efpc->hlc = (t & DECT_QT_EFPC_EHLC_MASK) >> DECT_QT_EFPC_EHLC_SHIFT;
  16072. + tm->type = DECT_TM_TYPE_EFPC;
  16073. +
  16074. + pr_debug("extended fixed part capabilities: fpc: %.5x hlc: %.6x\n",
  16075. + efpc->fpc, efpc->hlc);
  16076. + return 0;
  16077. +}
  16078. +
  16079. +static u64 dect_build_extended_fixed_part_capabilities(const struct dect_efpc *efpc)
  16080. +{
  16081. + u64 t = 0;
  16082. +
  16083. + t |= (u64)efpc->fpc << DECT_QT_EFPC_EFPC_SHIFT;
  16084. + t |= (u64)efpc->hlc << DECT_QT_EFPC_EHLC_SHIFT;
  16085. + t |= DECT_QT_SI_EFPC;
  16086. + return t;
  16087. +}
  16088. +
  16089. +static int dect_parse_extended_fixed_part_capabilities2(struct dect_tail_msg *tm, u64 t)
  16090. +{
  16091. + struct dect_efpc2 *efpc2 = &tm->efpc2;
  16092. +
  16093. + efpc2->fpc = (t & DECT_QT_EFPC2_FPC_MASK) >> DECT_QT_EFPC2_FPC_SHIFT;
  16094. + efpc2->hlc = (t & DECT_QT_EFPC2_HLC_MASK) >> DECT_QT_EFPC2_HLC_SHIFT;
  16095. + tm->type = DECT_TM_TYPE_EFPC2;
  16096. +
  16097. + pr_debug("extended fixed part capabilities2: fpc: %x hlc: %x\n",
  16098. + efpc2->fpc, efpc2->hlc);
  16099. + return 0;
  16100. +}
  16101. +
  16102. +static u64 dect_build_extended_fixed_part_capabilities2(const struct dect_efpc2 *efpc2)
  16103. +{
  16104. + u64 t = 0;
  16105. +
  16106. + t |= (u64)efpc2->fpc << DECT_QT_EFPC2_FPC_SHIFT;
  16107. + t |= (u64)efpc2->hlc << DECT_QT_EFPC2_HLC_SHIFT;
  16108. + t |= DECT_QT_SI_EFPC2;
  16109. + return t;
  16110. +}
  16111. +
  16112. +static int dect_parse_sari(struct dect_tail_msg *tm, u64 t)
  16113. +{
  16114. + struct dect_sari *sari = &tm->sari;
  16115. +
  16116. + sari->list_cycle = (((t & DECT_QT_SARI_LIST_CYCLE_MASK) >>
  16117. + DECT_QT_SARI_LIST_CYCLE_SHIFT) + 1) * 2;
  16118. + sari->tari = (t & DECT_QT_SARI_TARI_FLAG);
  16119. + sari->black = (t & DECT_QT_SARI_BLACK_FLAG);
  16120. + dect_parse_ari(&sari->ari, t << DECT_QT_SARI_ARI_SHIFT);
  16121. + tm->type = DECT_TM_TYPE_SARI;
  16122. +
  16123. + pr_debug("sari: cycle %u tari: %u black: %u\n",
  16124. + sari->list_cycle, sari->tari, sari->black);
  16125. + return 0;
  16126. +}
  16127. +
  16128. +static u64 dect_build_sari(const struct dect_sari *sari)
  16129. +{
  16130. + u64 t = 0;
  16131. +
  16132. + t |= sari->tari ? DECT_QT_SARI_TARI_FLAG : 0;
  16133. + t |= sari->black ? DECT_QT_SARI_BLACK_FLAG : 0;
  16134. + t |= dect_build_ari(&sari->ari) >> DECT_QT_SARI_ARI_SHIFT;
  16135. + t |= DECT_QT_SI_SARI;
  16136. + return t;
  16137. +}
  16138. +
  16139. +static int dect_parse_multiframe_number(struct dect_tail_msg *tm, u64 t)
  16140. +{
  16141. + tm->mfn.num = (t & DECT_QT_MFN_MASK) >> DECT_QT_MFN_SHIFT;
  16142. + tm->type = DECT_TM_TYPE_MFN;
  16143. +
  16144. + pr_debug("multi-frame number: %u\n", tm->mfn.num);
  16145. + return 0;
  16146. +}
  16147. +
  16148. +static u64 dect_build_multiframe_number(const struct dect_mfn *mfn)
  16149. +{
  16150. + u64 t = 0;
  16151. +
  16152. + t |= (u64)mfn->num << DECT_QT_MFN_SHIFT;
  16153. + t |= DECT_QT_SI_MFN;
  16154. + return t;
  16155. +}
  16156. +
  16157. +static int dect_parse_system_information(struct dect_tail_msg *tm, u64 t)
  16158. +{
  16159. + /* clear of memcmp */
  16160. + memset(((void *)tm) + offsetof(struct dect_tail_msg, ssi), 0,
  16161. + sizeof(*tm) - offsetof(struct dect_tail_msg, ssi));
  16162. +
  16163. + switch (t & DECT_QT_H_MASK) {
  16164. + case DECT_QT_SI_SSI:
  16165. + case DECT_QT_SI_SSI2:
  16166. + return dect_parse_static_system_information(tm, t);
  16167. + case DECT_QT_SI_ERFC:
  16168. + return dect_parse_extended_rf_carrier_information(tm, t);
  16169. + case DECT_QT_SI_FPC:
  16170. + return dect_parse_fixed_part_capabilities(tm, t);
  16171. + case DECT_QT_SI_EFPC:
  16172. + return dect_parse_extended_fixed_part_capabilities(tm, t);
  16173. + case DECT_QT_SI_EFPC2:
  16174. + return dect_parse_extended_fixed_part_capabilities2(tm, t);
  16175. + case DECT_QT_SI_SARI:
  16176. + return dect_parse_sari(tm, t);
  16177. + case DECT_QT_SI_MFN:
  16178. + return dect_parse_multiframe_number(tm, t);
  16179. + default:
  16180. + pr_debug("unknown system information type %llx\n",
  16181. + (unsigned long long)t & DECT_QT_H_MASK);
  16182. + return -1;
  16183. + }
  16184. +}
  16185. +
  16186. +static int dect_parse_blind_full_slots(struct dect_tail_msg *tm, u64 t)
  16187. +{
  16188. + struct dect_bfs *bfs = &tm->bfs;
  16189. +
  16190. + bfs->mask = (t & DECT_PT_BFS_MASK) >> DECT_PT_BFS_SHIFT;
  16191. + tm->type = DECT_TM_TYPE_BFS;
  16192. +
  16193. + pr_debug("page: RFPI: %.3x blind full slots: %.3x\n",
  16194. + tm->page.rfpi, bfs->mask);
  16195. + return 0;
  16196. +}
  16197. +
  16198. +static u64 dect_build_blind_full_slots(const struct dect_bfs *bfs)
  16199. +{
  16200. + u64 t = 0;
  16201. +
  16202. + t |= (u64)bfs->mask << DECT_PT_BFS_SHIFT;
  16203. + t |= DECT_PT_IT_BLIND_FULL_SLOT;
  16204. + return t;
  16205. +}
  16206. +
  16207. +static int dect_parse_bearer_description(struct dect_tail_msg *tm, u64 t)
  16208. +{
  16209. + struct dect_bearer_desc *bd = &tm->bd;
  16210. +
  16211. + bd->bt = (t & DECT_PT_INFO_TYPE_MASK);
  16212. + bd->sn = (t & DECT_PT_BEARER_SN_MASK) >> DECT_PT_BEARER_SN_SHIFT;
  16213. + bd->sp = (t & DECT_PT_BEARER_SP_MASK) >> DECT_PT_BEARER_SP_SHIFT;
  16214. + bd->cn = (t & DECT_PT_BEARER_CN_MASK) >> DECT_PT_BEARER_CN_SHIFT;
  16215. + if (bd->sn >= DECT_HALF_FRAME_SIZE)
  16216. + return -1;
  16217. + tm->type = DECT_TM_TYPE_BD;
  16218. +
  16219. + pr_debug("page: RFPI: %.3x bearer description: bt: %llx sn: %u sp: %u cn: %u\n",
  16220. + tm->page.rfpi, (unsigned long long)bd->bt, bd->sn, bd->sp, bd->cn);
  16221. + return 0;
  16222. +}
  16223. +
  16224. +static u64 dect_build_bearer_description(const struct dect_bearer_desc *bd)
  16225. +{
  16226. + u64 t = 0;
  16227. +
  16228. + t |= (u64)bd->sn << DECT_PT_BEARER_SN_SHIFT;
  16229. + t |= (u64)bd->sp << DECT_PT_BEARER_SP_SHIFT;
  16230. + t |= (u64)bd->cn << DECT_PT_BEARER_CN_SHIFT;
  16231. + t |= bd->bt;
  16232. + return t;
  16233. +}
  16234. +
  16235. +static int dect_parse_rfp_identity(struct dect_tail_msg *tm, u64 t)
  16236. +{
  16237. + struct dect_rfp_id *id = &tm->rfp_id;
  16238. +
  16239. + id->id = (t & DECT_PT_RFP_ID_MASK) >> DECT_PT_RFP_ID_SHIFT;
  16240. + tm->type = DECT_TM_TYPE_RFP_ID;
  16241. +
  16242. + pr_debug("page: RFPI: %.3x RFP identity: %.3x\n",
  16243. + tm->page.rfpi, id->id);
  16244. + return 0;
  16245. +}
  16246. +
  16247. +static u64 dect_build_rfp_identity(const struct dect_rfp_id *id)
  16248. +{
  16249. + u64 t = 0;
  16250. +
  16251. + t |= (u64)id->id << DECT_PT_RFP_ID_SHIFT;
  16252. + t |= DECT_PT_IT_RFP_IDENTITY;
  16253. + return t;
  16254. +}
  16255. +
  16256. +static int dect_parse_rfp_status(struct dect_tail_msg *tm, u64 t)
  16257. +{
  16258. + struct dect_rfp_status *st = &tm->rfp_status;
  16259. +
  16260. + st->rfp_busy = t & DECT_PT_RFPS_RFP_BUSY_FLAG;
  16261. + st->sys_busy = t & DECT_PT_RFPS_SYS_BUSY_FLAG;
  16262. + tm->type = DECT_TM_TYPE_RFP_STATUS;
  16263. +
  16264. + pr_debug("page: RFPI: %.3x RFP status: rfp_busy: %d sys_busy: %d\n",
  16265. + tm->page.rfpi, st->rfp_busy, st->sys_busy);
  16266. + return 0;
  16267. +}
  16268. +
  16269. +static u64 dect_build_rfp_status(const struct dect_rfp_status *st)
  16270. +{
  16271. + u64 t = 0;
  16272. +
  16273. + t |= st->rfp_busy ? DECT_PT_RFPS_RFP_BUSY_FLAG : 0;
  16274. + t |= st->sys_busy ? DECT_PT_RFPS_SYS_BUSY_FLAG : 0;
  16275. + t |= DECT_PT_IT_RFP_STATUS;
  16276. + return t;
  16277. +}
  16278. +
  16279. +static int dect_parse_active_carriers(struct dect_tail_msg *tm, u64 t)
  16280. +{
  16281. + struct dect_active_carriers *ac = &tm->active_carriers;
  16282. +
  16283. + ac->active = (t & DECT_PT_ACTIVE_CARRIERS_MASK) >>
  16284. + DECT_PT_ACTIVE_CARRIERS_SHIFT;
  16285. + tm->type = DECT_TM_TYPE_ACTIVE_CARRIERS;
  16286. +
  16287. + pr_debug("page: RFPI: %.3x active carriers: %.3x\n",
  16288. + tm->page.rfpi, ac->active);
  16289. + return 0;
  16290. +}
  16291. +
  16292. +static u64 dect_build_active_carriers(const struct dect_active_carriers *ac)
  16293. +{
  16294. + u64 t = 0;
  16295. +
  16296. + t |= (u64)ac->active << DECT_PT_ACTIVE_CARRIERS_SHIFT;
  16297. + t |= DECT_PT_IT_ACTIVE_CARRIERS;
  16298. + return t;
  16299. +}
  16300. +
  16301. +static int dect_parse_paging_info(struct dect_tail_msg *tm, u64 t)
  16302. +{
  16303. + switch (t & DECT_PT_INFO_TYPE_MASK) {
  16304. + case DECT_PT_IT_BLIND_FULL_SLOT:
  16305. + return dect_parse_blind_full_slots(tm, t);
  16306. + case DECT_PT_IT_OTHER_BEARER:
  16307. + case DECT_PT_IT_RECOMMENDED_OTHER_BEARER:
  16308. + case DECT_PT_IT_GOOD_RFP_BEARER:
  16309. + case DECT_PT_IT_DUMMY_OR_CL_BEARER_POSITION:
  16310. + case DECT_PT_IT_CL_BEARER_POSITION:
  16311. + return dect_parse_bearer_description(tm, t);
  16312. + case DECT_PT_IT_RFP_IDENTITY:
  16313. + return dect_parse_rfp_identity(tm, t);
  16314. + case DECT_PT_IT_DUMMY_OR_CL_BEARER_MARKER:
  16315. + pr_debug("dummy or cl bearer marker\n");
  16316. + return 0;
  16317. + case DECT_PT_IT_RFP_STATUS:
  16318. + return dect_parse_rfp_status(tm, t);
  16319. + case DECT_PT_IT_ACTIVE_CARRIERS:
  16320. + return dect_parse_active_carriers(tm, t);
  16321. + default:
  16322. + pr_debug("unknown MAC page info %llx\n",
  16323. + (unsigned long long)t & DECT_PT_INFO_TYPE_MASK);
  16324. + return -1;
  16325. + }
  16326. +}
  16327. +
  16328. +static int dect_parse_paging_msg(struct dect_tail_msg *tm, u64 t)
  16329. +{
  16330. + tm->page.extend = t & DECT_PT_HDR_EXTEND_FLAG;
  16331. + tm->page.length = t & DECT_PT_HDR_LENGTH_MASK;
  16332. +
  16333. + switch (tm->page.length) {
  16334. + case DECT_PT_ZERO_PAGE:
  16335. + tm->page.rfpi = (t & DECT_PT_ZP_RFPI_MASK) >>
  16336. + DECT_PT_ZP_RFPI_SHIFT;
  16337. +
  16338. + return dect_parse_paging_info(tm, t);
  16339. + case DECT_PT_SHORT_PAGE:
  16340. + tm->page.rfpi = 0;
  16341. + return dect_parse_paging_info(tm, t);
  16342. + case DECT_PT_FULL_PAGE:
  16343. + case DECT_PT_LONG_PAGE:
  16344. + case DECT_PT_LONG_PAGE_FIRST:
  16345. + case DECT_PT_LONG_PAGE_LAST:
  16346. + case DECT_PT_LONG_PAGE_ALL:
  16347. + tm->type = DECT_TM_TYPE_PAGE;
  16348. + pr_debug("full/long page: extend: %u length: %llx\n",
  16349. + tm->page.extend, (unsigned long long)tm->page.length);
  16350. + return 0;
  16351. + default:
  16352. + pr_debug("invalid page length %llx\n",
  16353. + (unsigned long long)tm->page.length);
  16354. + return -1;
  16355. + }
  16356. +}
  16357. +
  16358. +static int dect_parse_cctrl_common(struct dect_cctrl *cctl, u64 t)
  16359. +{
  16360. + cctl->fmid = (t & DECT_CCTRL_FMID_MASK) >> DECT_CCTRL_FMID_SHIFT;
  16361. + cctl->pmid = (t & DECT_CCTRL_PMID_MASK) >> DECT_CCTRL_PMID_SHIFT;
  16362. +
  16363. + pr_debug("cctrl: cmd: %llx fmid: %.3x pmid: %.5x\n",
  16364. + (unsigned long long)cctl->cmd, cctl->fmid, cctl->pmid);
  16365. + return 0;
  16366. +}
  16367. +
  16368. +static u64 dect_build_cctrl_common(const struct dect_cctrl *cctl)
  16369. +{
  16370. + u64 t = 0;
  16371. +
  16372. + t |= cctl->cmd;
  16373. + t |= (u64)cctl->fmid << DECT_CCTRL_FMID_SHIFT;
  16374. + t |= (u64)cctl->pmid << DECT_CCTRL_PMID_SHIFT;
  16375. + return t;
  16376. +}
  16377. +
  16378. +static int dect_parse_cctrl_attr(struct dect_cctrl *cctl, u64 t)
  16379. +{
  16380. + cctl->attr.ecn = (t & DECT_CCTRL_ATTR_ECN_MASK) >> DECT_CCTRL_ATTR_ECN_SHIFT;
  16381. + cctl->attr.lbn = (t & DECT_CCTRL_ATTR_LBN_MASK) >> DECT_CCTRL_ATTR_LBN_SHIFT;
  16382. + cctl->attr.type = (t & DECT_CCTRL_ATTR_TYPE_MASK) >> DECT_CCTRL_ATTR_TYPE_SHIFT;
  16383. + cctl->attr.service = (t & DECT_CCTRL_ATTR_SERVICE_MASK) >> DECT_CCTRL_ATTR_SERVICE_SHIFT;
  16384. + cctl->attr.slot = (t & DECT_CCTRL_ATTR_SLOT_MASK) >> DECT_CCTRL_ATTR_SLOT_SHIFT;
  16385. + cctl->attr.cf = (t & DECT_CCTRL_ATTR_CF_FLAG);
  16386. + cctl->attr.a_mod = (t & DECT_CCTRL_ATTR_A_MOD_MASK) >> DECT_CCTRL_ATTR_A_MOD_SHIFT;
  16387. + cctl->attr.bz_mod = (t & DECT_CCTRL_ATTR_BZ_MOD_MASK) >> DECT_CCTRL_ATTR_BZ_MOD_SHIFT;
  16388. + cctl->attr.bz_ext_mod = (t & DECT_CCTRL_ATTR_BZ_EXT_MOD_MASK) >> DECT_CCTRL_ATTR_BZ_EXT_MOD_SHIFT;
  16389. + cctl->attr.acr = (t & DECT_CCTRL_ATTR_ACR_MASK) >> DECT_CCTRL_ATTR_ACR_SHIFT;
  16390. +
  16391. + pr_debug("cctrl: cmd: %llx ecn: %x lbn: %x type: %x "
  16392. + "service: %x slot: %x cf %d a_mod %x bz_mod %x bz_ext_mod %x acr %x\n",
  16393. + (unsigned long long)cctl->cmd, cctl->attr.ecn, cctl->attr.lbn,
  16394. + cctl->attr.type, cctl->attr.service, cctl->attr.slot,
  16395. + cctl->attr.cf, cctl->attr.a_mod, cctl->attr.bz_mod,
  16396. + cctl->attr.bz_ext_mod, cctl->attr.acr);
  16397. + return 0;
  16398. +}
  16399. +
  16400. +static u64 dect_build_cctrl_attr(const struct dect_cctrl *cctl)
  16401. +{
  16402. + u64 t = 0;
  16403. +
  16404. + t |= cctl->cmd;
  16405. + t |= (u64)cctl->attr.ecn << DECT_CCTRL_ATTR_ECN_SHIFT;
  16406. + t |= (u64)cctl->attr.lbn << DECT_CCTRL_ATTR_LBN_SHIFT;
  16407. + t |= (u64)cctl->attr.type << DECT_CCTRL_ATTR_TYPE_SHIFT;
  16408. + t |= (u64)cctl->attr.service << DECT_CCTRL_ATTR_SERVICE_SHIFT;
  16409. + t |= (u64)cctl->attr.slot << DECT_CCTRL_ATTR_SLOT_SHIFT;
  16410. + t |= cctl->attr.cf ? DECT_CCTRL_ATTR_CF_FLAG : 0;
  16411. + t |= (u64)cctl->attr.a_mod << DECT_CCTRL_ATTR_A_MOD_SHIFT;
  16412. + t |= (u64)cctl->attr.bz_mod << DECT_CCTRL_ATTR_BZ_MOD_SHIFT;
  16413. + t |= (u64)cctl->attr.bz_ext_mod << DECT_CCTRL_ATTR_BZ_EXT_MOD_SHIFT;
  16414. + t |= (u64)cctl->attr.acr << DECT_CCTRL_ATTR_ACR_SHIFT;
  16415. + return t;
  16416. +}
  16417. +
  16418. +static int dect_parse_cctrl_release(struct dect_cctrl *cctl, u64 t)
  16419. +{
  16420. + cctl->rel.lbn = (t & DECT_CCTRL_RELEASE_LBN_MASK) >>
  16421. + DECT_CCTRL_RELEASE_LBN_SHIFT;
  16422. + cctl->rel.reason = (t & DECT_CCTRL_RELEASE_REASON_MASK) >>
  16423. + DECT_CCTRL_RELEASE_REASON_SHIFT;
  16424. + cctl->pmid = (t & DECT_CCTRL_RELEASE_PMID_MASK) >>
  16425. + DECT_CCTRL_RELEASE_PMID_SHIFT;
  16426. +
  16427. + pr_debug("cctrl: release: pmid: %.5x lbn: %x reason: %x\n",
  16428. + cctl->pmid, cctl->rel.lbn, cctl->rel.reason);
  16429. + return 0;
  16430. +}
  16431. +
  16432. +static u64 dect_build_cctrl_release(const struct dect_cctrl *cctl)
  16433. +{
  16434. + u64 t = 0;
  16435. +
  16436. + t |= cctl->cmd;
  16437. + t |= (u64)cctl->rel.lbn << DECT_CCTRL_RELEASE_LBN_SHIFT;
  16438. + t |= (u64)cctl->rel.reason << DECT_CCTRL_RELEASE_REASON_SHIFT;
  16439. + t |= (u64)cctl->pmid << DECT_CCTRL_RELEASE_PMID_SHIFT;
  16440. + return t;
  16441. +}
  16442. +
  16443. +static int dect_parse_basic_cctrl(struct dect_tail_msg *tm, u64 t)
  16444. +{
  16445. + struct dect_cctrl *cctl = &tm->cctl;
  16446. +
  16447. + cctl->cmd = t & DECT_MT_CMD_MASK;
  16448. + switch (cctl->cmd) {
  16449. + case DECT_CCTRL_ACCESS_REQ:
  16450. + case DECT_CCTRL_BEARER_HANDOVER_REQ:
  16451. + case DECT_CCTRL_CONNECTION_HANDOVER_REQ:
  16452. + case DECT_CCTRL_UNCONFIRMED_ACCESS_REQ:
  16453. + case DECT_CCTRL_BEARER_CONFIRM:
  16454. + case DECT_CCTRL_WAIT:
  16455. + return dect_parse_cctrl_common(cctl, t);
  16456. + case DECT_CCTRL_ATTRIBUTES_T_REQUEST:
  16457. + case DECT_CCTRL_ATTRIBUTES_T_CONFIRM:
  16458. + return dect_parse_cctrl_attr(cctl, t);
  16459. + case DECT_CCTRL_RELEASE:
  16460. + return dect_parse_cctrl_release(cctl, t);
  16461. + default:
  16462. + pr_debug("unknown cctrl command: %llx\n",
  16463. + (unsigned long long)cctl->cmd);
  16464. + return -1;
  16465. + }
  16466. +}
  16467. +
  16468. +static int dect_parse_advanced_cctrl(struct dect_tail_msg *tm, u64 t)
  16469. +{
  16470. + struct dect_cctrl *cctl = &tm->cctl;
  16471. +
  16472. + cctl->cmd = t & DECT_MT_CMD_MASK;
  16473. + switch (cctl->cmd) {
  16474. + case DECT_CCTRL_UNCONFIRMED_DUMMY:
  16475. + case DECT_CCTRL_UNCONFIRMED_HANDOVER:
  16476. + return dect_parse_cctrl_common(cctl, t);
  16477. + case DECT_CCTRL_BANDWIDTH_T_REQUEST:
  16478. + case DECT_CCTRL_BANDWIDTH_T_CONFIRM:
  16479. + return -1;
  16480. + default:
  16481. + return dect_parse_basic_cctrl(tm, t);
  16482. + }
  16483. +}
  16484. +
  16485. +static int dect_parse_encryption_ctrl(struct dect_tail_msg *tm, u64 t)
  16486. +{
  16487. + struct dect_encctrl *ectl = &tm->encctl;
  16488. +
  16489. + ectl->cmd = (t & DECT_ENCCTRL_CMD_MASK) >> DECT_ENCCTRL_CMD_SHIFT;
  16490. + ectl->fmid = (t & DECT_ENCCTRL_FMID_MASK) >> DECT_ENCCTRL_FMID_SHIFT;
  16491. + ectl->pmid = (t & DECT_ENCCTRL_PMID_MASK) >> DECT_ENCCTRL_PMID_SHIFT;
  16492. + pr_debug("encctrl: cmd: %x fmid: %.4x pmid: %.5x\n",
  16493. + ectl->cmd, ectl->fmid, ectl->pmid);
  16494. + return 0;
  16495. +}
  16496. +
  16497. +static u64 dect_build_encryption_ctrl(const struct dect_encctrl *ectl)
  16498. +{
  16499. + u64 t = 0;
  16500. +
  16501. + t |= (u64)DECT_ENCCTRL_FILL_MASK;
  16502. + t |= (u64)ectl->cmd << DECT_ENCCTRL_CMD_SHIFT;
  16503. + t |= (u64)ectl->fmid << DECT_ENCCTRL_FMID_SHIFT;
  16504. + t |= (u64)ectl->pmid << DECT_ENCCTRL_PMID_SHIFT;
  16505. + return t;
  16506. +}
  16507. +
  16508. +static int dect_parse_mac_ctrl(struct dect_tail_msg *tm, u64 t)
  16509. +{
  16510. + switch (t & DECT_MT_HDR_MASK) {
  16511. + case DECT_MT_BASIC_CCTRL:
  16512. + if (dect_parse_basic_cctrl(tm, t) < 0)
  16513. + return -1;
  16514. + tm->type = DECT_TM_TYPE_BCCTRL;
  16515. + return 0;
  16516. + case DECT_MT_ADV_CCTRL:
  16517. + if (dect_parse_advanced_cctrl(tm, t) < 0)
  16518. + return -1;
  16519. + tm->type = DECT_TM_TYPE_ACCTRL;
  16520. + return 0;
  16521. + case DECT_MT_ENC_CTRL:
  16522. + if (dect_parse_encryption_ctrl(tm, t) < 0)
  16523. + return -1;
  16524. + tm->type = DECT_TM_TYPE_ENCCTRL;
  16525. + return 0;
  16526. + default:
  16527. + pr_debug("Unknown MAC control %llx\n",
  16528. + (unsigned long long)t & DECT_MT_HDR_MASK);
  16529. + return -1;
  16530. + }
  16531. +}
  16532. +
  16533. +static u64 dect_build_cctrl(const struct dect_cctrl *cctl)
  16534. +{
  16535. + switch (cctl->cmd) {
  16536. + case DECT_CCTRL_ACCESS_REQ:
  16537. + case DECT_CCTRL_BEARER_HANDOVER_REQ:
  16538. + case DECT_CCTRL_CONNECTION_HANDOVER_REQ:
  16539. + case DECT_CCTRL_UNCONFIRMED_ACCESS_REQ:
  16540. + case DECT_CCTRL_BEARER_CONFIRM:
  16541. + case DECT_CCTRL_WAIT:
  16542. + case DECT_CCTRL_UNCONFIRMED_DUMMY:
  16543. + case DECT_CCTRL_UNCONFIRMED_HANDOVER:
  16544. + return dect_build_cctrl_common(cctl);
  16545. + case DECT_CCTRL_ATTRIBUTES_T_REQUEST:
  16546. + case DECT_CCTRL_ATTRIBUTES_T_CONFIRM:
  16547. + return dect_build_cctrl_attr(cctl);
  16548. + case DECT_CCTRL_BANDWIDTH_T_REQUEST:
  16549. + case DECT_CCTRL_BANDWIDTH_T_CONFIRM:
  16550. + case DECT_CCTRL_CHANNEL_LIST:
  16551. + return 0;
  16552. + case DECT_CCTRL_RELEASE:
  16553. + return dect_build_cctrl_release(cctl);
  16554. + default:
  16555. + return 0;
  16556. + }
  16557. +}
  16558. +
  16559. +static int dect_parse_ct_data(struct dect_tail_msg *tm, u64 t, u8 seq)
  16560. +{
  16561. + struct dect_ct_data *ctd = &tm->ctd;
  16562. +
  16563. + ctd->seq = seq;
  16564. + tm->type = DECT_TM_TYPE_CT;
  16565. + pr_debug("C_S tail sequence number %u\n", seq);
  16566. + return 0;
  16567. +}
  16568. +
  16569. +static int dect_parse_tail_msg(struct dect_tail_msg *tm,
  16570. + const struct sk_buff *skb)
  16571. +{
  16572. + u64 t;
  16573. +
  16574. + tm->type = DECT_TM_TYPE_INVALID;
  16575. + WARN_ON_ONCE(!IS_ALIGNED((unsigned long)skb->data, __alignof__(u64)));
  16576. + t = be64_to_cpu(*(__be64 *)skb->data);
  16577. +
  16578. + switch (dect_parse_tail(skb)) {
  16579. + case DECT_TI_CT_PKT_0:
  16580. + return dect_parse_ct_data(tm, t, 0);
  16581. + case DECT_TI_CT_PKT_1:
  16582. + return dect_parse_ct_data(tm, t, 1);
  16583. + case DECT_TI_NT_CL:
  16584. + pr_debug("connectionless: ");
  16585. + case DECT_TI_NT:
  16586. + return dect_parse_identities_information(tm, t);
  16587. + case DECT_TI_QT:
  16588. + return dect_parse_system_information(tm, t);
  16589. + case DECT_TI_PT:
  16590. + /* Paging tail in direction FP->PP, MAC control otherwise */
  16591. + if (DECT_TRX_CB(skb)->slot < 12)
  16592. + return dect_parse_paging_msg(tm, t);
  16593. + case DECT_TI_MT:
  16594. + return dect_parse_mac_ctrl(tm, t);
  16595. + default:
  16596. + pr_debug("unknown tail %x\n", dect_parse_tail(skb));
  16597. + return -1;
  16598. + }
  16599. +}
  16600. +
  16601. +static struct sk_buff *dect_build_tail_msg(struct sk_buff *skb,
  16602. + enum dect_tail_msg_types type,
  16603. + const void *data)
  16604. +{
  16605. + enum dect_tail_identifications ti;
  16606. + unsigned int i;
  16607. + u64 t;
  16608. +
  16609. + switch (type) {
  16610. + case DECT_TM_TYPE_ID:
  16611. + t = dect_build_identities_information(data);
  16612. + ti = DECT_TI_NT;
  16613. + break;
  16614. + case DECT_TM_TYPE_SSI:
  16615. + t = dect_build_static_system_information(data);
  16616. + ti = DECT_TI_QT;
  16617. + break;
  16618. + case DECT_TM_TYPE_ERFC:
  16619. + t = dect_build_extended_rf_carrier_information(data);
  16620. + ti = DECT_TI_QT;
  16621. + break;
  16622. + case DECT_TM_TYPE_FPC:
  16623. + t = dect_build_fixed_part_capabilities(data);
  16624. + ti = DECT_TI_QT;
  16625. + break;
  16626. + case DECT_TM_TYPE_EFPC:
  16627. + t = dect_build_extended_fixed_part_capabilities(data);
  16628. + ti = DECT_TI_QT;
  16629. + break;
  16630. + case DECT_TM_TYPE_EFPC2:
  16631. + t = dect_build_extended_fixed_part_capabilities2(data);
  16632. + ti = DECT_TI_QT;
  16633. + break;
  16634. + case DECT_TM_TYPE_SARI:
  16635. + t = dect_build_sari(data);
  16636. + ti = DECT_TI_QT;
  16637. + break;
  16638. + case DECT_TM_TYPE_MFN:
  16639. + t = dect_build_multiframe_number(data);
  16640. + ti = DECT_TI_QT;
  16641. + break;
  16642. + case DECT_TM_TYPE_BCCTRL:
  16643. + t = dect_build_cctrl(data) | DECT_MT_BASIC_CCTRL;
  16644. + ti = DECT_TI_MT;
  16645. + break;
  16646. + case DECT_TM_TYPE_ACCTRL:
  16647. + t = dect_build_cctrl(data) | DECT_MT_ADV_CCTRL;
  16648. + ti = DECT_TI_MT;
  16649. + break;
  16650. + case DECT_TM_TYPE_ENCCTRL:
  16651. + t = dect_build_encryption_ctrl(data);
  16652. + ti = DECT_TI_MT;
  16653. + break;
  16654. + default:
  16655. + BUG();
  16656. + }
  16657. +
  16658. + skb_put(skb, DECT_T_FIELD_SIZE);
  16659. + for (i = 0; i < DECT_T_FIELD_SIZE; i++)
  16660. + skb->data[i] = t >> ((sizeof(t) - i - 2) * BITS_PER_BYTE);
  16661. +
  16662. + DECT_A_CB(skb)->id = ti;
  16663. + return skb;
  16664. +}
  16665. +
  16666. +/**
  16667. + * dect_t_skb_alloc - allocate a socket buffer for the T-Field
  16668. + *
  16669. + */
  16670. +static struct sk_buff *dect_t_skb_alloc(void)
  16671. +{
  16672. + struct sk_buff *skb;
  16673. +
  16674. + skb = alloc_skb(DECT_PREAMBLE_SIZE + DECT_A_FIELD_SIZE, GFP_ATOMIC);
  16675. + if (skb == NULL)
  16676. + return NULL;
  16677. +
  16678. + /* Reserve space for preamble */
  16679. + skb_reset_mac_header(skb);
  16680. + skb_reserve(skb, DECT_PREAMBLE_SIZE);
  16681. +
  16682. + skb_reset_network_header(skb);
  16683. +
  16684. + /* Reserve space for Header Field */
  16685. + skb_reserve(skb, DECT_HDR_FIELD_SIZE);
  16686. + return skb;
  16687. +}
  16688. +
  16689. +/*
  16690. + * MAC Bearers
  16691. + */
  16692. +
  16693. +static void dect_bearer_enable(struct dect_bearer *bearer)
  16694. +{
  16695. + switch (bearer->mode) {
  16696. + case DECT_BEARER_RX:
  16697. + dect_set_channel_mode(bearer->trx, &bearer->chd, DECT_SLOT_RX);
  16698. + break;
  16699. + case DECT_BEARER_TX:
  16700. + dect_set_channel_mode(bearer->trx, &bearer->chd, DECT_SLOT_TX);
  16701. + break;
  16702. + };
  16703. + dect_set_carrier(bearer->trx, bearer->chd.slot, bearer->chd.carrier);
  16704. + bearer->state = DECT_BEARER_ENABLED;
  16705. +}
  16706. +
  16707. +static void dect_bearer_disable(struct dect_bearer *bearer)
  16708. +{
  16709. + dect_set_channel_mode(bearer->trx, &bearer->chd, DECT_SLOT_IDLE);
  16710. + bearer->trx->slots[bearer->chd.slot].bearer = NULL;
  16711. +}
  16712. +
  16713. +static void dect_bearer_timer_add(struct dect_cell *cell,
  16714. + struct dect_bearer *bearer,
  16715. + struct dect_timer *timer,
  16716. + unsigned int frames)
  16717. +{
  16718. + u8 slot = bearer->chd.slot;
  16719. +
  16720. + switch (bearer->mode) {
  16721. + case DECT_BEARER_RX:
  16722. + dect_timer_add(cell, timer, DECT_TIMER_RX, frames, slot);
  16723. + break;
  16724. + case DECT_BEARER_TX:
  16725. + dect_timer_add(cell, timer, DECT_TIMER_TX, frames, slot);
  16726. + break;
  16727. + }
  16728. +}
  16729. +
  16730. +/**
  16731. + * dect_bearer_release - release a MAC bearer
  16732. + *
  16733. + * Release a MAC bearer that is no longer used. The unused slot position is
  16734. + * given to IRC and converted to a scan bearer.
  16735. + */
  16736. +static void dect_scan_bearer_enable(struct dect_transceiver *trx,
  16737. + const struct dect_channel_desc *chd);
  16738. +
  16739. +static void dect_bearer_release(struct dect_cell *cell,
  16740. + struct dect_bearer *bearer)
  16741. +{
  16742. + struct dect_transceiver *trx = bearer->trx;
  16743. + u8 slot = bearer->chd.slot;
  16744. +
  16745. + __skb_queue_purge(&bearer->m_tx_queue);
  16746. + dect_timer_del(&bearer->tx_timer);
  16747. + dect_bearer_disable(bearer);
  16748. + dect_disable_cipher(trx, &bearer->chd);
  16749. +
  16750. + if (trx->index < 3 &&
  16751. + ((slot >= dect_normal_receive_base(cell->mode) &&
  16752. + slot <= dect_normal_receive_end(cell->mode)) ||
  16753. + (cell->flags & DECT_CELL_MONITOR)))
  16754. + dect_scan_bearer_enable(trx, &bearer->chd);
  16755. +}
  16756. +
  16757. +static void dect_bearer_init(struct dect_cell *cell, struct dect_bearer *bearer,
  16758. + const struct dect_bearer_ops *ops,
  16759. + struct dect_transceiver *trx,
  16760. + const struct dect_channel_desc *chd,
  16761. + enum dect_bearer_modes mode, void *data)
  16762. +{
  16763. + pr_debug("init bearer: mode: %s slot: %u carrier: %u\n",
  16764. + mode == DECT_BEARER_RX ? "RX" : "TX" , chd->slot, chd->carrier);
  16765. +
  16766. + bearer->ops = ops;
  16767. + bearer->trx = trx;
  16768. + bearer->chd = *chd;
  16769. + bearer->mode = mode;
  16770. + bearer->state = DECT_BEARER_INACTIVE;
  16771. + dect_timer_setup(&bearer->tx_timer, NULL, NULL);
  16772. + skb_queue_head_init(&bearer->m_tx_queue);
  16773. + bearer->data = data;
  16774. +
  16775. + trx->slots[chd->slot].bearer = bearer;
  16776. + dect_set_channel_mode(bearer->trx, &bearer->chd, DECT_SLOT_IDLE);
  16777. +}
  16778. +
  16779. +/*
  16780. + * TX bearer activation:
  16781. + *
  16782. + * The first transmission of an outgoing traffic or connectionless bearer is
  16783. + * scheduled for the frame in which the remote sides' scan is on the desired
  16784. + * carrier.
  16785. + *
  16786. + * The noise value of the physical channel must be confirmed not to be more
  16787. + * than 12dBm stronger than the RSSI measurement obtained from the channel
  16788. + * list when selecting the channel within two frames before the first
  16789. + * transmission.
  16790. + *
  16791. + * Dummy bearers are activated immediately after confirming the RSSI.
  16792. + */
  16793. +
  16794. +static void dect_tx_bearer_report_rssi(struct dect_cell *cell,
  16795. + struct dect_bearer *bearer,
  16796. + u8 rssi)
  16797. +{
  16798. + rx_debug(cell, "RSSI confirm: last: %u new: %u\n", bearer->rssi, rssi);
  16799. + if (rssi > bearer->rssi + dect_dbm_to_rssi_rel(12))
  16800. + pr_debug("RSSI: too much noise\n");
  16801. + bearer->state = DECT_BEARER_RSSI_CONFIRMED;
  16802. +}
  16803. +
  16804. +static void dect_tx_bearer_enable_timer(struct dect_cell *cell, void *data)
  16805. +{
  16806. + struct dect_bearer *bearer = data;
  16807. +
  16808. + switch ((int)bearer->state) {
  16809. + case DECT_BEARER_SCHEDULED:
  16810. + tx_debug(cell, "confirm RSSI carrier %u\n", bearer->chd.carrier);
  16811. + dect_set_channel_mode(bearer->trx, &bearer->chd, DECT_SLOT_RX);
  16812. + dect_set_carrier(bearer->trx, bearer->chd.slot, bearer->chd.carrier);
  16813. + dect_bearer_timer_add(cell, bearer, &bearer->tx_timer, 2);
  16814. + bearer->state = DECT_BEARER_RSSI_CONFIRM;
  16815. + break;
  16816. + case DECT_BEARER_RSSI_CONFIRMED:
  16817. + tx_debug(cell, "enable bearer\n");
  16818. + if (bearer->ops->enable != NULL)
  16819. + bearer->ops->enable(cell, bearer);
  16820. + else
  16821. + dect_bearer_enable(bearer);
  16822. + break;
  16823. + }
  16824. +}
  16825. +
  16826. +static void dect_tx_bearer_schedule(struct dect_cell *cell,
  16827. + struct dect_bearer *bearer, u8 rssi)
  16828. +{
  16829. + u8 delay = 0;
  16830. +
  16831. + dect_timer_setup(&bearer->tx_timer, dect_tx_bearer_enable_timer, bearer);
  16832. + if (bearer->ops->state != DECT_DUMMY_BEARER)
  16833. + delay = dect_channel_delay(cell, &bearer->chd) - 2;
  16834. +
  16835. + bearer->state = DECT_BEARER_SCHEDULED;
  16836. + bearer->rssi = rssi;
  16837. +
  16838. + if (delay == 0)
  16839. + dect_tx_bearer_enable_timer(cell, bearer);
  16840. + else {
  16841. + dect_bearer_timer_add(cell, bearer, &bearer->tx_timer, delay);
  16842. + tx_debug(cell, "scheduled bearer: delay %u carrier %u pscn %u\n",
  16843. + delay, bearer->chd.carrier, cell->si.ssi.pscn);
  16844. + }
  16845. +}
  16846. +
  16847. +/*
  16848. + * Broadcast Message Control - decentralized components
  16849. + */
  16850. +
  16851. +/* Paging:
  16852. + *
  16853. + * The following rules apply to page message transmission:
  16854. + *
  16855. + * - Fast pages may be transmitted in any frame and have priority over normal
  16856. + * pages.
  16857. + *
  16858. + * - Normal short and full pages, as well as the first segment of a normal long
  16859. + * page, may only be transmitted in frame 0, or a frame up to 12 if the page
  16860. + * transmitted in the previously allowed frame had the extend bit bit set.
  16861. + *
  16862. + * - Normal pages must be repeated three times in the frames following their
  16863. + * first transmission for page detection in low duty idle mode.
  16864. + *
  16865. + * - Fast pages may be repeated up to three times following their first
  16866. + * transmission. New page message have priority over repetitions.
  16867. + *
  16868. + * FIXME: fast pages should not interrupt repetitions
  16869. + */
  16870. +
  16871. +static void dect_page_timer_schedule(struct dect_cell *cell)
  16872. +{
  16873. + u8 framenum = dect_framenum(cell, DECT_TIMER_TX);
  16874. + u8 frames;
  16875. +
  16876. + if ((framenum & 0x1) == 1)
  16877. + frames = 1;
  16878. + else
  16879. + frames = 2;
  16880. + framenum = dect_framenum_add(framenum, frames);
  16881. +
  16882. + if (framenum == 8 || framenum == 14)
  16883. + frames += 2;
  16884. +
  16885. + tx_debug(cell, "page timer: schedule in %u frames\n", frames);
  16886. + dect_timer_add(cell, &cell->page_timer, DECT_TIMER_TX, frames, 0);
  16887. +}
  16888. +
  16889. +/**
  16890. + * dect_queue_page - Add a paging message to the appropriate queue
  16891. + *
  16892. + * The first transmission of a page is added to the end of the normal or
  16893. + * fast queue. The first three repetitions of normal pages have priority
  16894. + * over first transmissions.
  16895. + */
  16896. +static void dect_queue_page(struct dect_cell *cell, struct sk_buff *skb)
  16897. +{
  16898. + u8 repetitions = DECT_BMC_CB(skb)->repetitions;
  16899. + bool fast = DECT_BMC_CB(skb)->fast_page;
  16900. + struct sk_buff_head *page_queue;
  16901. +
  16902. + page_queue = fast ? &cell->page_fast_queue : &cell->page_queue;
  16903. + if (!fast && repetitions > 0)
  16904. + skb_queue_head(page_queue, skb);
  16905. + else
  16906. + skb_queue_tail(page_queue, skb);
  16907. +
  16908. + dect_page_timer_schedule(cell);
  16909. +}
  16910. +
  16911. +/**
  16912. + * dect_queue_page_segments - perform segmentation and queue the page segments
  16913. + *
  16914. + * Segment a page message into B_S channel sized segments and add them
  16915. + * to the TX queue.
  16916. + */
  16917. +static void dect_queue_page_segments(struct sk_buff_head *list,
  16918. + struct sk_buff *skb)
  16919. +{
  16920. + unsigned int len = skb->len;
  16921. + struct sk_buff *seg;
  16922. + u64 t;
  16923. +
  16924. + while (skb->len > DECT_PT_LFP_BS_DATA_SIZE) {
  16925. + seg = skb_clone(skb, GFP_ATOMIC);
  16926. + if (seg == NULL)
  16927. + goto err;
  16928. + skb_trim(seg, DECT_PT_LFP_BS_DATA_SIZE);
  16929. +
  16930. + if (skb_queue_empty(list))
  16931. + t = DECT_PT_LONG_PAGE_FIRST;
  16932. + else
  16933. + t = DECT_PT_LONG_PAGE;
  16934. +
  16935. + seg->data[0] &= 0x0f;
  16936. + seg->data[0] |= t >> 48;
  16937. + pr_debug("queue page segment len %u hdr %x\n",
  16938. + seg->len, seg->data[0] & 0xf0);
  16939. + __skb_queue_tail(list, seg);
  16940. +
  16941. + skb_pull(skb, DECT_PT_LFP_BS_DATA_SIZE);
  16942. + }
  16943. +
  16944. + /* Short and full pages have the extend bit set in order to reduce
  16945. + * the delay for new pages arriving while a page is already active.
  16946. + */
  16947. + if (skb->len == DECT_PT_SP_BS_DATA_SIZE)
  16948. + t = DECT_PT_SHORT_PAGE | DECT_PT_HDR_EXTEND_FLAG;
  16949. + else if (!DECT_BMC_CB(skb)->long_page)
  16950. + t = DECT_PT_FULL_PAGE | DECT_PT_HDR_EXTEND_FLAG;
  16951. + else if (len == DECT_PT_LFP_BS_DATA_SIZE)
  16952. + t = DECT_PT_LONG_PAGE_ALL;
  16953. + else
  16954. + t = DECT_PT_LONG_PAGE_LAST;
  16955. +
  16956. + skb->data[0] &= 0x0f;
  16957. + skb->data[0] |= t >> 48;
  16958. + pr_debug("queue page segment len %u hdr %x\n",
  16959. + skb->len, skb->data[0] & 0xf0);
  16960. + __skb_queue_tail(list, skb);
  16961. + return;
  16962. +
  16963. +err:
  16964. + __skb_queue_purge(list);
  16965. + kfree_skb(skb);
  16966. +}
  16967. +
  16968. +/**
  16969. + * dect_page_timer - page message transmission timer
  16970. + *
  16971. + * This timer performs maintenance of the page transmit queue. While the queue
  16972. + * is active, it is advanced by one segment per frame. When a page message has
  16973. + * been fully transmitted, the next message is selected for transmission,
  16974. + * segmented into appropriate units and queued to the transmit queue.
  16975. + */
  16976. +static void dect_page_tx_timer(struct dect_cell *cell, void *data)
  16977. +{
  16978. + u32 timeout, mfn = dect_mfn(cell, DECT_TIMER_TX);
  16979. + u8 framenum = dect_framenum(cell, DECT_TIMER_TX);
  16980. + struct sk_buff *skb, *last;
  16981. +
  16982. + tx_debug(cell, "page timer\n");
  16983. +
  16984. + /* Advance the transmit queue by one segment per allowed tail. */
  16985. + if (!skb_queue_empty(&cell->page_tx_queue)) {
  16986. + tx_debug(cell, "advance queue\n");
  16987. + kfree_skb(__skb_dequeue(&cell->page_tx_queue));
  16988. + if (!skb_queue_empty(&cell->page_tx_queue)) {
  16989. + dect_page_timer_schedule(cell);
  16990. + return;
  16991. + }
  16992. + }
  16993. +
  16994. + /* Add the last page back to the queue unless its lifetime expired. */
  16995. + last = cell->page_sdu;
  16996. + if (last != NULL) {
  16997. + cell->page_sdu = NULL;
  16998. +
  16999. + DECT_BMC_CB(last)->repetitions++;
  17000. + timeout = dect_mfn_add(DECT_BMC_CB(last)->stamp, DECT_PAGE_LIFETIME);
  17001. + if (dect_mfn_before(mfn, timeout))
  17002. + dect_queue_page(cell, last);
  17003. + else
  17004. + kfree_skb(last);
  17005. + }
  17006. +
  17007. + /* Get the next page message */
  17008. + while (1) {
  17009. + skb = skb_dequeue(&cell->page_fast_queue);
  17010. + tx_debug(cell, "fast page: %p\n", skb);
  17011. + if (skb == NULL && !skb_queue_empty(&cell->page_queue)) {
  17012. + if (framenum == 0 || (last != NULL && framenum <= 12))
  17013. + skb = skb_dequeue(&cell->page_queue);
  17014. + tx_debug(cell, "normal page: %p\n", skb);
  17015. + }
  17016. + if (skb == NULL)
  17017. + goto out;
  17018. +
  17019. + timeout = dect_mfn_add(DECT_BMC_CB(skb)->stamp, DECT_PAGE_LIFETIME);
  17020. + if (dect_mfn_before(mfn, timeout))
  17021. + break;
  17022. + else
  17023. + kfree_skb(skb);
  17024. + }
  17025. +
  17026. + /* Save a copy of short and full pages for repetitions. */
  17027. + if (!DECT_BMC_CB(skb)->long_page &&
  17028. + DECT_BMC_CB(skb)->repetitions < 3)
  17029. + cell->page_sdu = skb_clone(skb, GFP_ATOMIC);
  17030. +
  17031. + /* Segment page message and queue segments to tx queue */
  17032. + dect_queue_page_segments(&cell->page_tx_queue, skb);
  17033. +out:
  17034. + if (skb != NULL || !skb_queue_empty(&cell->page_queue))
  17035. + dect_page_timer_schedule(cell);
  17036. +}
  17037. +
  17038. +static void dect_cell_schedule_page(struct dect_cell *cell, u32 mask)
  17039. +{
  17040. + struct dect_bc *bc;
  17041. +
  17042. + list_for_each_entry(bc, &cell->bcs, list)
  17043. + bc->p_tx_mask |= mask;
  17044. +}
  17045. +
  17046. +static void dect_cell_bmc_init(struct dect_cell *cell)
  17047. +{
  17048. + skb_queue_head_init(&cell->page_queue);
  17049. + skb_queue_head_init(&cell->page_fast_queue);
  17050. + skb_queue_head_init(&cell->page_tx_queue);
  17051. + dect_timer_setup(&cell->page_timer, dect_page_tx_timer, NULL);
  17052. +}
  17053. +
  17054. +static void dect_cell_bmc_disable(struct dect_cell *cell)
  17055. +{
  17056. + dect_timer_del(&cell->page_timer);
  17057. + __skb_queue_purge(&cell->page_tx_queue);
  17058. + __skb_queue_purge(&cell->page_fast_queue);
  17059. + __skb_queue_purge(&cell->page_queue);
  17060. +}
  17061. +
  17062. +/*
  17063. + * Broadcast Control
  17064. + */
  17065. +
  17066. +static void dect_cell_mac_info_ind(struct dect_cell *cell)
  17067. +{
  17068. + const struct dect_cluster_handle *clh = cell->handle.clh;
  17069. +
  17070. + clh->ops->mac_info_ind(clh, &cell->idi, &cell->si);
  17071. +}
  17072. +
  17073. +static u32 dect_build_page_rfpi(const struct dect_cell *cell)
  17074. +{
  17075. + return (dect_build_rfpi(&cell->idi) >> 24) & ((1 << 20) - 1);
  17076. +}
  17077. +
  17078. +static void dect_bc_release(struct dect_bc *bc)
  17079. +{
  17080. + kfree_skb(bc->p_rx_skb);
  17081. + list_del(&bc->list);
  17082. +}
  17083. +
  17084. +static void dect_bc_init(struct dect_cell *cell, struct dect_bc *bc)
  17085. +{
  17086. + INIT_LIST_HEAD(&bc->list);
  17087. + bc->p_rx_skb = NULL;
  17088. + list_add_tail(&bc->list, &cell->bcs);
  17089. +}
  17090. +
  17091. +static const enum dect_mac_system_information_types dect_bc_q_cycle[] = {
  17092. + DECT_QT_SI_SSI,
  17093. + DECT_QT_SI_ERFC,
  17094. + DECT_QT_SI_SARI,
  17095. + DECT_QT_SI_FPC,
  17096. + DECT_QT_SI_EFPC,
  17097. + DECT_QT_SI_EFPC2,
  17098. + DECT_QT_SI_MFN,
  17099. +};
  17100. +
  17101. +static struct sk_buff *dect_bc_q_dequeue(struct dect_cell *cell,
  17102. + struct dect_bearer *bearer)
  17103. +{
  17104. + const struct dect_si *si = &cell->si;
  17105. + struct dect_ssi ssi;
  17106. + struct dect_mfn mfn;
  17107. + struct sk_buff *skb;
  17108. + unsigned int index;
  17109. +
  17110. + skb = dect_t_skb_alloc();
  17111. + if (skb == NULL)
  17112. + return NULL;
  17113. +
  17114. + while (1) {
  17115. + index = cell->si_idx++;
  17116. + if (cell->si_idx == ARRAY_SIZE(dect_bc_q_cycle))
  17117. + cell->si_idx = 0;
  17118. +
  17119. + switch (dect_bc_q_cycle[index]) {
  17120. + case DECT_QT_SI_SSI:
  17121. + memcpy(&ssi, &si->ssi, sizeof(ssi));
  17122. + ssi.sn = bearer->chd.slot;
  17123. + ssi.cn = bearer->chd.carrier;
  17124. + ssi.sp = 0;
  17125. + ssi.pscn = dect_next_carrier(ssi.rfcars, ssi.pscn);
  17126. +
  17127. + return dect_build_tail_msg(skb, DECT_TM_TYPE_SSI, &ssi);
  17128. + case DECT_QT_SI_ERFC:
  17129. + if (!si->ssi.mc)
  17130. + continue;
  17131. + return dect_build_tail_msg(skb, DECT_TM_TYPE_ERFC,
  17132. + &si->erfc);
  17133. + case DECT_QT_SI_SARI:
  17134. + break;
  17135. + case DECT_QT_SI_FPC:
  17136. + return dect_build_tail_msg(skb, DECT_TM_TYPE_FPC,
  17137. + &si->fpc);
  17138. + case DECT_QT_SI_EFPC:
  17139. + if (!(si->fpc.fpc & DECT_FPC_EXTENDED_FP_INFO))
  17140. + continue;
  17141. + return dect_build_tail_msg(skb, DECT_TM_TYPE_EFPC,
  17142. + &si->efpc);
  17143. + case DECT_QT_SI_EFPC2:
  17144. + if (!(si->efpc.fpc & DECT_EFPC_EXTENDED_FP_INFO2))
  17145. + continue;
  17146. + return dect_build_tail_msg(skb, DECT_TM_TYPE_EFPC2,
  17147. + &si->efpc2);
  17148. + case DECT_QT_SI_MFN:
  17149. + mfn.num = dect_mfn(cell, DECT_TIMER_TX);
  17150. + return dect_build_tail_msg(skb, DECT_TM_TYPE_MFN, &mfn);
  17151. + default:
  17152. + BUG();
  17153. + }
  17154. + }
  17155. +}
  17156. +
  17157. +static void dect_page_add_mac_info(struct dect_cell *cell, struct dect_bc *bc,
  17158. + struct sk_buff *skb)
  17159. +{
  17160. + struct dect_tail_msg tm;
  17161. + struct dect_dbc *dbc;
  17162. + u64 t;
  17163. + u8 *it;
  17164. +
  17165. + memset(&tm, 0, sizeof(tm));
  17166. + if (bc->p_tx_mask & (1 << DECT_TM_TYPE_BFS))
  17167. + tm.type = DECT_TM_TYPE_BFS;
  17168. + else if (bc->p_tx_mask & (1 << DECT_TM_TYPE_BD))
  17169. + tm.type = DECT_TM_TYPE_BD;
  17170. + else
  17171. + tm.type = DECT_TM_TYPE_ACTIVE_CARRIERS;
  17172. +
  17173. + switch (tm.type) {
  17174. + case DECT_TM_TYPE_BFS:
  17175. + tm.bfs.mask = cell->trg_blind_full_slots;
  17176. + t = dect_build_blind_full_slots(&tm.bfs);
  17177. + break;
  17178. + case DECT_TM_TYPE_BD:
  17179. + dbc = dect_dbc_get(cell);
  17180. + if (dbc == NULL)
  17181. + goto out;
  17182. + tm.bd.bt = DECT_PT_IT_DUMMY_OR_CL_BEARER_POSITION;
  17183. + tm.bd.sn = dbc->bearer.chd.slot;
  17184. + tm.bd.sp = 0;
  17185. + tm.bd.cn = dbc->bearer.chd.carrier;
  17186. + t = dect_build_bearer_description(&tm.bd);
  17187. + break;
  17188. + case DECT_TM_TYPE_RFP_ID:
  17189. + t = dect_build_rfp_identity(&tm.rfp_id);
  17190. + break;
  17191. + case DECT_TM_TYPE_RFP_STATUS:
  17192. + t = dect_build_rfp_status(&tm.rfp_status);
  17193. + break;
  17194. + case DECT_TM_TYPE_ACTIVE_CARRIERS:
  17195. + default:
  17196. + t = dect_build_active_carriers(&tm.active_carriers);
  17197. + break;
  17198. + }
  17199. +
  17200. + it = skb_put(skb, DECT_PT_INFO_TYPE_SIZE);
  17201. + it[0] = t >> 24;
  17202. + it[1] = t >> 16;
  17203. +out:
  17204. + bc->p_tx_mask &= ~(1 << tm.type);
  17205. +}
  17206. +
  17207. +static struct sk_buff *dect_bc_p_dequeue(struct dect_cell *cell,
  17208. + struct dect_bearer *bearer,
  17209. + struct dect_bc *bc)
  17210. +{
  17211. + unsigned int headroom, tailroom = 0;
  17212. + struct sk_buff *skb;
  17213. + u8 *hdr;
  17214. + u64 t;
  17215. +
  17216. + /* Send higher layer page messages if present */
  17217. + skb = skb_peek(&cell->page_tx_queue);
  17218. + if (skb != NULL) {
  17219. + /* The frame needs headroom for the preamble and hdr-field.
  17220. + * Short pages need additional tailroom for the MAC Layer
  17221. + * Information. */
  17222. + headroom = DECT_PREAMBLE_SIZE + DECT_HDR_FIELD_SIZE;
  17223. + if (skb->len == DECT_PT_SP_BS_DATA_SIZE)
  17224. + tailroom = DECT_PT_INFO_TYPE_SIZE;
  17225. +
  17226. + skb = skb_copy_expand(skb, headroom, tailroom, GFP_ATOMIC);
  17227. + if (skb == NULL)
  17228. + return NULL;
  17229. + /* Reserve space for preamble */
  17230. + skb_set_mac_header(skb, -headroom);
  17231. + } else {
  17232. + /* Send zero-length page if required */
  17233. + if (dect_framenum(cell, DECT_TIMER_TX) == 0 ||
  17234. + bc->p_tx_mask == 0)
  17235. + return NULL;
  17236. +
  17237. + skb = dect_t_skb_alloc();
  17238. + if (skb == NULL)
  17239. + return NULL;
  17240. +
  17241. + t = DECT_PT_ZERO_PAGE | DECT_PT_HDR_EXTEND_FLAG;
  17242. + t |= (u64)dect_build_page_rfpi(cell) << DECT_PT_ZP_RFPI_SHIFT;
  17243. +
  17244. + hdr = skb_put(skb, 3);
  17245. + hdr[0] = t >> 48;
  17246. + hdr[1] = t >> 40;
  17247. + hdr[2] = t >> 32;
  17248. +
  17249. + tailroom = DECT_PT_INFO_TYPE_SIZE;
  17250. + }
  17251. +
  17252. + DECT_A_CB(skb)->id = DECT_TI_PT;
  17253. + if (tailroom > 0)
  17254. + dect_page_add_mac_info(cell, bc, skb);
  17255. +
  17256. + return skb;
  17257. +}
  17258. +
  17259. +static struct sk_buff *dect_bc_dequeue(struct dect_cell *cell,
  17260. + struct dect_bearer *bearer,
  17261. + struct dect_bc *bc,
  17262. + enum dect_mac_channels chan)
  17263. +{
  17264. + struct sk_buff *skb;
  17265. +
  17266. + switch (chan) {
  17267. + case DECT_MC_P:
  17268. + return dect_bc_p_dequeue(cell, bearer, bc);
  17269. + case DECT_MC_Q:
  17270. + return dect_bc_q_dequeue(cell, bearer);
  17271. + case DECT_MC_N:
  17272. + skb = dect_t_skb_alloc();
  17273. + if (skb == NULL)
  17274. + return NULL;
  17275. + return dect_build_tail_msg(skb, DECT_TM_TYPE_ID, &cell->idi);
  17276. + default:
  17277. + BUG();
  17278. + }
  17279. +}
  17280. +
  17281. +/**
  17282. + * dect_bc_queue_bs_data - queue a page message to the broadcast controller for
  17283. + * reassembly and delivery to broadcast message control.
  17284. + *
  17285. + * @cell: DECT cell
  17286. + * @bc: broadcast controller
  17287. + * @skb_in: DECT frame
  17288. + * @page: page message
  17289. + */
  17290. +static void dect_bc_queue_bs_data(struct dect_cell *cell, struct dect_bc *bc,
  17291. + struct sk_buff *skb_in, const struct dect_page *page)
  17292. +{
  17293. + const struct dect_cluster_handle *clh = cell->handle.clh;
  17294. + struct sk_buff *skb, *head;
  17295. +
  17296. + if (page->length == DECT_PT_ZERO_PAGE)
  17297. + return;
  17298. +
  17299. + skb = skb_clone(skb_in, GFP_ATOMIC);
  17300. + if (skb == NULL)
  17301. + return;
  17302. + skb_pull(skb, DECT_T_FIELD_OFF);
  17303. + DECT_BMC_CB(skb)->long_page = false;
  17304. +
  17305. + head = bc->p_rx_skb;
  17306. + switch (page->length) {
  17307. + case DECT_PT_SHORT_PAGE:
  17308. + skb_trim(skb, DECT_PT_SP_BS_DATA_SIZE);
  17309. + break;
  17310. + case DECT_PT_LONG_PAGE_ALL:
  17311. + DECT_BMC_CB(skb)->long_page = true;
  17312. + /* fall through */
  17313. + case DECT_PT_FULL_PAGE:
  17314. + skb_trim(skb, DECT_PT_LFP_BS_DATA_SIZE);
  17315. + break;
  17316. + case DECT_PT_LONG_PAGE_FIRST:
  17317. + if (head != NULL)
  17318. + goto err_free;
  17319. + DECT_BMC_CB(skb)->long_page = true;
  17320. + skb_trim(skb, DECT_PT_LFP_BS_DATA_SIZE);
  17321. + bc->p_rx_skb = skb;
  17322. + return;
  17323. + case DECT_PT_LONG_PAGE:
  17324. + if (head == NULL)
  17325. + goto err_free;
  17326. + skb_trim(skb, DECT_PT_LFP_BS_DATA_SIZE);
  17327. + skb_append_frag(head, skb);
  17328. + if (head->len >= 30)
  17329. + goto err;
  17330. + return;
  17331. + case DECT_PT_LONG_PAGE_LAST:
  17332. + if (head == NULL)
  17333. + goto err_free;
  17334. + skb_trim(skb, DECT_PT_LFP_BS_DATA_SIZE);
  17335. + skb = skb_append_frag(head, skb);
  17336. + bc->p_rx_skb = NULL;
  17337. + break;
  17338. + default:
  17339. + BUG();
  17340. + }
  17341. +
  17342. + return clh->ops->bmc_page_ind(clh, skb);
  17343. +
  17344. +err_free:
  17345. + kfree_skb(skb);
  17346. +err:
  17347. + kfree_skb(bc->p_rx_skb);
  17348. + bc->p_rx_skb = NULL;
  17349. +}
  17350. +
  17351. +static bool dect_bc_update_si(struct dect_si *si,
  17352. + const struct dect_tail_msg *tm)
  17353. +{
  17354. + bool notify = false;
  17355. + unsigned int i;
  17356. +
  17357. + switch (tm->type) {
  17358. + case DECT_TM_TYPE_SSI:
  17359. + if (memcmp(&si->ssi, &tm->ssi, sizeof(si->ssi)))
  17360. + memcpy(&si->ssi, &tm->ssi, sizeof(si->ssi));
  17361. + break;
  17362. + case DECT_TM_TYPE_ERFC:
  17363. + if (memcmp(&si->erfc, &tm->erfc, sizeof(si->erfc)))
  17364. + memcpy(&si->erfc, &tm->erfc, sizeof(si->erfc));
  17365. + break;
  17366. + case DECT_TM_TYPE_FPC:
  17367. + if (memcmp(&si->fpc, &tm->fpc, sizeof(si->fpc))) {
  17368. + memcpy(&si->fpc, &tm->fpc, sizeof(si->fpc));
  17369. + notify = true;
  17370. + }
  17371. + break;
  17372. + case DECT_TM_TYPE_EFPC:
  17373. + if (memcmp(&si->efpc, &tm->efpc, sizeof(si->efpc))) {
  17374. + memcpy(&si->efpc, &tm->efpc, sizeof(si->efpc));
  17375. + notify = true;
  17376. + }
  17377. + break;
  17378. + case DECT_TM_TYPE_EFPC2:
  17379. + if (memcmp(&si->efpc2, &tm->efpc2, sizeof(si->efpc2))) {
  17380. + memcpy(&si->efpc2, &tm->efpc2, sizeof(si->efpc2));
  17381. + notify = true;
  17382. + }
  17383. + break;
  17384. + case DECT_TM_TYPE_SARI:
  17385. + if (si->num_saris == ARRAY_SIZE(si->sari))
  17386. + break;
  17387. +
  17388. + for (i = 0; i < si->num_saris; i++) {
  17389. + if (!dect_ari_cmp(&tm->sari.ari, &si->sari[i].ari))
  17390. + break;
  17391. + }
  17392. + if (i < si->num_saris)
  17393. + break;
  17394. +
  17395. + memcpy(&si->sari[si->num_saris++], &tm->sari,
  17396. + sizeof(si->sari[i]));
  17397. + notify = true;
  17398. + break;
  17399. + case DECT_TM_TYPE_MFN:
  17400. + memcpy(&si->mfn, &tm->mfn, sizeof(si->mfn));
  17401. + break;
  17402. + default:
  17403. + return false;
  17404. + }
  17405. +
  17406. + si->mask |= 1 << tm->type;
  17407. + return notify;
  17408. +}
  17409. +
  17410. +static bool dect_bc_si_cycle_complete(struct dect_idi *idi,
  17411. + const struct dect_si *si)
  17412. +{
  17413. + if (!(si->mask & (1 << DECT_TM_TYPE_SSI))) {
  17414. + pr_debug("incomplete: SSI\n");
  17415. + return false;
  17416. + }
  17417. + if (si->ssi.mc &&
  17418. + !(si->mask & (1 << DECT_TM_TYPE_ERFC))) {
  17419. + pr_debug("incomplete: ERFC\n");
  17420. + return false;
  17421. + }
  17422. +
  17423. + if (!(si->mask & (1 << DECT_TM_TYPE_FPC))) {
  17424. + pr_debug("incomplete: FPC\n");
  17425. + return false;
  17426. + }
  17427. + if (si->fpc.fpc & DECT_FPC_EXTENDED_FP_INFO &&
  17428. + !(si->mask & (1 << DECT_TM_TYPE_EFPC))) {
  17429. + pr_debug("incomplete: EFPC\n");
  17430. + return false;
  17431. + }
  17432. +
  17433. + if (si->mask & (1 << DECT_TM_TYPE_EFPC) &&
  17434. + si->efpc.fpc & DECT_EFPC_EXTENDED_FP_INFO2 &&
  17435. + !(si->mask & (1 << DECT_TM_TYPE_EFPC2))) {
  17436. + pr_debug("incomplete: EFPC2\n");
  17437. + return false;
  17438. + }
  17439. +
  17440. + if (idi->e &&
  17441. + (!(si->mask & (1 << DECT_TM_TYPE_SARI)) ||
  17442. + si->num_saris != si->sari[0].list_cycle)) {
  17443. + pr_debug("incomplete: SARI\n");
  17444. + return false;
  17445. + }
  17446. +
  17447. + pr_debug("complete\n");
  17448. + return true;
  17449. +}
  17450. +
  17451. +static void dect_bc_rcv(struct dect_cell *cell, struct dect_bc *bc,
  17452. + struct sk_buff *skb, const struct dect_tail_msg *tm)
  17453. +{
  17454. + enum dect_tail_identifications ti;
  17455. + bool notify;
  17456. +
  17457. + if (cell->mode != DECT_MODE_PP)
  17458. + return;
  17459. +
  17460. + ti = dect_parse_tail(skb);
  17461. + if (ti == DECT_TI_QT) {
  17462. + /* Q-channel information is broadcast in frame 8 */
  17463. + dect_timer_synchronize_framenum(cell, DECT_Q_CHANNEL_FRAME);
  17464. + if (tm->type == DECT_TM_TYPE_MFN)
  17465. + dect_timer_synchronize_mfn(cell, tm->mfn.num);
  17466. +
  17467. + notify = dect_bc_update_si(&cell->si, tm);
  17468. + if (dect_bc_si_cycle_complete(&cell->idi, &cell->si) && notify)
  17469. + dect_cell_mac_info_ind(cell);
  17470. + } else if (ti == DECT_TI_PT) {
  17471. + if (tm->page.length == DECT_PT_ZERO_PAGE &&
  17472. + tm->page.rfpi != dect_build_page_rfpi(cell))
  17473. + pr_debug("RFPI mismatch %.3x %.3x\n",
  17474. + tm->page.rfpi, dect_build_page_rfpi(cell));
  17475. + }
  17476. +
  17477. + switch (tm->type) {
  17478. + case DECT_TM_TYPE_BFS:
  17479. + cell->blind_full_slots = tm->bfs.mask;
  17480. + case DECT_TM_TYPE_BD:
  17481. + case DECT_TM_TYPE_RFP_ID:
  17482. + case DECT_TM_TYPE_RFP_STATUS:
  17483. + case DECT_TM_TYPE_ACTIVE_CARRIERS:
  17484. + case DECT_TM_TYPE_PAGE:
  17485. + dect_bc_queue_bs_data(cell, bc, skb, &tm->page);
  17486. + break;
  17487. + default:
  17488. + break;
  17489. + }
  17490. +}
  17491. +
  17492. +/*
  17493. + * Traffic Bearer Control (TBC)
  17494. + */
  17495. +
  17496. +#define tbc_debug(tbc, fmt, args...) \
  17497. + pr_debug("TBC (TBEI %u/%s): PMID: %s %x FMID: %.3x: " fmt, \
  17498. + (tbc)->id.tbei, tbc_states[(tbc)->state], \
  17499. + (tbc)->id.pmid.type == DECT_PMID_DEFAULT ? "default" : \
  17500. + (tbc)->id.pmid.type == DECT_PMID_ASSIGNED ? "assigned" : \
  17501. + (tbc)->id.pmid.type == DECT_PMID_EMERGENCY ? "emergency" : "?", \
  17502. + (tbc)->id.pmid.tpui, (tbc)->cell->fmid, ## args);
  17503. +
  17504. +static const char *tbc_states[] = {
  17505. + [DECT_TBC_NONE] = "NONE",
  17506. + [DECT_TBC_REQ_SENT] = "REQ_SENT",
  17507. + [DECT_TBC_WAIT_RCVD] = "WAIT_RCVD",
  17508. + [DECT_TBC_REQ_RCVD] = "REQ_RCVD",
  17509. + [DECT_TBC_RESPONSE_SENT] = "RESPONSE_SENT",
  17510. + [DECT_TBC_ATTRIBUTES_SENT] = "ATTRIBUTES_SENT",
  17511. + [DECT_TBC_OTHER_WAIT] = "OTHER_WAIT",
  17512. + [DECT_TBC_ESTABLISHED] = "ESTABLISHED",
  17513. + [DECT_TBC_RELEASING] = "RELEASING",
  17514. + [DECT_TBC_RELEASED] = "RELEASED",
  17515. +};
  17516. +
  17517. +static struct sk_buff *dect_b_skb_alloc(const struct dect_channel_desc *chd)
  17518. +{
  17519. + unsigned int b_field_size;
  17520. + struct sk_buff *skb;
  17521. +
  17522. + b_field_size = dect_pkt_b_field_size(chd);
  17523. + skb = alloc_skb(b_field_size, GFP_ATOMIC);
  17524. + if (skb == NULL)
  17525. + return NULL;
  17526. + skb_put(skb, b_field_size);
  17527. + memset(skb->data, 0xff, b_field_size);
  17528. + return skb;
  17529. +}
  17530. +
  17531. +static enum dect_b_identifications dect_pkt_to_bi(enum dect_packet_types pkt)
  17532. +{
  17533. + switch (pkt) {
  17534. + case DECT_PACKET_P08:
  17535. + return DECT_BI_HALF_SLOT_REQUIRED;
  17536. + case DECT_PACKET_P80:
  17537. + return DECT_BI_DOUBLE_SLOT_REQUIRED;
  17538. + case DECT_PACKET_P640j:
  17539. + return DECT_BI_LONG_SLOT_640_REQUIRED;
  17540. + case DECT_PACKET_P672j:
  17541. + return DECT_BI_LONG_SLOT_672_REQUIRED;
  17542. + default:
  17543. + return DECT_BI_NONE;
  17544. + }
  17545. +}
  17546. +
  17547. +static enum dect_packet_types dect_bi_to_pkt(enum dect_b_identifications b_id)
  17548. +{
  17549. + switch (b_id) {
  17550. + case DECT_BI_DOUBLE_SLOT_REQUIRED:
  17551. + return DECT_PACKET_P80;
  17552. + case DECT_BI_HALF_SLOT_REQUIRED:
  17553. + return DECT_PACKET_P08;
  17554. + case DECT_BI_LONG_SLOT_672_REQUIRED:
  17555. + return DECT_PACKET_P672j;
  17556. + case DECT_BI_LONG_SLOT_640_REQUIRED:
  17557. + return DECT_PACKET_P640j;
  17558. + default:
  17559. + return DECT_PACKET_P32;
  17560. + }
  17561. +}
  17562. +
  17563. +static struct dect_tbc *dect_tbc_get_by_tbei(const struct dect_cell *cell, u32 tbei)
  17564. +{
  17565. + struct dect_tbc *tbc;
  17566. +
  17567. + list_for_each_entry(tbc, &cell->tbcs, list) {
  17568. + if (tbc->id.tbei == tbei)
  17569. + return tbc;
  17570. + }
  17571. + return NULL;
  17572. +}
  17573. +
  17574. +static u32 dect_tbc_alloc_tbei(struct dect_cell *cell)
  17575. +{
  17576. + u32 tbei;
  17577. +
  17578. + while (1) {
  17579. + tbei = ++cell->tbei_rover;
  17580. + if (tbei == 0)
  17581. + continue;
  17582. + if (dect_tbc_get_by_tbei(cell, tbei))
  17583. + continue;
  17584. + return tbei;
  17585. + }
  17586. +}
  17587. +
  17588. +static void dect_tbc_queue_mac_control(struct dect_tbc *tbc, struct sk_buff *skb)
  17589. +{
  17590. + skb_queue_tail(&tbc->txb.m_tx_queue, skb);
  17591. +}
  17592. +
  17593. +static struct sk_buff *dect_tbc_build_cctrl(const struct dect_tbc *tbc,
  17594. + enum dect_cctrl_cmds cmd)
  17595. +{
  17596. + struct dect_cctrl cctl;
  17597. + struct sk_buff *skb;
  17598. +
  17599. + skb = dect_t_skb_alloc();
  17600. + if (skb == NULL)
  17601. + return NULL;
  17602. +
  17603. + cctl.fmid = tbc->cell->fmid;
  17604. + cctl.pmid = dect_build_pmid(&tbc->id.pmid);
  17605. + cctl.cmd = cmd;
  17606. +
  17607. + if (tbc->mcp.type == DECT_MAC_CONN_BASIC)
  17608. + return dect_build_tail_msg(skb, DECT_TM_TYPE_BCCTRL, &cctl);
  17609. + else
  17610. + return dect_build_tail_msg(skb, DECT_TM_TYPE_ACCTRL, &cctl);
  17611. +}
  17612. +
  17613. +static struct sk_buff *dect_tbc_build_encctrl(const struct dect_tbc *tbc,
  17614. + enum dect_encctrl_cmds cmd)
  17615. +{
  17616. + struct dect_encctrl ectl;
  17617. + struct sk_buff *skb;
  17618. +
  17619. + skb = dect_t_skb_alloc();
  17620. + if (skb == NULL)
  17621. + return NULL;
  17622. +
  17623. + ectl.fmid = tbc->cell->fmid;
  17624. + ectl.pmid = dect_build_pmid(&tbc->id.pmid);
  17625. + ectl.cmd = cmd;
  17626. +
  17627. + return dect_build_tail_msg(skb, DECT_TM_TYPE_ENCCTRL, &ectl);
  17628. +}
  17629. +
  17630. +static int dect_tbc_send_confirm(struct dect_tbc *tbc)
  17631. +{
  17632. + struct sk_buff *skb;
  17633. +
  17634. + tbc_debug(tbc, "TX CONFIRM\n");
  17635. + skb = dect_tbc_build_cctrl(tbc, DECT_CCTRL_BEARER_CONFIRM);
  17636. + if (skb == NULL)
  17637. + return -ENOMEM;
  17638. +
  17639. + /* The first response is permitted in any frame */
  17640. + if (tbc->state == DECT_TBC_REQ_RCVD)
  17641. + skb->priority = DECT_MT_HIGH_PRIORITY;
  17642. + dect_tbc_queue_mac_control(tbc, skb);
  17643. + return 0;
  17644. +}
  17645. +
  17646. +static int dect_tbc_send_attributes(struct dect_tbc *tbc, enum dect_cctrl_cmds cmd)
  17647. +{
  17648. + struct dect_cctrl cctl;
  17649. + struct sk_buff *skb;
  17650. +
  17651. + skb = dect_t_skb_alloc();
  17652. + if (skb == NULL)
  17653. + return -ENOMEM;
  17654. +
  17655. + cctl.cmd = cmd;
  17656. + cctl.attr.ecn = tbc->id.ecn;
  17657. + cctl.attr.lbn = tbc->id.lbn;
  17658. + cctl.attr.type = DECT_CCTRL_TYPE_SYMETRIC_BEARER;
  17659. + cctl.attr.service = tbc->mcp.service;
  17660. + cctl.attr.cf = false;
  17661. +
  17662. + cctl.attr.slot = tbc->mcp.slot;
  17663. + cctl.attr.a_mod = DECT_MODULATION_2_LEVEL;
  17664. + cctl.attr.bz_mod = DECT_MODULATION_2_LEVEL;
  17665. + cctl.attr.bz_ext_mod = 7;
  17666. + cctl.attr.acr = 0;
  17667. +
  17668. + if (tbc->mcp.type == DECT_MAC_CONN_BASIC)
  17669. + dect_build_tail_msg(skb, DECT_TM_TYPE_BCCTRL, &cctl);
  17670. + else
  17671. + dect_build_tail_msg(skb, DECT_TM_TYPE_ACCTRL, &cctl);
  17672. +
  17673. + dect_tbc_queue_mac_control(tbc, skb);
  17674. + return 0;
  17675. +}
  17676. +
  17677. +static int dect_tbc_send_attributes_confirm(struct dect_tbc *tbc)
  17678. +{
  17679. + tbc_debug(tbc, "TX ATTRIBUTES_T_CONFIRM\n");
  17680. + return dect_tbc_send_attributes(tbc, DECT_CCTRL_ATTRIBUTES_T_CONFIRM);
  17681. +}
  17682. +
  17683. +static int dect_tbc_send_attributes_request(struct dect_tbc *tbc)
  17684. +{
  17685. + tbc_debug(tbc, "TX ATTRIBUTES_T_REQUEST\n");
  17686. + return dect_tbc_send_attributes(tbc, DECT_CCTRL_ATTRIBUTES_T_REQUEST);
  17687. +}
  17688. +
  17689. +static int dect_tbc_send_wait(struct dect_tbc *tbc)
  17690. +{
  17691. + struct sk_buff *skb;
  17692. +
  17693. + skb = dect_tbc_build_cctrl(tbc, DECT_CCTRL_WAIT);
  17694. + if (skb == NULL)
  17695. + return -ENOMEM;
  17696. + dect_tbc_queue_mac_control(tbc, skb);
  17697. + return 0;
  17698. +}
  17699. +
  17700. +static int dect_tbc_send_release(struct dect_tbc *tbc,
  17701. + enum dect_release_reasons reason)
  17702. +{
  17703. + struct dect_cctrl cctl;
  17704. + struct sk_buff *skb;
  17705. +
  17706. + tbc_debug(tbc, "TX RELEASE: reason: %x\n", reason);
  17707. + skb = dect_t_skb_alloc();
  17708. + if (skb == NULL)
  17709. + return -ENOMEM;
  17710. +
  17711. + cctl.cmd = DECT_CCTRL_RELEASE;
  17712. + cctl.pmid = dect_build_pmid(&tbc->id.pmid);
  17713. + cctl.rel.reason = reason;
  17714. +
  17715. + if (tbc->mcp.type == DECT_MAC_CONN_BASIC)
  17716. + dect_build_tail_msg(skb, DECT_TM_TYPE_BCCTRL, &cctl);
  17717. + else
  17718. + dect_build_tail_msg(skb, DECT_TM_TYPE_ACCTRL, &cctl);
  17719. +
  17720. + /* RELEASE messages may appear in any frame */
  17721. + skb->priority = DECT_MT_HIGH_PRIORITY;
  17722. + dect_tbc_queue_mac_control(tbc, skb);
  17723. + return 0;
  17724. +}
  17725. +
  17726. +static void dect_tbc_state_change(struct dect_tbc *tbc, enum dect_tbc_state state)
  17727. +{
  17728. + struct dect_cell *cell = tbc->cell;
  17729. +
  17730. + tbc_debug(tbc, "state change: %s (%u) -> %s (%u)\n",
  17731. + tbc_states[tbc->state], tbc->state, tbc_states[state], state);
  17732. +
  17733. + if (tbc->state == DECT_TBC_ESTABLISHED) {
  17734. + cell->tbc_num_est--;
  17735. + cell->tbc_last_chd = tbc->rxb.chd;
  17736. + } else if (state == DECT_TBC_ESTABLISHED)
  17737. + cell->tbc_num_est++;
  17738. +
  17739. + tbc->state = state;
  17740. +}
  17741. +
  17742. +static int dect_tbc_event(const struct dect_tbc *tbc, enum dect_tbc_event event)
  17743. +{
  17744. + const struct dect_cluster_handle *clh = tbc->cell->handle.clh;
  17745. +
  17746. + return clh->ops->tbc_event_ind(clh, &tbc->id, event);
  17747. +}
  17748. +
  17749. +static int dect_tbc_establish_cfm(const struct dect_tbc *tbc, bool success)
  17750. +{
  17751. + const struct dect_cluster_handle *clh = tbc->cell->handle.clh;
  17752. +
  17753. + return clh->ops->tbc_establish_cfm(clh, &tbc->id, success,
  17754. + tbc->rxb.chd.slot);
  17755. +}
  17756. +
  17757. +static void dect_tbc_release_notify(const struct dect_tbc *tbc,
  17758. + enum dect_release_reasons reason)
  17759. +{
  17760. + const struct dect_cluster_handle *clh = tbc->cell->handle.clh;
  17761. +
  17762. + clh->ops->tbc_dis_ind(clh, &tbc->id, reason);
  17763. +}
  17764. +
  17765. +static void dect_tdd_channel_desc(struct dect_channel_desc *dst,
  17766. + const struct dect_channel_desc *chd)
  17767. +{
  17768. + dst->pkt = chd->pkt;
  17769. + dst->b_fmt = chd->b_fmt;
  17770. + dst->carrier = chd->carrier;
  17771. + dst->slot = dect_tdd_slot(chd->slot);
  17772. +}
  17773. +
  17774. +static void dect_tbc_destroy(struct dect_cell *cell, struct dect_tbc *tbc)
  17775. +{
  17776. + tbc_debug(tbc, "destroy\n");
  17777. + dect_tbc_state_change(tbc, DECT_TBC_NONE);
  17778. +
  17779. + dect_timer_del(&tbc->wd_timer);
  17780. + dect_timer_del(&tbc->wait_timer);
  17781. + dect_timer_del(&tbc->release_timer);
  17782. + dect_timer_del(&tbc->enc_timer);
  17783. + dect_bc_release(&tbc->bc);
  17784. +
  17785. + dect_channel_release(cell, tbc->txb.trx, &tbc->txb.chd);
  17786. + dect_bearer_release(cell, &tbc->txb);
  17787. +
  17788. + dect_channel_release(cell, tbc->rxb.trx, &tbc->rxb.chd);
  17789. + dect_bearer_release(cell, &tbc->rxb);
  17790. +
  17791. + list_del(&tbc->list);
  17792. + kfree_skb(tbc->cs_tx_skb);
  17793. + kfree(tbc);
  17794. +}
  17795. +
  17796. +static void dect_tbc_release_timer(struct dect_cell *cell, void *data)
  17797. +{
  17798. + struct dect_tbc *tbc = data;
  17799. +
  17800. + switch (tbc->state) {
  17801. + default:
  17802. + dect_tbc_state_change(tbc, DECT_TBC_RELEASING);
  17803. + break;
  17804. + case DECT_TBC_RELEASING:
  17805. + dect_tbc_state_change(tbc, DECT_TBC_RELEASED);
  17806. + break;
  17807. + case DECT_TBC_NONE:
  17808. + case DECT_TBC_REQ_SENT:
  17809. + case DECT_TBC_RELEASED:
  17810. + return dect_tbc_destroy(cell, tbc);
  17811. + }
  17812. +
  17813. + dect_tbc_send_release(tbc, tbc->release_reason);
  17814. + dect_bearer_timer_add(tbc->cell, &tbc->txb, &tbc->release_timer,
  17815. + DECT_MT_FRAME_RATE);
  17816. +}
  17817. +
  17818. +static void dect_tbc_begin_release(struct dect_cell *cell, struct dect_tbc *tbc,
  17819. + enum dect_release_reasons reason)
  17820. +{
  17821. + tbc->release_reason = reason;
  17822. + dect_tbc_release_timer(cell, tbc);
  17823. +}
  17824. +
  17825. +static void dect_tbc_dis_req(const struct dect_cell_handle *ch,
  17826. + const struct dect_tbc_id *id,
  17827. + enum dect_release_reasons reason)
  17828. +{
  17829. + struct dect_cell *cell = dect_cell(ch);
  17830. + struct dect_tbc *tbc;
  17831. +
  17832. + tbc = dect_tbc_get_by_tbei(cell, id->tbei);
  17833. + if (tbc == NULL)
  17834. + return;
  17835. + tbc_debug(tbc, "TBC_DIS-req: reason: %u\n", reason);
  17836. + dect_tbc_begin_release(cell, tbc, reason);
  17837. +}
  17838. +
  17839. +static int dect_tbc_establish(struct dect_cell *cell, struct dect_tbc *tbc)
  17840. +{
  17841. + dect_tbc_state_change(tbc, DECT_TBC_ESTABLISHED);
  17842. + if (dect_tbc_establish_cfm(tbc, true) < 0)
  17843. + return -1;
  17844. + return 0;
  17845. +}
  17846. +
  17847. +/**
  17848. + * dect_watchdog_timer - connection watchdog timer
  17849. + *
  17850. + * The watchdog timer is forwarded when an expected event occurs, on expiry
  17851. + * it will release the TBC. The relevant event depends on the TBC's state:
  17852. + *
  17853. + * Until ESTABLISHED state, P_T tails must be sent in every allowed frame.
  17854. + * The timer is forwarded when receiving a P_T tail in an allowed frame.
  17855. + *
  17856. + * In ESTABLISHED state, an RFPI handshake must be received at least
  17857. + * every T201 (5) seconds. The timer is forwarded when receiving an N_T
  17858. + * tail containing a matching RFPI.
  17859. + */
  17860. +static void dect_tbc_watchdog_timer(struct dect_cell *cell, void *data)
  17861. +{
  17862. + struct dect_tbc *tbc = data;
  17863. +
  17864. + tbc_debug(tbc, "watchdog expire\n");
  17865. + if (tbc->state != DECT_TBC_ESTABLISHED) {
  17866. + dect_tbc_establish_cfm(tbc, false);
  17867. + dect_tbc_begin_release(cell, tbc, DECT_REASON_BEARER_SETUP_OR_HANDOVER_FAILED);
  17868. + } else {
  17869. + dect_tbc_release_notify(tbc, DECT_REASON_TIMEOUT_LOST_HANDSHAKE);
  17870. + dect_tbc_begin_release(cell, tbc, DECT_REASON_TIMEOUT_LOST_HANDSHAKE);
  17871. + }
  17872. +}
  17873. +
  17874. +static void dect_tbc_watchdog_reschedule(struct dect_cell *cell,
  17875. + struct dect_tbc *tbc)
  17876. +{
  17877. + u16 timeout;
  17878. +
  17879. + if (tbc->state == DECT_TBC_ESTABLISHED)
  17880. + timeout = DECT_TBC_RFPI_TIMEOUT;
  17881. + else
  17882. + timeout = DECT_MT_FRAME_RATE;
  17883. +
  17884. + tbc_debug(tbc, "watchdog reschedule timeout: %u\n", timeout);
  17885. + dect_bearer_timer_add(cell, &tbc->rxb, &tbc->wd_timer, timeout);
  17886. +}
  17887. +
  17888. +static int dect_tbc_check_attributes(struct dect_cell *cell, struct dect_tbc *tbc,
  17889. + const struct dect_cctrl *cctl)
  17890. +{
  17891. + const struct dect_cluster_handle *clh = cell->handle.clh;
  17892. +
  17893. + tbc_debug(tbc, "RX ATTRIBUTES_T_REQUEST\n");
  17894. + tbc->id.ecn = cctl->attr.ecn;
  17895. + tbc->id.lbn = cctl->attr.lbn;
  17896. + tbc->mcp.service = cctl->attr.service;
  17897. + tbc->mcp.slot = cctl->attr.slot;
  17898. +
  17899. + if (clh->ops->tbc_establish_ind(clh, &cell->handle, &tbc->id,
  17900. + &tbc->mcp, tbc->handover) < 0)
  17901. + return -1;
  17902. + return 0;
  17903. +}
  17904. +
  17905. +/**
  17906. + * dect_tbc_state_process - connection setup and maintenance state proccesing
  17907. + *
  17908. + * Process all messages before ESTABLISHED state, as well as all connection
  17909. + * control messages in ESTABLISHED state.
  17910. + */
  17911. +static int dect_tbc_state_process(struct dect_cell *cell, struct dect_tbc *tbc,
  17912. + const struct dect_tail_msg *tm)
  17913. +{
  17914. + const struct dect_cctrl *cctl = &tm->cctl;
  17915. + u8 framenum;
  17916. +
  17917. + if (tbc->state == DECT_TBC_OTHER_WAIT) {
  17918. + tbc_debug(tbc, "RX in OTHER_WAIT\n");
  17919. + /* Any message except RELEASE switches the bearer to
  17920. + * ESTABLISHED state.
  17921. + */
  17922. + if ((tm->type == DECT_TM_TYPE_BCCTRL ||
  17923. + tm->type == DECT_TM_TYPE_ACCTRL) &&
  17924. + (cctl->fmid != cell->fmid ||
  17925. + cctl->pmid != dect_build_pmid(&tbc->id.pmid) ||
  17926. + cctl->cmd == DECT_CCTRL_RELEASE))
  17927. + goto release;
  17928. +
  17929. + if (dect_tbc_establish(cell, tbc) < 0)
  17930. + goto release;
  17931. + goto out;
  17932. + }
  17933. +
  17934. + /* Before OTHER_WAIT state, M_T tails must be received in every allowed
  17935. + * frame. FPs may send M_T tails in uneven frames, PTs in even frames.
  17936. + * Additionally FPs may transmit responses to BEARER_REQUEST messages in
  17937. + * every frame.
  17938. + */
  17939. + framenum = dect_framenum(cell, DECT_TIMER_RX);
  17940. + if (cell->mode == DECT_MODE_FP) {
  17941. + if ((framenum & 0x1) == 1)
  17942. + return 1;
  17943. + } else {
  17944. + if ((framenum & 0x1) == 0 && tbc->state != DECT_TBC_REQ_SENT)
  17945. + return 1;
  17946. + }
  17947. +
  17948. + if (tm->type != DECT_TM_TYPE_BCCTRL && tm->type != DECT_TM_TYPE_ACCTRL)
  17949. + goto release;
  17950. +
  17951. + switch (cctl->cmd) {
  17952. + case DECT_CCTRL_ATTRIBUTES_T_REQUEST:
  17953. + case DECT_CCTRL_ATTRIBUTES_T_CONFIRM:
  17954. + case DECT_CCTRL_BANDWIDTH_T_REQUEST:
  17955. + case DECT_CCTRL_BANDWIDTH_T_CONFIRM:
  17956. + case DECT_CCTRL_CHANNEL_LIST:
  17957. + break;
  17958. + default:
  17959. + if (cctl->fmid != cell->fmid)
  17960. + goto release;
  17961. + /* fall through */
  17962. + case DECT_CCTRL_RELEASE:
  17963. + if (cctl->pmid != dect_build_pmid(&tbc->id.pmid))
  17964. + goto release;
  17965. + }
  17966. +
  17967. + switch ((int)tbc->state) {
  17968. + case DECT_TBC_NONE:
  17969. + /*
  17970. + * Receiving side, initial request.
  17971. + */
  17972. + dect_tbc_state_change(tbc, DECT_TBC_REQ_RCVD);
  17973. + break;
  17974. +
  17975. + case DECT_TBC_REQ_RCVD:
  17976. + case DECT_TBC_RESPONSE_SENT:
  17977. + /*
  17978. + * Receiving side: waiting for LLME to create MBC. Only "WAIT"
  17979. + * messages are valid in both directions.
  17980. + */
  17981. + tbc_debug(tbc, "RX in REQ_RCVD: %llx\n",
  17982. + (unsigned long long)cctl->cmd);
  17983. +
  17984. + if (tbc->mcp.type == DECT_MAC_CONN_ADVANCED &&
  17985. + cctl->cmd == DECT_CCTRL_ATTRIBUTES_T_REQUEST)
  17986. + dect_tbc_check_attributes(cell, tbc, cctl);
  17987. + else if (cctl->cmd != DECT_CCTRL_WAIT)
  17988. + goto release;
  17989. +
  17990. + if (dect_tbc_send_wait(tbc) < 0)
  17991. + goto release;
  17992. + break;
  17993. +
  17994. + case DECT_TBC_REQ_SENT:
  17995. + case DECT_TBC_WAIT_RCVD:
  17996. + /*
  17997. + * Initiator: request was sent, waiting for confirm. "WAIT"
  17998. + * messages must be responded to with another "WAIT" message.
  17999. + */
  18000. + tbc_debug(tbc, "Reply in REQ_SENT %u\n", tm->type);
  18001. + if (cctl->cmd != DECT_CCTRL_BEARER_CONFIRM) {
  18002. + if (cctl->cmd != DECT_CCTRL_WAIT)
  18003. + goto release;
  18004. + if (dect_tbc_send_wait(tbc) < 0)
  18005. + goto release;
  18006. + dect_tbc_state_change(tbc, DECT_TBC_WAIT_RCVD);
  18007. + } else {
  18008. + tbc_debug(tbc, "Confirmed\n");
  18009. + if (tbc->mcp.type == DECT_MAC_CONN_BASIC) {
  18010. + if (dect_tbc_send_wait(tbc) < 0)
  18011. + goto release;
  18012. + dect_tbc_state_change(tbc, DECT_TBC_OTHER_WAIT);
  18013. + } else {
  18014. + if (dect_tbc_send_attributes_request(tbc) < 0)
  18015. + goto release;
  18016. + dect_tbc_state_change(tbc, DECT_TBC_ATTRIBUTES_SENT);
  18017. + }
  18018. + }
  18019. + break;
  18020. +
  18021. + case DECT_TBC_ATTRIBUTES_SENT:
  18022. + if (cctl->cmd != DECT_CCTRL_ATTRIBUTES_T_CONFIRM) {
  18023. + if (cctl->cmd != DECT_CCTRL_WAIT)
  18024. + goto release;
  18025. + if (dect_tbc_send_wait(tbc) < 0)
  18026. + goto release;
  18027. + } else {
  18028. + if (dect_tbc_send_wait(tbc) < 0)
  18029. + goto release;
  18030. + dect_tbc_state_change(tbc, DECT_TBC_OTHER_WAIT);
  18031. + }
  18032. + break;
  18033. +
  18034. + case DECT_TBC_ESTABLISHED:
  18035. + if (cctl->cmd != DECT_CCTRL_RELEASE)
  18036. + break;
  18037. + /* Immediate release */
  18038. + dect_tbc_release_notify(tbc, DECT_REASON_BEARER_RELEASE);
  18039. + dect_tbc_destroy(cell, tbc);
  18040. + return 0;
  18041. +
  18042. + case DECT_TBC_RELEASING:
  18043. + /*
  18044. + * Unacknowledged release procedure in progress, ignore the
  18045. + * packet unless its a release message, in which case the
  18046. + * bearer can be destroyed immediately (crossed bearer release
  18047. + * procedure).
  18048. + */
  18049. + if (cctl->cmd == DECT_CCTRL_RELEASE)
  18050. + dect_tbc_destroy(cell, tbc);
  18051. +
  18052. + case DECT_TBC_RELEASED:
  18053. + return 0;
  18054. + }
  18055. +
  18056. +out:
  18057. + dect_tbc_watchdog_reschedule(cell, tbc);
  18058. + return 1;
  18059. +
  18060. +release:
  18061. + dect_tbc_establish_cfm(tbc, false);
  18062. + dect_tbc_begin_release(cell, tbc, DECT_REASON_UNKNOWN);
  18063. + return 0;
  18064. +}
  18065. +
  18066. +static void dect_tbc_enc_timer(struct dect_cell *cell, void *data)
  18067. +{
  18068. + struct dect_tbc *tbc = data;
  18069. + enum dect_encctrl_cmds cmd;
  18070. + struct sk_buff *skb;
  18071. +
  18072. + tbc_debug(tbc, "encryption timer: state: %u cnt: %u\n",
  18073. + tbc->enc_state, tbc->enc_msg_cnt);
  18074. +
  18075. + if (++tbc->enc_msg_cnt > 5) {
  18076. + dect_tbc_release_notify(tbc, DECT_REASON_BEARER_RELEASE);
  18077. + return dect_tbc_begin_release(cell, tbc, DECT_REASON_BEARER_RELEASE);
  18078. + }
  18079. +
  18080. + dect_bearer_timer_add(cell, &tbc->txb, &tbc->enc_timer, 2);
  18081. +
  18082. + switch (tbc->enc_state) {
  18083. + case DECT_TBC_ENC_START_REQ_RCVD:
  18084. + tbc_debug(tbc, "TX encryption enabled\n");
  18085. + dect_enable_cipher(tbc->txb.trx, &tbc->txb.chd, tbc->ck);
  18086. + /* fall through */
  18087. + case DECT_TBC_ENC_START_CFM_SENT:
  18088. + tbc->enc_state = DECT_TBC_ENC_START_CFM_SENT;
  18089. + cmd = DECT_ENCCTRL_START_CONFIRM;
  18090. + break;
  18091. + case DECT_TBC_ENC_START_REQ_SENT:
  18092. + cmd = DECT_ENCCTRL_START_REQUEST;
  18093. + break;
  18094. + case DECT_TBC_ENC_STOP_REQ_RCVD:
  18095. + tbc_debug(tbc, "TX encryption disabled\n");
  18096. + dect_disable_cipher(tbc->txb.trx, &tbc->txb.chd);
  18097. + /* fall through */
  18098. + case DECT_TBC_ENC_STOP_CFM_SENT:
  18099. + tbc->enc_state = DECT_TBC_ENC_STOP_CFM_SENT;
  18100. + cmd = DECT_ENCCTRL_STOP_CONFIRM;
  18101. + break;
  18102. + case DECT_TBC_ENC_STOP_REQ_SENT:
  18103. + cmd = DECT_ENCCTRL_STOP_REQUEST;
  18104. + break;
  18105. + default:
  18106. + return;
  18107. + }
  18108. +
  18109. + skb = dect_tbc_build_encctrl(tbc, cmd);
  18110. + if (skb != NULL)
  18111. + dect_tbc_queue_mac_control(tbc, skb);
  18112. +}
  18113. +
  18114. +static int dect_tbc_enc_state_process(struct dect_cell *cell,
  18115. + struct dect_tbc *tbc,
  18116. + const struct dect_tail_msg *tm)
  18117. +{
  18118. + const struct dect_encctrl *ectl = &tm->encctl;
  18119. + struct sk_buff *skb;
  18120. +
  18121. + if (ectl->fmid != cell->fmid ||
  18122. + ectl->pmid != dect_build_pmid(&tbc->id.pmid))
  18123. + return 0;
  18124. +
  18125. + switch (ectl->cmd) {
  18126. + case DECT_ENCCTRL_START_REQUEST:
  18127. + if (tbc->enc_state != DECT_TBC_ENC_DISABLED ||
  18128. + cell->mode != DECT_MODE_FP)
  18129. + break;
  18130. + tbc->enc_state = DECT_TBC_ENC_START_REQ_RCVD;
  18131. + tbc->enc_msg_cnt = 0;
  18132. +
  18133. + dect_bearer_timer_add(cell, &tbc->txb, &tbc->enc_timer, 0);
  18134. + break;
  18135. + case DECT_ENCCTRL_START_CONFIRM:
  18136. + if (tbc->enc_state == DECT_TBC_ENC_START_REQ_SENT) {
  18137. + tbc->enc_state = DECT_TBC_ENC_START_CFM_RCVD;
  18138. + tbc->enc_msg_cnt = 0;
  18139. +
  18140. + dect_timer_del(&tbc->enc_timer);
  18141. + tbc_debug(tbc, "TX encryption enabled\n");
  18142. + dect_enable_cipher(tbc->txb.trx, &tbc->txb.chd, tbc->ck);
  18143. + }
  18144. + if (tbc->enc_state == DECT_TBC_ENC_START_CFM_RCVD) {
  18145. + skb = dect_tbc_build_encctrl(tbc, DECT_ENCCTRL_START_GRANT);
  18146. + if (skb != NULL)
  18147. + dect_tbc_queue_mac_control(tbc, skb);
  18148. + }
  18149. + break;
  18150. + case DECT_ENCCTRL_START_GRANT:
  18151. + if (tbc->enc_state != DECT_TBC_ENC_START_CFM_SENT)
  18152. + break;
  18153. + tbc->enc_state = DECT_TBC_ENC_ENABLED;
  18154. +
  18155. + dect_timer_del(&tbc->enc_timer);
  18156. + tbc_debug(tbc, "RX encryption enabled\n");
  18157. + dect_enable_cipher(tbc->rxb.trx, &tbc->rxb.chd, tbc->ck);
  18158. + dect_tbc_event(tbc, DECT_TBC_CIPHER_ENABLED);
  18159. + break;
  18160. +
  18161. + case DECT_ENCCTRL_STOP_REQUEST:
  18162. + if (cell->mode != DECT_MODE_FP)
  18163. + break;
  18164. +
  18165. + tbc->enc_state = DECT_TBC_ENC_STOP_REQ_RCVD;
  18166. + tbc->enc_msg_cnt = 0;
  18167. +
  18168. + dect_bearer_timer_add(cell, &tbc->txb, &tbc->enc_timer, 0);
  18169. + break;
  18170. + case DECT_ENCCTRL_STOP_CONFIRM:
  18171. + if (tbc->enc_state == DECT_TBC_ENC_STOP_REQ_SENT) {
  18172. + tbc->enc_state = DECT_TBC_ENC_STOP_CFM_RCVD;
  18173. + tbc->enc_msg_cnt = 0;
  18174. +
  18175. + dect_timer_del(&tbc->enc_timer);
  18176. + tbc_debug(tbc, "TX encryption disabled\n");
  18177. + dect_disable_cipher(tbc->txb.trx, &tbc->txb.chd);
  18178. + }
  18179. + if (tbc->enc_state == DECT_TBC_ENC_STOP_CFM_RCVD) {
  18180. + skb = dect_tbc_build_encctrl(tbc, DECT_ENCCTRL_STOP_GRANT);
  18181. + if (skb != NULL)
  18182. + dect_tbc_queue_mac_control(tbc, skb);
  18183. + }
  18184. + break;
  18185. + case DECT_ENCCTRL_STOP_GRANT:
  18186. + if (tbc->enc_state != DECT_TBC_ENC_STOP_CFM_SENT)
  18187. + break;
  18188. + tbc->enc_state = DECT_TBC_CIPHER_DISABLED;
  18189. +
  18190. + dect_timer_del(&tbc->enc_timer);
  18191. + tbc_debug(tbc, "RX encryption disabled\n");
  18192. + dect_disable_cipher(tbc->txb.trx, &tbc->txb.chd);
  18193. + dect_tbc_event(tbc, DECT_TBC_CIPHER_DISABLED);
  18194. + break;
  18195. + default:
  18196. + return 0;
  18197. + }
  18198. + return 1;
  18199. +}
  18200. +
  18201. +static void dect_tbc_queue_cs_data(struct dect_cell *cell, struct dect_tbc *tbc,
  18202. + struct sk_buff *skb,
  18203. + const struct dect_tail_msg *tm)
  18204. +{
  18205. + const struct dect_cluster_handle *clh = cell->handle.clh;
  18206. +
  18207. + skb = skb_clone(skb, GFP_ATOMIC);
  18208. + if (skb == NULL)
  18209. + return;
  18210. + skb_pull(skb, DECT_T_FIELD_OFF);
  18211. + skb_trim(skb, DECT_C_S_SDU_SIZE);
  18212. +
  18213. + DECT_CS_CB(skb)->seq = tm->ctd.seq;
  18214. + clh->ops->tbc_data_ind(clh, &tbc->id, DECT_MC_C_S, skb);
  18215. +}
  18216. +
  18217. +static void dect_tbc_update_handover_state(struct dect_tbc *tbc, bool ok)
  18218. +{
  18219. + const struct dect_cluster_handle *clh = tbc->cell->handle.clh;
  18220. +
  18221. + if (ok) {
  18222. + tbc->handover_tokens += DECT_TBC_HO_TOKENS_OK;
  18223. + if (tbc->handover_tokens > DECT_TBC_HO_TOKENS_MAX)
  18224. + tbc->handover_tokens = DECT_TBC_HO_TOKENS_MAX;
  18225. + } else {
  18226. + tbc->handover_tokens -= DECT_TBC_HO_TOKENS_ERROR;
  18227. + if (tbc->handover_tokens < 0)
  18228. + tbc->handover_tokens = 0;
  18229. + }
  18230. +
  18231. + tbc_debug(tbc, "handover: ok: %u tokens: %d\n", ok, tbc->handover_tokens);
  18232. + if (tbc->handover_tokens == 0)
  18233. + clh->ops->tbc_handover_req(clh, &tbc->id);
  18234. +}
  18235. +
  18236. +static void dect_tbc_report_rssi(struct dect_cell *cell,
  18237. + struct dect_bearer *bearer,
  18238. + u8 slot, u8 rssi)
  18239. +{
  18240. + struct dect_tbc *tbc = bearer->tbc;
  18241. +
  18242. + /* A RSSI report implies an In-Sync error */
  18243. + if (cell->mode == DECT_MODE_PP)
  18244. + dect_tbc_update_handover_state(tbc, false);
  18245. +}
  18246. +
  18247. +#define DECT_CHECKSUM_ALL \
  18248. + (DECT_CHECKSUM_A_CRC_OK | DECT_CHECKSUM_X_CRC_OK | DECT_CHECKSUM_Z_CRC_OK)
  18249. +
  18250. +static bool dect_tbc_checksum_ok(const struct sk_buff *skb)
  18251. +{
  18252. + return (DECT_TRX_CB(skb)->csum & DECT_CHECKSUM_ALL) == DECT_CHECKSUM_ALL;
  18253. +}
  18254. +
  18255. +static void dect_tbc_rcv(struct dect_cell *cell, struct dect_bearer *bearer,
  18256. + struct sk_buff *skb)
  18257. +{
  18258. + const struct dect_cluster_handle *clh = cell->handle.clh;
  18259. + struct dect_tbc *tbc = bearer->tbc;
  18260. + struct dect_tail_msg _tm, *tm = &_tm;
  18261. + bool a_crc_ok, collision;
  18262. + bool q1, q2;
  18263. +
  18264. + dect_raw_rcv(skb);
  18265. +
  18266. + if (cell->mode == DECT_MODE_PP)
  18267. + dect_tbc_update_handover_state(tbc, dect_tbc_checksum_ok(skb));
  18268. +
  18269. + /* Verify A-field checksum. Sucessful reception of the A-field is
  18270. + * indicated by transmitting the Q2 bit in the reverse direction
  18271. + * or the Q1 bit in the direction FP->PP when Q1 is set to 0.
  18272. + */
  18273. + if (DECT_TRX_CB(skb)->csum & DECT_CHECKSUM_A_CRC_OK)
  18274. + tbc->txb.q = DECT_HDR_Q2_FLAG;
  18275. + else
  18276. + goto rcv_b_field;
  18277. +
  18278. + /* Q1 and Q2 bit settings for MAC service IN as per section 10.8.1.3.1 */
  18279. + q1 = skb->data[DECT_HDR_Q1_OFF] & DECT_HDR_Q1_FLAG;
  18280. + q2 = skb->data[DECT_HDR_Q2_OFF] & DECT_HDR_Q2_FLAG;
  18281. +
  18282. + if (cell->mode == DECT_MODE_FP)
  18283. + a_crc_ok = q2;
  18284. + else {
  18285. + if (q2) {
  18286. + a_crc_ok = true;
  18287. + collision = q1;
  18288. + /* ignore collision indications for now as the
  18289. + * transceiver firmware seems to improperly transmit
  18290. + * the Z-Field.
  18291. + */
  18292. + collision = false;
  18293. + } else {
  18294. + a_crc_ok = q1;
  18295. + collision = false;
  18296. + }
  18297. +
  18298. + dect_tbc_update_handover_state(tbc, a_crc_ok && !collision);
  18299. + }
  18300. +
  18301. + if (tbc->cs_tx_ok) {
  18302. + if (a_crc_ok) {
  18303. + tbc_debug(tbc, "ARQ acknowledgement\n");
  18304. + dect_tbc_event(tbc, DECT_TBC_ACK_RECEIVED);
  18305. + } else
  18306. + tbc_debug(tbc, "C-channel data lost\n");
  18307. + }
  18308. +
  18309. + if (dect_parse_tail_msg(tm, skb) < 0)
  18310. + goto err;
  18311. +
  18312. + if (tbc->state != DECT_TBC_ESTABLISHED ||
  18313. + tm->type == DECT_TM_TYPE_BCCTRL ||
  18314. + tm->type == DECT_TM_TYPE_ACCTRL) {
  18315. + if (!dect_tbc_state_process(cell, tbc, tm))
  18316. + goto err;
  18317. + }
  18318. +
  18319. + tbc_debug(tbc, "receive\n");
  18320. +
  18321. + /* Reschedule watchdog on successful RFPI handshake. */
  18322. + if (tm->type == DECT_TM_TYPE_ID && !dect_rfpi_cmp(&tm->idi, &cell->idi))
  18323. + dect_tbc_watchdog_reschedule(cell, tbc);
  18324. +
  18325. + if (tm->type == DECT_TM_TYPE_ENCCTRL) {
  18326. + if (!dect_tbc_enc_state_process(cell, tbc, tm))
  18327. + goto err;
  18328. + }
  18329. +
  18330. + dect_bc_rcv(cell, &tbc->bc, skb, tm);
  18331. +
  18332. + switch (tbc->enc_state) {
  18333. + case DECT_TBC_ENC_START_REQ_SENT:
  18334. + case DECT_TBC_ENC_START_CFM_SENT:
  18335. + goto err;
  18336. + default:
  18337. + break;
  18338. + }
  18339. +
  18340. + if (tbc->state != DECT_TBC_REQ_RCVD &&
  18341. + tbc->state != DECT_TBC_RESPONSE_SENT) {
  18342. + if (tm->type == DECT_TM_TYPE_CT)
  18343. + dect_tbc_queue_cs_data(cell, tbc, skb, tm);
  18344. + }
  18345. +
  18346. +rcv_b_field:
  18347. + switch (dect_parse_b_id(skb)) {
  18348. + case DECT_BI_UTYPE_0:
  18349. + case DECT_BI_UTYPE_1:
  18350. + break;
  18351. + default:
  18352. + goto err;
  18353. + }
  18354. +
  18355. + skb_pull(skb, DECT_A_FIELD_SIZE);
  18356. + skb_trim(skb, dect_pkt_b_field_size(&bearer->chd));
  18357. + clh->ops->tbc_data_ind(clh, &tbc->id, DECT_MC_I_N, skb);
  18358. + return;
  18359. +
  18360. +err:
  18361. + kfree_skb(skb);
  18362. +}
  18363. +
  18364. +static void dect_tbc_data_req(const struct dect_cell_handle *ch,
  18365. + const struct dect_tbc_id *id,
  18366. + enum dect_data_channels chan,
  18367. + struct sk_buff *skb)
  18368. +{
  18369. + struct dect_cell *cell = dect_cell(ch);
  18370. + struct dect_tbc *tbc;
  18371. +
  18372. + tbc = dect_tbc_get_by_tbei(cell, id->tbei);
  18373. + if (tbc == NULL)
  18374. + goto err;
  18375. + tbc_debug(tbc, "TBC_DATA-req: chan: %u len: %u\n", chan, skb->len);
  18376. +
  18377. + switch (chan) {
  18378. + case DECT_MC_C_S:
  18379. + DECT_A_CB(skb)->id = DECT_CS_CB(skb)->seq ? DECT_TI_CT_PKT_1 :
  18380. + DECT_TI_CT_PKT_0;
  18381. + tbc->cs_tx_skb = skb;
  18382. + break;
  18383. + case DECT_MC_I_N:
  18384. + tbc->b_tx_skb = skb;
  18385. + break;
  18386. + default:
  18387. + goto err;
  18388. + }
  18389. + return;
  18390. +
  18391. +err:
  18392. + kfree_skb(skb);
  18393. +}
  18394. +
  18395. +static int dect_tbc_enc_req(const struct dect_cell_handle *ch,
  18396. + const struct dect_tbc_id *id, u64 ck)
  18397. +{
  18398. + struct dect_cell *cell = dect_cell(ch);
  18399. + struct dect_tbc *tbc;
  18400. +
  18401. + tbc = dect_tbc_get_by_tbei(cell, id->tbei);
  18402. + if (tbc == NULL)
  18403. + return -ENOENT;
  18404. +
  18405. + tbc_debug(tbc, "RX/TX encryption enabled: ck: %.16llx\n",
  18406. + (unsigned long long)ck);
  18407. +
  18408. + tbc->ck = ck;
  18409. + dect_enable_cipher(tbc->rxb.trx, &tbc->rxb.chd, tbc->ck);
  18410. + dect_enable_cipher(tbc->txb.trx, &tbc->txb.chd, tbc->ck);
  18411. + return 0;
  18412. +}
  18413. +
  18414. +static int dect_tbc_enc_eks_req(const struct dect_cell_handle *ch,
  18415. + const struct dect_tbc_id *id,
  18416. + enum dect_cipher_states status)
  18417. +{
  18418. + struct dect_cell *cell = dect_cell(ch);
  18419. + struct dect_tbc *tbc;
  18420. + struct sk_buff *skb;
  18421. +
  18422. + tbc = dect_tbc_get_by_tbei(cell, id->tbei);
  18423. + if (tbc == NULL)
  18424. + return -ENOENT;
  18425. +
  18426. + tbc_debug(tbc, "TBC_ENC_EKS-req: status: %u\n", status);
  18427. + if (status == DECT_CIPHER_ENABLED) {
  18428. + skb = dect_tbc_build_encctrl(tbc, DECT_ENCCTRL_START_REQUEST);
  18429. + if (skb != NULL)
  18430. + dect_tbc_queue_mac_control(tbc, skb);
  18431. + tbc->enc_state = DECT_TBC_ENC_START_REQ_SENT;
  18432. +
  18433. + tbc_debug(tbc, "RX encryption enabled\n");
  18434. + dect_enable_cipher(tbc->rxb.trx, &tbc->rxb.chd, tbc->ck);
  18435. + } else {
  18436. + skb = dect_tbc_build_encctrl(tbc, DECT_ENCCTRL_STOP_REQUEST);
  18437. + if (skb != NULL)
  18438. + dect_tbc_queue_mac_control(tbc, skb);
  18439. + tbc->enc_state = DECT_TBC_ENC_STOP_REQ_SENT;
  18440. + }
  18441. +
  18442. + tbc->enc_msg_cnt = 0;
  18443. + dect_bearer_timer_add(cell, &tbc->txb, &tbc->enc_timer, 0);
  18444. + return 0;
  18445. +}
  18446. +
  18447. +static int dect_tbc_enc_key_req(const struct dect_cell_handle *ch,
  18448. + const struct dect_tbc_id *id, u64 ck)
  18449. +{
  18450. + struct dect_cell *cell = dect_cell(ch);
  18451. + struct dect_tbc *tbc;
  18452. +
  18453. + tbc = dect_tbc_get_by_tbei(cell, id->tbei);
  18454. + if (tbc == NULL)
  18455. + return -ENOENT;
  18456. +
  18457. + tbc_debug(tbc, "TBC_ENC_KEY-req: key: %.16llx\n", (unsigned long long)ck);
  18458. + tbc->ck = ck;
  18459. + return 0;
  18460. +}
  18461. +
  18462. +static void dect_tbc_enable(struct dect_cell *cell, struct dect_tbc *tbc)
  18463. +{
  18464. + dect_bearer_enable(&tbc->rxb);
  18465. + dect_bearer_enable(&tbc->txb);
  18466. + dect_bc_init(cell, &tbc->bc);
  18467. +}
  18468. +
  18469. +/*
  18470. + * Activation timer: enable the bearer once the TX channel is accessible,
  18471. + * which is defined by the receivers scanning sequence.
  18472. + */
  18473. +static void dect_tbc_enable_timer(struct dect_cell *cell,
  18474. + struct dect_bearer *bearer)
  18475. +{
  18476. + struct dect_tbc *tbc = bearer->tbc;
  18477. + struct sk_buff *skb, *b_skb;
  18478. + enum dect_cctrl_cmds cmd;
  18479. +
  18480. + tbc_debug(tbc, "TX ACCESS_REQUEST\n");
  18481. + if (tbc->handover)
  18482. + cmd = DECT_CCTRL_BEARER_HANDOVER_REQ;
  18483. + else
  18484. + cmd = DECT_CCTRL_ACCESS_REQ;
  18485. +
  18486. + skb = dect_tbc_build_cctrl(tbc, cmd);
  18487. + if (skb == NULL)
  18488. + return;
  18489. +
  18490. + /* The packet overrides the T-MUX rules. PPs use a special tail
  18491. + * coding for the first transmission. */
  18492. + skb->priority = DECT_MT_HIGH_PRIORITY;
  18493. + if (cell->mode == DECT_MODE_FP)
  18494. + DECT_A_CB(skb)->id = DECT_TI_MT;
  18495. + else
  18496. + DECT_A_CB(skb)->id = DECT_TI_MT_PKT_0;
  18497. +
  18498. + if (tbc->mcp.type == DECT_MAC_CONN_ADVANCED) {
  18499. + b_skb = dect_b_skb_alloc(&tbc->txb.chd);
  18500. + if (b_skb == NULL)
  18501. + goto err1;
  18502. + DECT_B_CB(b_skb)->id = dect_pkt_to_bi(tbc->txb.chd.pkt);
  18503. + tbc->b_tx_skb = b_skb;
  18504. + }
  18505. +
  18506. + dect_tbc_enable(cell, tbc);
  18507. + dect_tbc_queue_mac_control(tbc, skb);
  18508. + dect_tbc_state_change(tbc, DECT_TBC_REQ_SENT);
  18509. +
  18510. + /* Start watchdog */
  18511. + dect_bearer_timer_add(cell, &tbc->rxb, &tbc->wd_timer, 1);
  18512. + return;
  18513. +
  18514. +err1:
  18515. + kfree_skb(skb);
  18516. + //FIXME: indicate error
  18517. +}
  18518. +
  18519. +static const struct dect_bearer_ops dect_tbc_ops = {
  18520. + .state = DECT_TRAFFIC_BEARER,
  18521. + .enable = dect_tbc_enable_timer,
  18522. + .rcv = dect_tbc_rcv,
  18523. + .report_rssi = dect_tbc_report_rssi,
  18524. +};
  18525. +
  18526. +/**
  18527. + * dect_tbc_init - initialise a traffic bearer control instance
  18528. + *
  18529. + * @cell: DECT cell
  18530. + * @id: MBC ID
  18531. + * @rchd: RX channel description
  18532. + * @tchd: TX channel description
  18533. + */
  18534. +static struct dect_tbc *dect_tbc_init(struct dect_cell *cell,
  18535. + const struct dect_tbc_id *id,
  18536. + struct dect_transceiver *rtrx,
  18537. + struct dect_transceiver *ttrx,
  18538. + const struct dect_channel_desc *rchd,
  18539. + const struct dect_channel_desc *tchd)
  18540. +{
  18541. + struct dect_tbc *tbc;
  18542. +
  18543. + tbc = kzalloc(sizeof(*tbc), GFP_ATOMIC);
  18544. + if (tbc == NULL)
  18545. + return NULL;
  18546. +
  18547. + tbc->cell = cell;
  18548. + tbc->id = *id;
  18549. + tbc->handover_tokens = DECT_TBC_HO_TOKENS_INITIAL;
  18550. +
  18551. + INIT_LIST_HEAD(&tbc->bc.list);
  18552. + dect_timer_init(&tbc->wait_timer);
  18553. + dect_timer_setup(&tbc->wd_timer, dect_tbc_watchdog_timer, tbc);
  18554. + dect_timer_setup(&tbc->release_timer, dect_tbc_release_timer, tbc);
  18555. + dect_timer_setup(&tbc->enc_timer, dect_tbc_enc_timer, tbc);
  18556. +
  18557. + dect_bearer_init(cell, &tbc->rxb, &dect_tbc_ops,
  18558. + rtrx, rchd, DECT_BEARER_RX, tbc);
  18559. + dect_bearer_init(cell, &tbc->txb, &dect_tbc_ops,
  18560. + ttrx, tchd, DECT_BEARER_TX, tbc);
  18561. +
  18562. + list_add_tail(&tbc->list, &cell->tbcs);
  18563. + return tbc;
  18564. +}
  18565. +
  18566. +static int dect_tbc_map_params(struct dect_channel_desc *chd,
  18567. + const struct dect_mac_conn_params *mcp)
  18568. +{
  18569. + switch (mcp->service) {
  18570. + case DECT_SERVICE_IN_MIN_DELAY:
  18571. + case DECT_SERVICE_IN_NORMAL_DELAY:
  18572. + case DECT_SERVICE_UNKNOWN:
  18573. + chd->b_fmt = DECT_B_UNPROTECTED;
  18574. + break;
  18575. + default:
  18576. + return -EOPNOTSUPP;
  18577. + }
  18578. +
  18579. + switch (mcp->slot) {
  18580. + case DECT_FULL_SLOT:
  18581. + chd->pkt = DECT_PACKET_P32;
  18582. + break;
  18583. + case DECT_DOUBLE_SLOT:
  18584. + chd->pkt = DECT_PACKET_P80;
  18585. + break;
  18586. + case DECT_LONG_SLOT_640:
  18587. + chd->pkt = DECT_PACKET_P640j;
  18588. + break;
  18589. + case DECT_LONG_SLOT_672:
  18590. + chd->pkt = DECT_PACKET_P672j;
  18591. + break;
  18592. + default:
  18593. + return -EOPNOTSUPP;
  18594. + }
  18595. +
  18596. + return 0;
  18597. +}
  18598. +
  18599. +static int dect_tbc_establish_req(const struct dect_cell_handle *ch,
  18600. + const struct dect_tbc_id *id,
  18601. + const struct dect_mac_conn_params *mcp,
  18602. + bool handover)
  18603. +{
  18604. + struct dect_cell *cell = dect_cell(ch);
  18605. + struct dect_transceiver *ttrx, *rtrx;
  18606. + struct dect_channel_desc tchd, rchd;
  18607. + struct dect_tbc *tbc;
  18608. + u8 rssi;
  18609. + int err;
  18610. +
  18611. + memset(&tchd, 0, sizeof(tchd));
  18612. + err = dect_tbc_map_params(&tchd, mcp);
  18613. + if (err < 0)
  18614. + goto err1;
  18615. +
  18616. + /* Select TDD slot pair and reserve transceiver resources */
  18617. + err = dect_select_channel(cell, &ttrx, &tchd, &rssi, true);
  18618. + if (err < 0)
  18619. + goto err1;
  18620. + dect_channel_reserve(cell, ttrx, &tchd);
  18621. +
  18622. + err = -ENOSPC;
  18623. + dect_tdd_channel_desc(&rchd, &tchd);
  18624. + rtrx = dect_select_transceiver(cell, &rchd);
  18625. + if (rtrx == NULL)
  18626. + goto err2;
  18627. + dect_channel_reserve(cell, rtrx, &rchd);
  18628. +
  18629. + err = -ENOMEM;
  18630. + tbc = dect_tbc_init(cell, id, rtrx, ttrx, &rchd, &tchd);
  18631. + if (tbc == NULL)
  18632. + goto err3;
  18633. + tbc->id.tbei = dect_tbc_alloc_tbei(cell);
  18634. + tbc->mcp = *mcp;
  18635. + tbc->handover = handover;
  18636. +
  18637. + tbc_debug(tbc, "TBC_ESTABLISH-req: handover: %d\n", handover);
  18638. + dect_tx_bearer_schedule(cell, &tbc->txb, rssi);
  18639. + return 0;
  18640. +
  18641. +err3:
  18642. + dect_channel_release(cell, rtrx, &rchd);
  18643. +err2:
  18644. + dect_channel_release(cell, ttrx, &tchd);
  18645. +err1:
  18646. + return err;
  18647. +}
  18648. +
  18649. +/* TBC establishment confirmation from CCF */
  18650. +static int dect_tbc_establish_res(const struct dect_cell_handle *ch,
  18651. + const struct dect_tbc_id *id)
  18652. +{
  18653. + struct dect_cell *cell = dect_cell(ch);
  18654. + struct dect_tbc *tbc;
  18655. + int err;
  18656. +
  18657. + tbc = dect_tbc_get_by_tbei(cell, id->tbei);
  18658. + if (tbc == NULL)
  18659. + return -ENOENT;
  18660. + tbc_debug(tbc, "TBC_ESTABLISH-res\n");
  18661. + WARN_ON(tbc->state != DECT_TBC_REQ_RCVD &&
  18662. + tbc->state != DECT_TBC_RESPONSE_SENT);
  18663. +
  18664. + /* Stop wait timer and send CONFIRM */
  18665. + dect_timer_del(&tbc->wait_timer);
  18666. + if (tbc->mcp.type == DECT_MAC_CONN_BASIC)
  18667. + err = dect_tbc_send_confirm(tbc);
  18668. + else
  18669. + err = dect_tbc_send_attributes_confirm(tbc);
  18670. + if (err < 0)
  18671. + return err;
  18672. +
  18673. + dect_tbc_state_change(tbc, DECT_TBC_OTHER_WAIT);
  18674. + return 0;
  18675. +}
  18676. +
  18677. +static void dect_tbc_wait_timer(struct dect_cell *cell, void *data)
  18678. +{
  18679. + struct dect_tbc *tbc = data;
  18680. + struct sk_buff *skb;
  18681. +
  18682. + tbc_debug(tbc, "wait timer\n");
  18683. + skb = dect_tbc_build_cctrl(tbc, DECT_CCTRL_WAIT);
  18684. + if (skb == NULL)
  18685. + return;
  18686. +
  18687. + /* The first response is permitted in any frame */
  18688. + if (tbc->state == DECT_TBC_REQ_RCVD)
  18689. + skb->priority = DECT_MT_HIGH_PRIORITY;
  18690. + dect_tbc_queue_mac_control(tbc, skb);
  18691. +
  18692. + dect_tbc_state_change(tbc, DECT_TBC_RESPONSE_SENT);
  18693. +}
  18694. +
  18695. +/**
  18696. + * dect_tbc_rcv_request - handle incoming connection setup attempts
  18697. + *
  18698. + *
  18699. + */
  18700. +static void dect_tbc_rcv_request(struct dect_cell *cell,
  18701. + const struct dect_transceiver_slot *ts,
  18702. + const struct dect_tail_msg *tm,
  18703. + struct sk_buff *skb)
  18704. +{
  18705. + const struct dect_cluster_handle *clh = cell->handle.clh;
  18706. + struct dect_transceiver *rtrx, *ttrx;
  18707. + struct dect_channel_desc rchd, tchd;
  18708. + enum dect_b_identifications b_id;
  18709. + enum dect_packet_types pkt;
  18710. + struct sk_buff *b_skb;
  18711. + struct dect_tbc_id id;
  18712. + struct dect_tbc *tbc;
  18713. + bool handover = false;
  18714. +
  18715. + if (tm->cctl.fmid != cell->fmid)
  18716. + goto err1;
  18717. + dect_raw_rcv(skb);
  18718. +
  18719. + switch (tm->cctl.cmd) {
  18720. + case DECT_CCTRL_ACCESS_REQ:
  18721. + break;
  18722. + case DECT_CCTRL_BEARER_HANDOVER_REQ:
  18723. + case DECT_CCTRL_CONNECTION_HANDOVER_REQ:
  18724. + /* Handover can only be initiated by the PP */
  18725. + if (cell->mode == DECT_MODE_FP) {
  18726. + handover = true;
  18727. + break;
  18728. + }
  18729. + default:
  18730. + rx_debug(cell, "unhandled TBC request: %llu\n",
  18731. + (unsigned long long)tm->cctl.cmd);
  18732. + goto err1;
  18733. + }
  18734. +
  18735. + if (tm->type == DECT_TM_TYPE_BCCTRL)
  18736. + pkt = DECT_PACKET_P32;
  18737. + else
  18738. + pkt = dect_bi_to_pkt(dect_parse_b_id(skb));
  18739. +
  18740. + /* Select transceivers for RX/TX and reserve resources */
  18741. + memcpy(&rchd, &ts->chd, sizeof(rchd));
  18742. + rchd.pkt = pkt;
  18743. + rchd.b_fmt = DECT_B_UNPROTECTED;
  18744. + rtrx = dect_select_transceiver(cell, &rchd);
  18745. + if (rtrx == NULL)
  18746. + goto err1;
  18747. + dect_channel_reserve(cell, rtrx, &rchd);
  18748. +
  18749. + dect_tdd_channel_desc(&tchd, &rchd);
  18750. + ttrx = dect_select_transceiver(cell, &tchd);
  18751. + if (ttrx == NULL)
  18752. + goto err2;
  18753. + dect_channel_reserve(cell, ttrx, &tchd);
  18754. +
  18755. + memset(&id, 0, sizeof(id));
  18756. + memcpy(&id.ari, &cell->idi.pari, sizeof(id.ari));
  18757. + dect_parse_pmid(&id.pmid, tm->cctl.pmid);
  18758. + id.lbn = 0xf;
  18759. + id.ecn = 0;
  18760. + id.tbei = dect_tbc_alloc_tbei(cell);
  18761. +
  18762. + /* Initialize TBC */
  18763. + tbc = dect_tbc_init(cell, &id, rtrx, ttrx, &rchd, &tchd);
  18764. + if (tbc == NULL)
  18765. + goto err3;
  18766. +
  18767. + tbc->handover = handover;
  18768. +
  18769. + if (tm->type == DECT_TM_TYPE_BCCTRL) {
  18770. + /* Basic MAC connections only support the I_N_minimal_delay service */
  18771. + tbc->mcp.type = DECT_MAC_CONN_BASIC;
  18772. + tbc->mcp.service = DECT_SERVICE_IN_MIN_DELAY;
  18773. + tbc->mcp.slot = DECT_FULL_SLOT;
  18774. + } else {
  18775. + /* Service is unknown at this time */
  18776. + tbc->mcp.type = DECT_MAC_CONN_ADVANCED;
  18777. + tbc->mcp.service = DECT_SERVICE_UNKNOWN;
  18778. +
  18779. + b_skb = dect_b_skb_alloc(&tchd);
  18780. + if (b_skb == NULL)
  18781. + goto err4;
  18782. + DECT_B_CB(b_skb)->id = b_id;
  18783. + tbc->b_tx_skb = b_skb;
  18784. + }
  18785. +
  18786. + dect_tbc_state_change(tbc, DECT_TBC_REQ_RCVD);
  18787. + tbc_debug(tbc, "RCV ACCESS_REQUEST: pkt: %u\n", pkt);
  18788. +
  18789. + /* Set Q2 bit on first response */
  18790. + tbc->txb.q = DECT_HDR_Q2_FLAG;
  18791. +
  18792. + /* Start the WAIT transmit timer */
  18793. + dect_timer_setup(&tbc->wait_timer, dect_tbc_wait_timer, tbc);
  18794. + dect_bearer_timer_add(cell, &tbc->txb, &tbc->wait_timer, 1);
  18795. +
  18796. + /* Start watchdog timer: until ESTABLISHED state, the remote side
  18797. + * must transmit a M-tail in every allowed frame. */
  18798. + dect_tbc_watchdog_reschedule(cell, tbc);
  18799. + dect_tbc_enable(cell, tbc);
  18800. +
  18801. + if (tbc->mcp.type == DECT_MAC_CONN_BASIC) {
  18802. + if (clh->ops->tbc_establish_ind(clh, &cell->handle, &tbc->id,
  18803. + &tbc->mcp, tbc->handover) < 0)
  18804. + goto err4;
  18805. + } else {
  18806. + if (dect_tbc_send_confirm(tbc) < 0)
  18807. + goto err4;
  18808. + dect_tbc_state_change(tbc, DECT_TBC_RESPONSE_SENT);
  18809. + }
  18810. +
  18811. + kfree_skb(skb);
  18812. + return;
  18813. +
  18814. +err4:
  18815. + dect_tbc_destroy(cell, tbc);
  18816. +err3:
  18817. + dect_channel_release(cell, ttrx, &tchd);
  18818. +err2:
  18819. + dect_channel_release(cell, rtrx, &rchd);
  18820. +err1:
  18821. + kfree_skb(skb);
  18822. +}
  18823. +
  18824. +#if 0
  18825. +/*
  18826. + * Connectionless Bearer Control (CBC)
  18827. + */
  18828. +
  18829. +static void dect_cbc_rcv(struct dect_cell *cell, struct dect_bearer *bearer,
  18830. + struct sk_buff *skb)
  18831. +{
  18832. + struct dect_cbc *cbc = bearer->cbc;
  18833. + struct dect_tail_msg tm;
  18834. +
  18835. + dect_parse_tail_msg(&tm, skb);
  18836. + dect_bc_rcv(cell, &cbc->bc, skb, &tm);
  18837. + kfree_skb(skb);
  18838. +}
  18839. +
  18840. +static const struct dect_bearer_ops dect_cbc_ops = {
  18841. + .state = DECT_CL_BEARER,
  18842. + .rcv = dect_cbc_rcv,
  18843. +};
  18844. +
  18845. +/**
  18846. + * dect_cbc_init - Initialise a connectionless bearer control
  18847. + *
  18848. + * @cell: DECT cell
  18849. + * @chd: channel description
  18850. + */
  18851. +static struct dect_cbc *dect_cbc_init(struct dect_cell *cell,
  18852. + struct dect_channel_desc *chd)
  18853. +{
  18854. + struct dect_bearer *bearer;
  18855. + enum dect_slot_states mode;
  18856. + struct dect_cbc *cbc = NULL;
  18857. +
  18858. + bearer = dect_bearer_init(cell, &dect_cbc_ops, DECT_SIMPLEX_BEARER,
  18859. + NULL, chd, mode, cbc);
  18860. + if (bearer == NULL)
  18861. + return NULL;
  18862. + cbc->dl_bearer = bearer;
  18863. +
  18864. + dect_bc_init(cell, &cbc->bc);
  18865. + return cbc;
  18866. +}
  18867. +#endif
  18868. +
  18869. +/*
  18870. + * Dummy Bearer Control (DBC)
  18871. + */
  18872. +
  18873. +#define dbc_debug(dbc, fmt, args...) \
  18874. + pr_debug("DBC slot %u carrier %u: " fmt, \
  18875. + (dbc)->bearer.chd.slot, (dbc)->bearer.chd.carrier, ## args)
  18876. +
  18877. +static void dect_dbc_rcv(struct dect_cell *cell, struct dect_bearer *bearer,
  18878. + struct sk_buff *skb)
  18879. +{
  18880. + struct dect_dbc *dbc = bearer->dbc;
  18881. + struct dect_tail_msg tm;
  18882. +
  18883. + /* Update A-field receive time stamp (A-field CRC is always correct) */
  18884. + if (dect_framenum(cell, DECT_TIMER_RX) == 0)
  18885. + cell->a_rcv_stamp = jiffies;
  18886. +
  18887. + dect_raw_rcv(skb);
  18888. +
  18889. + if (dect_parse_tail_msg(&tm, skb) < 0)
  18890. + goto err;
  18891. +
  18892. + /* Update Nt receive stamp if PARI matches */
  18893. + if (tm.type == DECT_TM_TYPE_ID && !dect_rfpi_cmp(&tm.idi, &cell->idi))
  18894. + cell->nt_rcv_stamp = jiffies;
  18895. +
  18896. + dect_bc_rcv(cell, &dbc->bc, skb, &tm);
  18897. +err:
  18898. + kfree_skb(skb);
  18899. +}
  18900. +
  18901. +static void dect_dbc_report_rssi(struct dect_cell *cell,
  18902. + struct dect_bearer *bearer,
  18903. + u8 slot, u8 rssi)
  18904. +{
  18905. + dbc_debug(bearer->dbc, "RSSI: selection: %u now: %u\n", bearer->rssi, rssi);
  18906. +}
  18907. +
  18908. +static void dect_dbc_quality_control_timer(struct dect_cell *cell, void *data)
  18909. +{
  18910. + struct dect_dbc *dbc = data;
  18911. + struct dect_bearer *bearer = &dbc->bearer;
  18912. +
  18913. + switch (dbc->qctrl) {
  18914. + case DECT_BEARER_QCTRL_WAIT:
  18915. + dbc_debug(dbc, "quality control: confirm quality\n");
  18916. + dect_set_channel_mode(bearer->trx, &bearer->chd, DECT_SLOT_RX);
  18917. + dect_set_carrier(bearer->trx, bearer->chd.slot, bearer->chd.carrier);
  18918. + dbc->qctrl = DECT_BEARER_QCTRL_CONFIRM;
  18919. + dect_timer_add(cell, &dbc->qctrl_timer, DECT_TIMER_TX,
  18920. + 1, bearer->chd.slot);
  18921. + break;
  18922. + case DECT_BEARER_QCTRL_CONFIRM:
  18923. + dbc_debug(dbc, "quality control: wait\n");
  18924. + dect_set_channel_mode(bearer->trx, &bearer->chd, DECT_SLOT_TX);
  18925. + dect_set_carrier(bearer->trx, bearer->chd.slot, bearer->chd.carrier);
  18926. + dbc->qctrl = DECT_BEARER_QCTRL_WAIT;
  18927. + dect_timer_add(cell, &dbc->qctrl_timer, DECT_TIMER_TX,
  18928. + DECT_BEARER_QCTRL_PERIOD - 1, bearer->chd.slot);
  18929. + break;
  18930. + }
  18931. +}
  18932. +
  18933. +static void dect_dbc_enable(struct dect_cell *cell, struct dect_bearer *bearer)
  18934. +{
  18935. + struct dect_dbc *dbc = bearer->dbc;
  18936. + u8 framenum = dect_framenum(cell, DECT_TIMER_TX);
  18937. + u8 extra;
  18938. +
  18939. + extra = DECT_BEARER_QCTRL_FRAMENUM - framenum;
  18940. + dbc->qctrl = DECT_BEARER_QCTRL_WAIT;
  18941. + dect_timer_add(cell, &dbc->qctrl_timer, DECT_TIMER_TX,
  18942. + DECT_BEARER_QCTRL_PERIOD + extra, bearer->chd.slot);
  18943. +
  18944. + dect_bearer_enable(bearer);
  18945. +}
  18946. +
  18947. +static const struct dect_bearer_ops dect_dbc_ops = {
  18948. + .state = DECT_DUMMY_BEARER,
  18949. + .enable = dect_dbc_enable,
  18950. + .report_rssi = dect_dbc_report_rssi,
  18951. + .rcv = dect_dbc_rcv,
  18952. +};
  18953. +
  18954. +static void dect_dbc_release(struct dect_dbc *dbc)
  18955. +{
  18956. + struct dect_cell *cell = dbc->cell;
  18957. +
  18958. + dect_channel_release(cell, dbc->bearer.trx, &dbc->bearer.chd);
  18959. + dect_bearer_release(cell, &dbc->bearer);
  18960. +
  18961. + dect_timer_del(&dbc->qctrl_timer);
  18962. + dect_bc_release(&dbc->bc);
  18963. + list_del(&dbc->list);
  18964. + kfree(dbc);
  18965. +}
  18966. +
  18967. +/**
  18968. + * dect_dbc_init - initialise dummy bearer control
  18969. + *
  18970. + * @cell: DECT cell
  18971. + * @chd: channel description (PP only)
  18972. + */
  18973. +static struct dect_dbc *dect_dbc_init(struct dect_cell *cell,
  18974. + const struct dect_channel_desc *chd)
  18975. +{
  18976. + struct dect_channel_desc tchd;
  18977. + struct dect_transceiver *trx;
  18978. + enum dect_bearer_modes mode;
  18979. + struct dect_dbc *dbc;
  18980. + u8 uninitialized_var(rssi);
  18981. +
  18982. + /* Transmission is always in direction FP -> PP */
  18983. + if (cell->mode == DECT_MODE_FP) {
  18984. + tchd.pkt = DECT_PACKET_P00;
  18985. + tchd.b_fmt = DECT_B_NONE;
  18986. + if (dect_select_channel(cell, &trx, &tchd, &rssi, false) < 0)
  18987. + goto err1;
  18988. + chd = &tchd;
  18989. +
  18990. + mode = DECT_BEARER_TX;
  18991. + } else {
  18992. + trx = dect_select_transceiver(cell, chd);
  18993. + if (trx == NULL)
  18994. + goto err1;
  18995. + mode = DECT_BEARER_RX;
  18996. + }
  18997. +
  18998. + dect_channel_reserve(cell, trx, chd);
  18999. +
  19000. + dbc = kzalloc(sizeof(*dbc), GFP_ATOMIC);
  19001. + if (dbc == NULL)
  19002. + goto err2;
  19003. + dbc->cell = cell;
  19004. + dect_timer_setup(&dbc->qctrl_timer, dect_dbc_quality_control_timer, dbc);
  19005. + dect_bc_init(cell, &dbc->bc);
  19006. +
  19007. + dect_bearer_init(cell, &dbc->bearer, &dect_dbc_ops, trx, chd, mode, dbc);
  19008. +
  19009. + if (cell->mode == DECT_MODE_FP)
  19010. + dect_tx_bearer_schedule(cell, &dbc->bearer, rssi);
  19011. + else {
  19012. + dect_bearer_enable(&dbc->bearer);
  19013. +
  19014. + cell->a_rcv_stamp = jiffies;
  19015. + cell->nt_rcv_stamp = jiffies;
  19016. + }
  19017. +
  19018. + list_add_tail(&dbc->list, &cell->dbcs);
  19019. + return dbc;
  19020. +
  19021. +err2:
  19022. + dect_channel_release(cell, trx, chd);
  19023. +err1:
  19024. + return NULL;
  19025. +}
  19026. +
  19027. +/*
  19028. + * Monitor Bearer
  19029. + */
  19030. +
  19031. +static void dect_dmb_release(struct dect_cell *cell, struct dect_dmb *dmb)
  19032. +{
  19033. + cell->tbc_last_chd = dmb->rxb2.chd;
  19034. +
  19035. + dect_timer_del(&dmb->wd_timer);
  19036. +
  19037. + dect_transceiver_release(&cell->trg, dmb->rxb1.trx, &dmb->rxb1.chd);
  19038. + dect_bearer_release(dmb->cell, &dmb->rxb1);
  19039. +
  19040. + dect_transceiver_release(&cell->trg, dmb->rxb2.trx, &dmb->rxb2.chd);
  19041. + dect_bearer_release(dmb->cell, &dmb->rxb2);
  19042. +
  19043. + dect_bc_release(&dmb->bc);
  19044. + list_del(&dmb->list);
  19045. + kfree(dmb);
  19046. +}
  19047. +
  19048. +static void dect_dmb_watchdog_timer(struct dect_cell *cell, void *data)
  19049. +{
  19050. + dect_dmb_release(cell, data);
  19051. +}
  19052. +
  19053. +static void dect_dmb_watchdog_reschedule(struct dect_cell *cell,
  19054. + struct dect_dmb *dmb)
  19055. +{
  19056. + dect_bearer_timer_add(cell, &dmb->rxb1, &dmb->wd_timer,
  19057. + DECT_TBC_RFPI_TIMEOUT);
  19058. +}
  19059. +
  19060. +static void dect_dmb_rcv(struct dect_cell *cell, struct dect_bearer *bearer,
  19061. + struct sk_buff *skb)
  19062. +{
  19063. + struct dect_dmb *dmb = bearer->dmb;
  19064. + struct dect_tail_msg tm;
  19065. +
  19066. + dect_raw_rcv(skb);
  19067. +
  19068. + if (dect_parse_tail_msg(&tm, skb) < 0)
  19069. + goto err;
  19070. +
  19071. + /* Reschedule watchdog on successful RFPI handshake. */
  19072. + if (tm.type == DECT_TM_TYPE_ID && !dect_rfpi_cmp(&tm.idi, &cell->idi))
  19073. + dect_dmb_watchdog_reschedule(cell, dmb);
  19074. +
  19075. + dect_bc_rcv(cell, &dmb->bc, skb, &tm);
  19076. +
  19077. + switch (tm.type) {
  19078. + case DECT_TM_TYPE_BCCTRL:
  19079. + case DECT_TM_TYPE_ACCTRL:
  19080. + if (tm.cctl.cmd == DECT_CCTRL_RELEASE)
  19081. + return dect_dmb_release(cell, dmb);
  19082. + break;
  19083. + default:
  19084. + break;
  19085. + }
  19086. +err:
  19087. + kfree_skb(skb);
  19088. +}
  19089. +
  19090. +static const struct dect_bearer_ops dect_dmb_ops = {
  19091. + .state = DECT_MONITOR_BEARER,
  19092. + .rcv = dect_dmb_rcv,
  19093. +};
  19094. +
  19095. +static struct dect_dmb *dect_dmb_init(struct dect_cell *cell,
  19096. + struct dect_transceiver *trx1,
  19097. + struct dect_transceiver *trx2,
  19098. + const struct dect_channel_desc *chd1,
  19099. + const struct dect_channel_desc *chd2)
  19100. +{
  19101. + struct dect_dmb *dmb;
  19102. +
  19103. + dmb = kzalloc(sizeof(*dmb), GFP_ATOMIC);
  19104. + if (dmb == NULL)
  19105. + return NULL;
  19106. + dmb->cell = cell;
  19107. +
  19108. + dect_timer_setup(&dmb->wd_timer, dect_dmb_watchdog_timer, dmb);
  19109. + dect_bearer_init(cell, &dmb->rxb1, &dect_dmb_ops,
  19110. + trx1, chd1, DECT_BEARER_RX, dmb);
  19111. + dect_bearer_init(cell, &dmb->rxb2, &dect_dmb_ops,
  19112. + trx2, chd2, DECT_BEARER_RX, dmb);
  19113. + dect_bc_init(cell, &dmb->bc);
  19114. +
  19115. + list_add_tail(&dmb->list, &cell->dmbs);
  19116. + return dmb;
  19117. +}
  19118. +
  19119. +static void dect_dmb_rcv_request(struct dect_cell *cell,
  19120. + const struct dect_transceiver_slot *ts,
  19121. + const struct dect_tail_msg *tm,
  19122. + struct sk_buff *skb)
  19123. +{
  19124. + struct dect_transceiver *trx1, *trx2;
  19125. + struct dect_channel_desc chd1, chd2;
  19126. + struct dect_dmb *dmb;
  19127. +
  19128. + if (tm->cctl.fmid != cell->fmid)
  19129. + goto err1;
  19130. + dect_raw_rcv(skb);
  19131. +
  19132. + switch (tm->cctl.cmd) {
  19133. + case DECT_CCTRL_ACCESS_REQ:
  19134. + case DECT_CCTRL_BEARER_HANDOVER_REQ:
  19135. + case DECT_CCTRL_CONNECTION_HANDOVER_REQ:
  19136. + break;
  19137. + default:
  19138. + rx_debug(cell, "unhandled DMB request: %llu\n",
  19139. + (unsigned long long)tm->cctl.cmd);
  19140. + goto err1;
  19141. + }
  19142. +
  19143. + rx_debug(cell, "DMB: RCV ACCESS_REQUEST\n");
  19144. +
  19145. + /* Select transceivers for RX/TX and reserve resources */
  19146. + memcpy(&chd1, &ts->chd, sizeof(chd1));
  19147. + chd1.pkt = DECT_PACKET_P32;
  19148. + chd1.b_fmt = DECT_B_UNPROTECTED;
  19149. + trx1 = dect_select_transceiver(cell, &chd1);
  19150. + if (trx1 == NULL)
  19151. + goto err1;
  19152. + dect_transceiver_reserve(&cell->trg, trx1, &chd1);
  19153. +
  19154. + dect_tdd_channel_desc(&chd2, &chd1);
  19155. + trx2 = dect_select_transceiver(cell, &chd2);
  19156. + if (trx2 == NULL)
  19157. + goto err2;
  19158. + dect_transceiver_reserve(&cell->trg, trx2, &chd2);
  19159. +
  19160. + dmb = dect_dmb_init(cell, trx1, trx2, &chd1, &chd2);
  19161. + if (dmb == NULL)
  19162. + goto err3;
  19163. +
  19164. + dect_bearer_enable(&dmb->rxb1);
  19165. + dect_bearer_enable(&dmb->rxb2);
  19166. +
  19167. + dect_bearer_timer_add(cell, &dmb->rxb1, &dmb->wd_timer,
  19168. + DECT_TBC_RFPI_TIMEOUT);
  19169. +
  19170. + kfree_skb(skb);
  19171. + return;
  19172. +
  19173. +err3:
  19174. + dect_transceiver_release(&cell->trg, trx2, &chd2);
  19175. +err2:
  19176. + dect_transceiver_release(&cell->trg, trx1, &chd1);
  19177. +err1:
  19178. + kfree_skb(skb);
  19179. +}
  19180. +
  19181. +/*
  19182. + * Idle Receiver Control
  19183. + */
  19184. +
  19185. +static void dect_initiate_scan(struct dect_transceiver *trx,
  19186. + const struct dect_ari *ari,
  19187. + const struct dect_ari *ari_mask,
  19188. + void (*notify)(struct dect_cell *,
  19189. + struct dect_transceiver *,
  19190. + enum dect_scan_status))
  19191. +{
  19192. + struct dect_irc *irc = trx->irc;
  19193. +
  19194. + if (ari != NULL) {
  19195. + memcpy(&irc->ari, ari, sizeof(irc->ari));
  19196. + if (ari_mask != NULL)
  19197. + memcpy(&irc->ari_mask, ari_mask, sizeof(irc->ari_mask));
  19198. + else
  19199. + memset(&irc->ari_mask, 0xff, sizeof(irc->ari_mask));
  19200. + }
  19201. +
  19202. + memset(&irc->si, 0, sizeof(irc->si));
  19203. + irc->notify = notify;
  19204. +
  19205. + dect_transceiver_enable(trx);
  19206. + dect_set_channel_mode(trx, &trx->slots[DECT_SCAN_SLOT].chd, DECT_SLOT_SCANNING);
  19207. +}
  19208. +
  19209. +static void dect_restart_scan(struct dect_cell *cell,
  19210. + struct dect_transceiver *trx)
  19211. +{
  19212. + struct dect_irc *irc = trx->irc;
  19213. +
  19214. + dect_transceiver_unlock(trx);
  19215. + memset(&irc->si, 0, sizeof(irc->si));
  19216. + dect_set_channel_mode(trx, &trx->slots[DECT_SCAN_SLOT].chd, DECT_SLOT_SCANNING);
  19217. +}
  19218. +
  19219. +/* This function controls the transceiver while scanning. It collects the
  19220. + * information requested in struct dect_scan_ctrl and invokes the completion
  19221. + * handler once all information is available.
  19222. + */
  19223. +void dect_mac_irc_rcv(struct dect_transceiver *trx, struct sk_buff *skb)
  19224. +{
  19225. + struct dect_cell *cell = trx->cell;
  19226. + struct dect_irc *irc = trx->irc;
  19227. + struct dect_tail_msg tm;
  19228. +
  19229. + if (dect_parse_tail_msg(&tm, skb) < 0)
  19230. + goto err;
  19231. +
  19232. + switch (trx->state) {
  19233. + case DECT_TRANSCEIVER_UNLOCKED:
  19234. + if (tm.type != DECT_TM_TYPE_ID)
  19235. + break;
  19236. + if (dect_ari_masked_cmp(&tm.idi.pari, &irc->ari, &irc->ari_mask))
  19237. + break;
  19238. + memcpy(&irc->idi, &tm.idi, sizeof(irc->idi));
  19239. +
  19240. + irc->timeout = 16 * DECT_FRAMES_PER_MULTIFRAME;
  19241. + irc->rssi = dect_average_rssi(0, DECT_TRX_CB(skb)->rssi);
  19242. + dect_transceiver_confirm(trx);
  19243. + break;
  19244. + case DECT_TRANSCEIVER_LOCK_PENDING:
  19245. + irc->rssi = dect_average_rssi(irc->rssi, DECT_TRX_CB(skb)->rssi);
  19246. + if (dect_parse_tail(skb) == DECT_TI_QT) {
  19247. + dect_bc_update_si(&irc->si, &tm);
  19248. + if (dect_bc_si_cycle_complete(&irc->idi, &irc->si) &&
  19249. + tm.type == DECT_TM_TYPE_MFN)
  19250. + irc->notify(cell, trx, DECT_SCAN_COMPLETE);
  19251. + }
  19252. + break;
  19253. + default:
  19254. + break;
  19255. + }
  19256. +err:
  19257. + kfree_skb(skb);
  19258. +}
  19259. +
  19260. +void dect_mac_irc_tick(struct dect_transceiver *trx)
  19261. +{
  19262. + struct dect_cell *cell = trx->cell;
  19263. + struct dect_irc *irc = trx->irc;
  19264. +
  19265. + switch (trx->state) {
  19266. + case DECT_TRANSCEIVER_UNLOCKED:
  19267. + /* maintain scan until clock is running */
  19268. + irc->rx_scn = dect_next_carrier(0x3ff, irc->rx_scn);
  19269. + dect_set_carrier(trx, DECT_SCAN_SLOT, irc->rx_scn);
  19270. + break;
  19271. + case DECT_TRANSCEIVER_LOCK_PENDING:
  19272. + irc->si.ssi.pscn = dect_next_carrier(0x3ff, irc->si.ssi.pscn);
  19273. + if (--irc->timeout == 0)
  19274. + irc->notify(cell, trx, DECT_SCAN_TIMEOUT);
  19275. + break;
  19276. + default:
  19277. + break;
  19278. + }
  19279. +}
  19280. +
  19281. +static void dect_scan_bearer_rcv(struct dect_cell *cell,
  19282. + struct dect_bearer *bearer,
  19283. + struct sk_buff *skb)
  19284. +{
  19285. + struct dect_transceiver *trx = bearer->trx;
  19286. + struct dect_transceiver_slot *ts;
  19287. + enum dect_tail_identifications ti;
  19288. + struct dect_tail_msg tm;
  19289. + bool monitor = false;
  19290. +
  19291. + ti = dect_parse_tail(skb);
  19292. + /* A PP uses a special encoding for the first transmission */
  19293. + if (cell->mode == DECT_MODE_FP && ti != DECT_TI_MT_PKT_0)
  19294. + goto out;
  19295. + if (cell->mode == DECT_MODE_PP) {
  19296. + if (cell->flags & DECT_CELL_MONITOR && ti == DECT_TI_MT_PKT_0)
  19297. + monitor = true;
  19298. + else if (ti != DECT_TI_MT)
  19299. + goto out;
  19300. + }
  19301. +
  19302. + if (dect_parse_tail_msg(&tm, skb) < 0)
  19303. + goto out;
  19304. +
  19305. + ts = &trx->slots[DECT_TRX_CB(skb)->slot];
  19306. + switch (tm.type) {
  19307. + case DECT_TM_TYPE_BCCTRL:
  19308. + case DECT_TM_TYPE_ACCTRL:
  19309. + if (monitor)
  19310. + return dect_dmb_rcv_request(cell, ts, &tm, skb);
  19311. + else
  19312. + return dect_tbc_rcv_request(cell, ts, &tm, skb);
  19313. + default:
  19314. + break;
  19315. + }
  19316. +out:
  19317. + kfree_skb(skb);
  19318. +}
  19319. +
  19320. +static void dect_scan_bearer_report_rssi(struct dect_cell *cell,
  19321. + struct dect_bearer *bearer,
  19322. + u8 slot, u8 rssi)
  19323. +{
  19324. + if (cell->chl == NULL)
  19325. + return;
  19326. + dect_chl_update(cell, cell->chl, &bearer->trx->slots[slot].chd, rssi);
  19327. +}
  19328. +
  19329. +static const struct dect_bearer_ops dect_scan_ops = {
  19330. + .report_rssi = dect_scan_bearer_report_rssi,
  19331. + .rcv = dect_scan_bearer_rcv,
  19332. +};
  19333. +
  19334. +static void dect_scan_channel_desc(struct dect_channel_desc *chd)
  19335. +{
  19336. + memset(chd, 0, sizeof(*chd));
  19337. + chd->pkt = DECT_PACKET_P32;
  19338. + chd->b_fmt = DECT_B_UNPROTECTED;
  19339. +}
  19340. +
  19341. +static void dect_chl_scan_channel_desc(struct dect_channel_desc *chd,
  19342. + const struct dect_channel_list *chl)
  19343. +{
  19344. + memset(chd, 0, sizeof(*chd));
  19345. + chd->pkt = chl->pkt;
  19346. + if (chl->pkt == DECT_PACKET_P00)
  19347. + chd->b_fmt = DECT_B_NONE;
  19348. + else
  19349. + chd->b_fmt = DECT_B_UNPROTECTED;
  19350. +}
  19351. +
  19352. +static void dect_scan_bearer_enable(struct dect_transceiver *trx,
  19353. + const struct dect_channel_desc *chd)
  19354. +{
  19355. + trx->slots[chd->slot].bearer = &trx->irc->scan_bearer;
  19356. + dect_set_channel_mode(trx, chd, DECT_SLOT_SCANNING);
  19357. +}
  19358. +
  19359. +static void dect_scan_bearer_disable(struct dect_transceiver *trx,
  19360. + const struct dect_channel_desc *chd)
  19361. +{
  19362. + dect_set_channel_mode(trx, chd, DECT_SLOT_IDLE);
  19363. + trx->slots[chd->slot].bearer = NULL;
  19364. +}
  19365. +
  19366. +static void dect_irc_tx_frame_timer(struct dect_cell *cell, void *data)
  19367. +{
  19368. + struct dect_irc *irc = data;
  19369. + struct dect_transceiver *trx = irc->trx;
  19370. + struct dect_channel_desc chd;
  19371. + u8 end;
  19372. +
  19373. + irc->tx_scn = dect_next_carrier(cell->si.ssi.rfcars, irc->tx_scn);
  19374. +
  19375. + /* Begin a pending channel list update:
  19376. + *
  19377. + * The IRC of the first transceiver that reaches a new frame queues the
  19378. + * channel list. All IRCs then switch the idle normal transmit slots
  19379. + * to scanning mode and switch all scanning slots to the lists physical
  19380. + * channel type. The actual update will begin once the receive side
  19381. + * reaches the same frame.
  19382. + */
  19383. + if (cell->chl == NULL && cell->chl_next == NULL)
  19384. + cell->chl_next = dect_chl_get_pending(cell);
  19385. +
  19386. + if (cell->chl_next != NULL) {
  19387. + dect_chl_scan_channel_desc(&chd, cell->chl_next);
  19388. + dect_foreach_receive_slot(chd.slot, end, cell) {
  19389. + if (trx->slots[chd.slot].state != DECT_SLOT_IDLE &&
  19390. + trx->slots[chd.slot].state != DECT_SLOT_SCANNING)
  19391. + continue;
  19392. + if (!dect_transceiver_channel_available(trx, &chd))
  19393. + continue;
  19394. +
  19395. + dect_scan_bearer_enable(trx, &chd);
  19396. + }
  19397. + dect_foreach_transmit_slot(chd.slot, end, cell) {
  19398. + if (trx->slots[chd.slot].state != DECT_SLOT_IDLE)
  19399. + continue;
  19400. + if (!dect_transceiver_channel_available(trx, &chd))
  19401. + continue;
  19402. + dect_scan_bearer_enable(trx, &chd);
  19403. + }
  19404. + } else if (cell->chl == NULL) {
  19405. + /* Switch back primary, secondary and tertiary scan to proper
  19406. + * packet format and disable scan on remaining transceivers
  19407. + * after the channel list update is complete.
  19408. + */
  19409. + dect_scan_channel_desc(&chd);
  19410. + dect_foreach_receive_slot(chd.slot, end, cell) {
  19411. + if (trx->slots[chd.slot].state != DECT_SLOT_SCANNING)
  19412. + continue;
  19413. +
  19414. + if (trx->index < 3)
  19415. + dect_scan_bearer_enable(trx, &chd);
  19416. + else
  19417. + dect_scan_bearer_disable(trx, &chd);
  19418. + }
  19419. +
  19420. + /* In monitor mode, transmit slots keep scanning for FP setup
  19421. + * attempts.
  19422. + */
  19423. + if (!(cell->flags & DECT_CELL_MONITOR)) {
  19424. + dect_foreach_transmit_slot(chd.slot, end, cell) {
  19425. + if (trx->slots[chd.slot].state != DECT_SLOT_SCANNING)
  19426. + continue;
  19427. + dect_scan_bearer_disable(trx, &chd);
  19428. + }
  19429. + }
  19430. + }
  19431. +
  19432. + dect_timer_add(cell, &irc->tx_frame_timer, DECT_TIMER_TX, 1, 0);
  19433. +}
  19434. +
  19435. +static void dect_irc_rx_frame_timer(struct dect_cell *cell, void *data)
  19436. +{
  19437. + struct dect_irc *irc = data;
  19438. +
  19439. + /* Update the list status at the end of a frame in case of an
  19440. + * active update or activate an update before a new frame begins.
  19441. + */
  19442. + if (cell->chl != NULL)
  19443. + dect_chl_update_carrier(cell, irc->rx_scn);
  19444. + else if (cell->chl_next != NULL) {
  19445. + cell->chl = cell->chl_next;
  19446. + cell->chl_next = NULL;
  19447. + chl_debug(cell, cell->chl, "begin update\n");
  19448. + }
  19449. +
  19450. + irc->rx_scn = dect_next_carrier(cell->si.ssi.rfcars, irc->rx_scn);
  19451. + dect_timer_add(cell, &irc->rx_frame_timer, DECT_TIMER_RX, 1, 23);
  19452. +}
  19453. +
  19454. +/* Primary, secondary and tertiary scan: the secondary scan lags behind the
  19455. + * primary scan by 6 TDMA frames, the tertiary scan by 3 TDMA frames.
  19456. + *
  19457. + * Additional transceivers don't scan for setup attempts, however they each
  19458. + * cover a different carrier in order to speed up channel list construction.
  19459. + */
  19460. +static const u8 scn_off_tbl[10] = {
  19461. + [0] = 0,
  19462. + [1] = 6,
  19463. + [2] = 3,
  19464. + [3] = 8,
  19465. + [4] = 1,
  19466. + [5] = 4,
  19467. + [6] = 9,
  19468. + [7] = 2,
  19469. + [8] = 5,
  19470. + [9] = 7,
  19471. +};
  19472. +
  19473. +static void dect_irc_enable(struct dect_cell *cell, struct dect_irc *irc)
  19474. +{
  19475. + struct dect_transceiver *trx = irc->trx;
  19476. + struct dect_channel_desc chd;
  19477. + u8 end, scn_off, scn;
  19478. +
  19479. + if (trx->index >= 10)
  19480. + return;
  19481. +
  19482. + scn_off = scn_off_tbl[trx->index];
  19483. + scn = dect_carrier_sub(cell->si.ssi.rfcars, cell->si.ssi.pscn, scn_off);
  19484. + irc->rx_scn = scn;
  19485. + irc->tx_scn = scn;
  19486. +
  19487. + if (trx->index < 3) {
  19488. + /* Set all idle slots to scanning */
  19489. + dect_scan_channel_desc(&chd);
  19490. + dect_foreach_receive_slot(chd.slot, end, cell) {
  19491. + if (trx->slots[chd.slot].state != DECT_SLOT_IDLE)
  19492. + continue;
  19493. + if (!dect_transceiver_channel_available(trx, &chd))
  19494. + continue;
  19495. + dect_scan_bearer_enable(trx, &chd);
  19496. + }
  19497. +
  19498. + if (cell->flags & DECT_CELL_MONITOR) {
  19499. + dect_foreach_transmit_slot(chd.slot, end, cell) {
  19500. + if (!dect_transceiver_channel_available(trx, &chd))
  19501. + continue;
  19502. + dect_scan_bearer_enable(trx, &chd);
  19503. + }
  19504. + }
  19505. + }
  19506. +
  19507. + /* Start frame timers */
  19508. + dect_timer_add(cell, &irc->tx_frame_timer, DECT_TIMER_TX, 1, 0);
  19509. + dect_timer_add(cell, &irc->rx_frame_timer, DECT_TIMER_RX, 0, 23);
  19510. +}
  19511. +
  19512. +static void dect_irc_disable(struct dect_cell *cell, struct dect_irc *irc)
  19513. +{
  19514. + struct dect_transceiver *trx = irc->trx;
  19515. + u8 slot;
  19516. +
  19517. + dect_timer_del(&irc->rx_frame_timer);
  19518. + dect_timer_del(&irc->tx_frame_timer);
  19519. +
  19520. + dect_foreach_slot(slot) {
  19521. + if (trx->slots[slot].state != DECT_SLOT_SCANNING)
  19522. + continue;
  19523. + dect_scan_bearer_disable(trx, &trx->slots[slot].chd);
  19524. + }
  19525. +}
  19526. +
  19527. +static struct dect_irc *dect_irc_init(struct dect_cell *cell,
  19528. + struct dect_transceiver *trx)
  19529. +{
  19530. + struct dect_irc *irc;
  19531. +
  19532. + irc = kzalloc(sizeof(*irc), GFP_KERNEL);
  19533. + if (irc == NULL)
  19534. + return NULL;
  19535. +
  19536. + irc->cell = cell;
  19537. + dect_timer_setup(&irc->rx_frame_timer, dect_irc_rx_frame_timer, irc);
  19538. + dect_timer_setup(&irc->tx_frame_timer, dect_irc_tx_frame_timer, irc);
  19539. + irc->scan_bearer.ops = &dect_scan_ops;
  19540. + irc->scan_bearer.irc = irc;
  19541. + irc->scan_bearer.trx = trx;
  19542. + irc->scan_bearer.mode = DECT_BEARER_RX;
  19543. + irc->scan_bearer.state = DECT_BEARER_ENABLED;
  19544. + irc->trx = trx;
  19545. + trx->irc = irc;
  19546. + return irc;
  19547. +}
  19548. +
  19549. +static void dect_lock_fp(struct dect_cell *cell, struct dect_transceiver *trx,
  19550. + enum dect_scan_status status)
  19551. +{
  19552. + const struct dect_cluster_handle *clh = cell->handle.clh;
  19553. + struct dect_irc *irc = trx->irc;
  19554. + struct dect_si *si = &irc->si;
  19555. + struct dect_channel_desc chd;
  19556. + struct dect_dbc *dbc;
  19557. +
  19558. + switch (status) {
  19559. + case DECT_SCAN_FAIL:
  19560. + case DECT_SCAN_TIMEOUT:
  19561. + return dect_restart_scan(cell, trx);
  19562. + case DECT_SCAN_COMPLETE:
  19563. + break;
  19564. + }
  19565. +
  19566. + dect_set_channel_mode(trx, &trx->slots[DECT_SCAN_SLOT].chd, DECT_SLOT_IDLE);
  19567. +
  19568. + chd.slot = si->ssi.sn + (si->ssi.nr ? DECT_HALF_FRAME_SIZE : 0);
  19569. + chd.carrier = si->ssi.cn;
  19570. + chd.pkt = DECT_PACKET_P00;
  19571. + chd.b_fmt = DECT_B_NONE;
  19572. +
  19573. + if (!dect_transceiver_channel_available(trx, &chd))
  19574. + return dect_restart_scan(cell, trx);
  19575. +
  19576. + if (cell->mode != DECT_MODE_FP) {
  19577. + memcpy(&cell->idi, &irc->idi, sizeof(cell->idi));
  19578. + cell->fmid = dect_build_fmid(&cell->idi);
  19579. + memcpy(&cell->si, si, sizeof(cell->si));
  19580. +
  19581. + /* Q-channel information is broadcast in frame 8 */
  19582. + dect_timer_synchronize_framenum(cell, DECT_Q_CHANNEL_FRAME);
  19583. + dect_timer_synchronize_mfn(cell, si->mfn.num);
  19584. +
  19585. + /* Lock framing based on slot position and create DBC */
  19586. + dect_transceiver_lock(trx, chd.slot);
  19587. + dect_dbc_init(cell, &chd);
  19588. +
  19589. + clh->ops->mac_info_ind(clh, &cell->idi, &cell->si);
  19590. + } else {
  19591. + /* secondary transceiver */
  19592. + dbc = dect_dbc_get(cell);
  19593. + if (!(cell->flags & DECT_CELL_SLAVE) &&
  19594. + (dbc == NULL ||
  19595. + dbc->bearer.chd.slot != chd.slot ||
  19596. + dbc->bearer.chd.carrier != chd.carrier))
  19597. + return dect_restart_scan(cell, trx);
  19598. +
  19599. + dect_transceiver_lock(trx, chd.slot);
  19600. +
  19601. + /* Lock to the primary dummy bearer to keep the radio synchronized */
  19602. + /* FIXME: do this cleanly */
  19603. + dect_channel_reserve(cell, trx, &chd);
  19604. + dect_set_channel_mode(trx, &chd, DECT_SLOT_RX);
  19605. + dect_set_flags(trx, chd.slot, DECT_SLOT_SYNC);
  19606. + dect_set_carrier(trx, chd.slot, chd.carrier);
  19607. + }
  19608. +
  19609. + /* Enable IRC */
  19610. + dect_irc_enable(cell, irc);
  19611. +}
  19612. +
  19613. +static void dect_attempt_lock(struct dect_cell *cell,
  19614. + struct dect_transceiver *trx)
  19615. +{
  19616. + dect_initiate_scan(trx, &cell->idi.pari, NULL, dect_lock_fp);
  19617. +}
  19618. +
  19619. +/*
  19620. + * Transmission: A- and B-Field MUXes
  19621. + */
  19622. +
  19623. +static struct sk_buff *dect_u_mux(struct dect_cell *cell,
  19624. + struct dect_bearer *bearer)
  19625. +{
  19626. + struct sk_buff *skb = NULL;
  19627. + struct dect_tbc *tbc;
  19628. +
  19629. + if (bearer->ops->state == DECT_TRAFFIC_BEARER) {
  19630. + tbc = bearer->tbc;
  19631. + skb = tbc->b_tx_skb;
  19632. + tbc->b_tx_skb = NULL;
  19633. + }
  19634. +
  19635. + if (skb == NULL) {
  19636. + skb = dect_b_skb_alloc(&bearer->chd);
  19637. + if (skb == NULL)
  19638. + return NULL;
  19639. + DECT_B_CB(skb)->id = DECT_BI_UTYPE_0;
  19640. + }
  19641. +
  19642. + return skb;
  19643. +}
  19644. +
  19645. +static struct sk_buff *dect_eu_mux(struct dect_cell *cell,
  19646. + struct dect_bearer *bearer)
  19647. +{
  19648. + return dect_u_mux(cell, bearer);
  19649. +}
  19650. +
  19651. +static struct sk_buff *dect_b_map(struct dect_cell *cell,
  19652. + struct dect_bearer *bearer)
  19653. +{
  19654. + return dect_eu_mux(cell, bearer);
  19655. +}
  19656. +
  19657. +#define tmux_debug(cell, fmt, args...) \
  19658. + tx_debug(cell, "%s T-MUX: " fmt, \
  19659. + cell->mode == DECT_MODE_FP ? "FT" : "PT", ## args)
  19660. +
  19661. +/**
  19662. + * dect_pt_t_mux - DECT T-MUX for PT transmissions
  19663. + *
  19664. + * @cell: DECT cell
  19665. + * @bearer: MAC bearer
  19666. + *
  19667. + * The PT T-MUX sequence is used by PTs for all traffic bearers in connection
  19668. + * oriented services and is defined as:
  19669. + *
  19670. + * Even frames: M_T, C_T, N_T
  19671. + * Uneven frames: N_T
  19672. + *
  19673. + * Exception: M_T tails containing "bearer request" or "bearer release"
  19674. + * messages may be placed in any frame.
  19675. + */
  19676. +static struct sk_buff *dect_pt_t_mux(struct dect_cell *cell,
  19677. + struct dect_bearer *bearer)
  19678. +{
  19679. + struct dect_tbc *tbc = NULL;
  19680. + struct sk_buff *skb;
  19681. +
  19682. + switch (bearer->ops->state) {
  19683. + case DECT_DUMMY_BEARER:
  19684. + case DECT_CL_BEARER:
  19685. + case DECT_MONITOR_BEARER:
  19686. + WARN_ON(0);
  19687. + break;
  19688. + case DECT_TRAFFIC_BEARER:
  19689. + tbc = bearer->tbc;
  19690. + tbc->cs_tx_ok = false;
  19691. + break;
  19692. + }
  19693. +
  19694. + if ((dect_framenum(cell, DECT_TIMER_TX) & 0x1) == 0) {
  19695. + skb = skb_dequeue(&bearer->m_tx_queue);
  19696. + if (skb != NULL) {
  19697. + tmux_debug(cell, "M-channel\n");
  19698. + return skb;
  19699. + }
  19700. + if (tbc != NULL && tbc->cs_tx_skb != NULL) {
  19701. + skb = tbc->cs_tx_skb;
  19702. + tbc->cs_tx_skb = NULL;
  19703. + tbc->cs_tx_ok = true;
  19704. + tmux_debug(cell, "C-channel\n");
  19705. + return skb;
  19706. + }
  19707. + } else {
  19708. + skb = skb_peek(&bearer->m_tx_queue);
  19709. + if (skb != NULL && skb->priority == DECT_MT_HIGH_PRIORITY) {
  19710. + tmux_debug(cell, "M-channel (high priority)\n");
  19711. + skb_unlink(skb, &bearer->m_tx_queue);
  19712. + return skb;
  19713. + }
  19714. + }
  19715. +
  19716. + tmux_debug(cell, "N-channel\n");
  19717. + return dect_bc_dequeue(cell, bearer, &tbc->bc, DECT_MC_N);
  19718. +}
  19719. +
  19720. +/**
  19721. + * dect_rfp_t_mux - DECT T-MUX for RFP transmissions
  19722. + *
  19723. + * @cell: DECT cell
  19724. + * @bearer: MAC bearer
  19725. + *
  19726. + * The RFP T-MUX sequence is used for all RFP transmissions and is defined as:
  19727. + *
  19728. + * Frame 8: Q_T
  19729. + * Frame 14: N_T
  19730. + * Other even frames: P_T, N_T
  19731. + * Uneven frames: M_T, C_T, N_T
  19732. + *
  19733. + * Exception: M_T tails sent in response to "bearer request" messages or during
  19734. + * bearer release may be placed in any frame.
  19735. + */
  19736. +static struct sk_buff *dect_rfp_t_mux(struct dect_cell *cell,
  19737. + struct dect_bearer *bearer)
  19738. +{
  19739. + u8 framenum = dect_framenum(cell, DECT_TIMER_TX);
  19740. + struct dect_tbc *tbc = NULL;
  19741. + struct dect_bc *bc = NULL;
  19742. + struct sk_buff *skb;
  19743. +
  19744. + switch (bearer->ops->state) {
  19745. + case DECT_DUMMY_BEARER:
  19746. + bc = &bearer->dbc->bc;
  19747. + break;
  19748. + case DECT_TRAFFIC_BEARER:
  19749. + tbc = bearer->tbc;
  19750. + tbc->cs_tx_ok = false;
  19751. + bc = &bearer->tbc->bc;
  19752. + break;
  19753. + case DECT_CL_BEARER:
  19754. + case DECT_MONITOR_BEARER:
  19755. + break;
  19756. + }
  19757. +
  19758. + if ((framenum & 0x1) == 0) {
  19759. + skb = skb_peek(&bearer->m_tx_queue);
  19760. + if (skb != NULL && skb->priority == DECT_MT_HIGH_PRIORITY) {
  19761. + tmux_debug(cell, "M-channel (high priority)\n");
  19762. + skb_unlink(skb, &bearer->m_tx_queue);
  19763. + return skb;
  19764. + }
  19765. +
  19766. + if (framenum == 8) {
  19767. + tmux_debug(cell, "Q-channel\n");
  19768. + return dect_bc_dequeue(cell, bearer, bc, DECT_MC_Q);
  19769. + }
  19770. + if (framenum == 14) {
  19771. + tmux_debug(cell, "N-channel\n");
  19772. + return dect_bc_dequeue(cell, bearer, bc, DECT_MC_N);
  19773. + }
  19774. +
  19775. + skb = dect_bc_dequeue(cell, bearer, bc, DECT_MC_P);
  19776. + if (skb != NULL) {
  19777. + tmux_debug(cell, "P-channel\n");
  19778. + return skb;
  19779. + }
  19780. + } else {
  19781. + skb = skb_dequeue(&bearer->m_tx_queue);
  19782. + if (skb != NULL) {
  19783. + tmux_debug(cell, "M-channel\n");
  19784. + return skb;
  19785. + }
  19786. + if (tbc != NULL && tbc->cs_tx_skb != NULL) {
  19787. + skb = tbc->cs_tx_skb;
  19788. + tbc->cs_tx_skb = NULL;
  19789. + tbc->cs_tx_ok = true;
  19790. + tmux_debug(cell, "C-channel\n");
  19791. + return skb;
  19792. + }
  19793. + }
  19794. +
  19795. + tmux_debug(cell, "N-channel\n");
  19796. + return dect_bc_dequeue(cell, bearer, bc, DECT_MC_N);
  19797. +}
  19798. +
  19799. +/**
  19800. + * dect_a_map - DECT A-Field mapping
  19801. + *
  19802. + * @cell: DECT cell
  19803. + * @bearer: MAC bearer
  19804. + *
  19805. + * Combine the H-, T- and RA-Fields into the A-Field.
  19806. + */
  19807. +static struct sk_buff *dect_a_map(struct dect_cell *cell,
  19808. + struct dect_bearer *bearer)
  19809. +{
  19810. + struct sk_buff *skb;
  19811. +
  19812. + switch (cell->mode) {
  19813. + case DECT_MODE_PP:
  19814. + skb = dect_pt_t_mux(cell, bearer);
  19815. + break;
  19816. + case DECT_MODE_FP:
  19817. + skb = dect_rfp_t_mux(cell, bearer);
  19818. + break;
  19819. + default:
  19820. + skb = NULL;
  19821. + break;
  19822. + }
  19823. +
  19824. + if (skb == NULL)
  19825. + return NULL;
  19826. +
  19827. + /* Append empty RA-Field */
  19828. + memset(skb_put(skb, DECT_RA_FIELD_SIZE), 0, DECT_RA_FIELD_SIZE);
  19829. +
  19830. + /* Prepend Header field */
  19831. + skb_push(skb, DECT_HDR_FIELD_SIZE);
  19832. + skb->data[DECT_HDR_FIELD_OFF] = DECT_A_CB(skb)->id;
  19833. + skb->data[DECT_HDR_FIELD_OFF] |= bearer->q;
  19834. + bearer->q = 0;
  19835. + return skb;
  19836. +}
  19837. +
  19838. +static struct sk_buff *dect_raw_tx_peek(struct dect_cell *cell)
  19839. +{
  19840. + struct dect_timer_base *base = &cell->timer_base[DECT_TIMER_TX];
  19841. + struct dect_skb_trx_cb *cb;
  19842. + struct sk_buff *skb;
  19843. +
  19844. + skb = skb_peek(&cell->raw_tx_queue);
  19845. + if (skb == NULL)
  19846. + return NULL;
  19847. + cb = DECT_TRX_CB(skb);
  19848. +
  19849. + if ((!cb->mfn || cb->mfn == base->mfn) &&
  19850. + (!cb->frame || cb->frame == base->framenum) &&
  19851. + cb->slot == dect_slotnum(cell, DECT_TIMER_TX))
  19852. + return skb;
  19853. +
  19854. + return NULL;
  19855. +}
  19856. +
  19857. +static void dect_raw_tx_configure(struct dect_cell *cell,
  19858. + struct dect_transceiver *trx,
  19859. + struct dect_transceiver_slot *ts)
  19860. +{
  19861. + if (dect_raw_tx_peek(cell)) {
  19862. + if (ts->state == DECT_SLOT_RX) {
  19863. + tx_debug(cell, "enable raw TX\n");
  19864. + dect_set_channel_mode(trx, &ts->chd, DECT_SLOT_TX);
  19865. + dect_set_carrier(trx, ts->chd.slot, ts->chd.carrier);
  19866. + ts->priv_flags |= DECT_SLOT_RAW_TX;
  19867. + }
  19868. + } else if (ts->priv_flags & DECT_SLOT_RAW_TX) {
  19869. + tx_debug(cell, "disable raw TX\n");
  19870. + dect_set_channel_mode(trx, &ts->chd, DECT_SLOT_RX);
  19871. + dect_set_carrier(trx, ts->chd.slot, ts->chd.carrier);
  19872. + ts->priv_flags &= ~DECT_SLOT_RAW_TX;
  19873. + }
  19874. +}
  19875. +
  19876. +static struct sk_buff *dect_raw_tx(struct dect_cell *cell)
  19877. +{
  19878. + struct sk_buff *skb;
  19879. +
  19880. + skb = dect_raw_tx_peek(cell);
  19881. + if (skb == NULL)
  19882. + return NULL;
  19883. +
  19884. + tx_debug(cell, "raw transmit\n");
  19885. + skb_unlink(skb, &cell->raw_tx_queue);
  19886. + return skb;
  19887. +}
  19888. +
  19889. +/**
  19890. + * dect_d_map - DECT D-Field mapping
  19891. + *
  19892. + * @cell: DECT cell
  19893. + * @bearer: MAC bearer
  19894. + *
  19895. + * Combine the A- and B-Fields from their respective MAPs into one D-Field.
  19896. + */
  19897. +static struct sk_buff *dect_d_map(struct dect_cell *cell,
  19898. + struct dect_bearer *bearer)
  19899. +{
  19900. + struct sk_buff *skb_a, *skb_b, *skb;
  19901. +
  19902. + skb = dect_raw_tx(cell);
  19903. + if (skb != NULL)
  19904. + return skb;
  19905. +
  19906. + skb_a = dect_a_map(cell, bearer);
  19907. + if (skb_a == NULL)
  19908. + goto err1;
  19909. +
  19910. + if (bearer->chd.pkt != DECT_PACKET_P00) {
  19911. + skb_b = dect_b_map(cell, bearer);
  19912. + if (skb_b == NULL)
  19913. + goto err2;
  19914. + skb_a->data[DECT_HDR_BA_OFF] |= DECT_B_CB(skb_b)->id;
  19915. +
  19916. + skb = skb_append_frag(skb_a, skb_b);
  19917. + if (skb_linearize(skb) < 0) {
  19918. + kfree_skb(skb);
  19919. + skb = NULL;
  19920. + }
  19921. + } else {
  19922. + skb_a->data[DECT_HDR_BA_OFF] |= DECT_BI_NONE;
  19923. + skb = skb_a;
  19924. + }
  19925. +
  19926. + return skb;
  19927. +
  19928. +err2:
  19929. + kfree_skb(skb_a);
  19930. +err1:
  19931. + return NULL;
  19932. +}
  19933. +
  19934. +static void dect_mac_xmit_frame(struct dect_transceiver *trx,
  19935. + struct dect_transceiver_slot *ts)
  19936. +{
  19937. + struct dect_cell *cell = trx->cell;
  19938. + struct dect_bearer *bearer = ts->bearer;
  19939. + struct sk_buff *skb;
  19940. +
  19941. + skb = dect_d_map(cell, bearer);
  19942. + if (skb == NULL)
  19943. + return;
  19944. +
  19945. + tx_debug(cell, "%s: Q1: %d Q2: %d A/B: %02x carrier: %u PSCN: %u\n",
  19946. + trx->name,
  19947. + skb->data[DECT_HDR_Q1_OFF] & DECT_HDR_Q1_FLAG ? 1 : 0,
  19948. + skb->data[DECT_HDR_Q2_OFF] & DECT_HDR_Q2_FLAG ? 1 : 0,
  19949. + skb->data[DECT_HDR_TA_OFF] &
  19950. + (DECT_HDR_TA_MASK | DECT_HDR_BA_MASK),
  19951. + ts->chd.carrier, cell->si.ssi.pscn);
  19952. +
  19953. + switch (cell->mode) {
  19954. + case DECT_MODE_FP:
  19955. + skb->mac_len = sizeof(dect_fp_preamble);
  19956. + memcpy(skb_mac_header(skb), dect_fp_preamble, skb->mac_len);
  19957. + break;
  19958. + case DECT_MODE_PP:
  19959. + skb->mac_len = sizeof(dect_pp_preamble);
  19960. + memcpy(skb_mac_header(skb), dect_pp_preamble, skb->mac_len);
  19961. + break;
  19962. + }
  19963. +
  19964. + DECT_TRX_CB(skb)->trx = trx;
  19965. + DECT_TRX_CB(skb)->slot = ts->chd.slot;
  19966. + DECT_TRX_CB(skb)->frame = dect_framenum(cell, DECT_TIMER_TX);
  19967. + DECT_TRX_CB(skb)->mfn = dect_mfn(cell, DECT_TIMER_TX);
  19968. + dect_raw_rcv(skb);
  19969. +
  19970. + dect_transceiver_tx(trx, skb);
  19971. +}
  19972. +
  19973. +void dect_mac_rcv(struct dect_transceiver *trx,
  19974. + struct dect_transceiver_slot *ts,
  19975. + struct sk_buff *skb)
  19976. +{
  19977. + struct dect_cell *cell = trx->cell;
  19978. +
  19979. + DECT_TRX_CB(skb)->frame = dect_framenum(cell, DECT_TIMER_RX);
  19980. + DECT_TRX_CB(skb)->mfn = dect_mfn(cell, DECT_TIMER_RX);
  19981. +
  19982. + /* TX bearers can temporarily switch to RX mode for noise measurement */
  19983. + if (ts->bearer != NULL &&
  19984. + ts->bearer->mode == DECT_BEARER_RX) {
  19985. + rx_debug(cell, "%s: Q1: %d Q2: %d A/B: %02x carrier: %u %s%s%s",
  19986. + trx->name,
  19987. + skb->data[DECT_HDR_Q1_OFF] & DECT_HDR_Q1_FLAG ? 1 : 0,
  19988. + skb->data[DECT_HDR_Q2_OFF] & DECT_HDR_Q2_FLAG ? 1 : 0,
  19989. + skb->data[DECT_HDR_TA_OFF] &
  19990. + (DECT_HDR_TA_MASK | DECT_HDR_BA_MASK), ts->chd.carrier,
  19991. + DECT_TRX_CB(skb)->csum & DECT_CHECKSUM_A_CRC_OK ?
  19992. + "" : "A-CRC: 0 ",
  19993. + ts->chd.pkt == DECT_PACKET_P00 ||
  19994. + DECT_TRX_CB(skb)->csum & DECT_CHECKSUM_X_CRC_OK ?
  19995. + "" : "X-CRC: 0 ",
  19996. + ts->chd.pkt == DECT_PACKET_P00 ||
  19997. + DECT_TRX_CB(skb)->csum & DECT_CHECKSUM_Z_CRC_OK ?
  19998. + "" : "Z-CRC: 0 ");
  19999. +
  20000. + ts->bearer->ops->rcv(cell, ts->bearer, skb);
  20001. + } else
  20002. + kfree_skb(skb);
  20003. +}
  20004. +
  20005. +void dect_mac_report_rssi(struct dect_transceiver *trx,
  20006. + struct dect_transceiver_slot *ts,
  20007. + u8 rssi)
  20008. +{
  20009. + struct dect_cell *cell = trx->cell;
  20010. +
  20011. + if (ts->bearer == NULL) {
  20012. + pr_debug("%s: RSSI: slot: %u carrier: %u state: %u no bearer\n",
  20013. + trx->name, ts->chd.slot, ts->chd.carrier, ts->state);
  20014. + return;
  20015. + }
  20016. + if (ts->bearer->state != DECT_BEARER_ENABLED)
  20017. + dect_tx_bearer_report_rssi(cell, ts->bearer, rssi);
  20018. + else if (ts->bearer->ops->report_rssi != NULL)
  20019. + ts->bearer->ops->report_rssi(cell, ts->bearer, ts->chd.slot, rssi);
  20020. +}
  20021. +
  20022. +static void dect_fp_state_process(struct dect_cell *cell)
  20023. +{
  20024. + if (list_empty(&cell->dbcs))
  20025. + dect_dbc_init(cell, NULL);
  20026. +
  20027. + if (time_before(cell->bfs_xmit_stamp + HZ, jiffies)) {
  20028. + dect_cell_schedule_page(cell, (1 << DECT_TM_TYPE_BFS) |
  20029. + (1 << DECT_TM_TYPE_BD));
  20030. + cell->bfs_xmit_stamp = jiffies;
  20031. + }
  20032. +}
  20033. +
  20034. +static bool dect_pp_idle_timeout(const struct dect_cell *cell)
  20035. +{
  20036. + u32 mfn;
  20037. +
  20038. + mfn = dect_mfn_add(cell->timer_sync_stamp, DECT_CELL_TIMER_RESYNC_TIMEOUT);
  20039. + if (dect_mfn_after(dect_mfn(cell, DECT_TIMER_RX), mfn) ||
  20040. + time_after(jiffies, cell->a_rcv_stamp + DECT_CELL_A_RCV_TIMEOUT) ||
  20041. + time_after(jiffies, cell->nt_rcv_stamp + DECT_CELL_NT_RCV_TIMEOUT)) {
  20042. + pr_debug("timeout, unlock, a: %ld nt: %ld mfn: %d\n",
  20043. + jiffies - cell->a_rcv_stamp, jiffies - cell->nt_rcv_stamp,
  20044. + dect_mfn(cell, DECT_TIMER_RX) - cell->timer_sync_stamp);
  20045. + return true;
  20046. + }
  20047. +
  20048. + return false;
  20049. +}
  20050. +
  20051. +static void dect_pp_state_process(struct dect_cell *cell)
  20052. +{
  20053. + struct dect_transceiver *trx = cell->trg.trx[0];
  20054. + struct dect_dbc *dbc, *next;
  20055. +
  20056. + if (cell->tbc_num_est || !list_empty(&cell->dmbs)) {
  20057. + /* Active locked state: release DBCs */
  20058. + list_for_each_entry_safe(dbc, next, &cell->dbcs, list)
  20059. + dect_dbc_release(dbc);
  20060. + } else if (trx->state == DECT_TRANSCEIVER_LOCKED) {
  20061. + /* Idle locked state: install DBC if none present */
  20062. + if (list_empty(&cell->dbcs) &&
  20063. + list_empty(&cell->tbcs) &&
  20064. + list_empty(&cell->dmbs)) {
  20065. + struct dect_channel_desc chd;
  20066. +
  20067. + chd.pkt = DECT_PACKET_P00;
  20068. + chd.b_fmt = DECT_B_NONE;
  20069. + chd.slot = cell->tbc_last_chd.slot;
  20070. + chd.carrier = cell->tbc_last_chd.carrier;
  20071. +
  20072. + dect_dbc_init(cell, &chd);
  20073. + }
  20074. +
  20075. + if (!list_empty(&cell->dbcs) && dect_pp_idle_timeout(cell)) {
  20076. + list_for_each_entry_safe(dbc, next, &cell->dbcs, list)
  20077. + dect_dbc_release(dbc);
  20078. +
  20079. + dect_irc_disable(cell, trx->irc);
  20080. + dect_transceiver_unlock(trx);
  20081. +
  20082. + dect_chl_flush(cell);
  20083. + /* Clear system information */
  20084. + memset(&cell->si, 0, sizeof(cell->si));
  20085. + dect_cell_mac_info_ind(cell);
  20086. +
  20087. + dect_attempt_lock(cell, trx);
  20088. + }
  20089. + }
  20090. +}
  20091. +
  20092. +static void dect_cell_state_process(struct dect_cell *cell)
  20093. +{
  20094. + if (list_empty(&cell->chanlists) && list_empty(&cell->chl_pending)) {
  20095. + dect_chl_schedule_update(cell, DECT_PACKET_P00);
  20096. + dect_chl_schedule_update(cell, DECT_PACKET_P32);
  20097. + if (cell->trg.features & DECT_TRANSCEIVER_PACKET_P64 &&
  20098. + cell->si.efpc2.fpc & DECT_EFPC2_LONG_SLOT_J640)
  20099. + dect_chl_schedule_update(cell, DECT_PACKET_P640j);
  20100. + }
  20101. +
  20102. + switch (cell->mode) {
  20103. + case DECT_MODE_FP:
  20104. + return dect_fp_state_process(cell);
  20105. + case DECT_MODE_PP:
  20106. + return dect_pp_state_process(cell);
  20107. + }
  20108. +}
  20109. +
  20110. +static void dect_cluster_time_ind(struct dect_cell *cell,
  20111. + enum dect_timer_bases base,
  20112. + u8 slot)
  20113. +{
  20114. + struct dect_cluster_handle *clh = cell->handle.clh;
  20115. +
  20116. + clh->ops->time_ind(clh, base,
  20117. + dect_mfn(cell, base),
  20118. + dect_framenum(cell, base),
  20119. + slot);
  20120. +}
  20121. +
  20122. +void dect_mac_rx_tick(struct dect_transceiver_group *grp, u8 slot)
  20123. +{
  20124. + struct dect_cell *cell = container_of(grp, struct dect_cell, trg);
  20125. +
  20126. + dect_run_timers(cell, DECT_TIMER_RX);
  20127. + dect_timer_base_update(cell, DECT_TIMER_RX, slot);
  20128. + dect_cluster_time_ind(cell, DECT_TIMER_RX, slot);
  20129. +}
  20130. +
  20131. +void dect_mac_tx_tick(struct dect_transceiver_group *grp, u8 slot)
  20132. +{
  20133. + struct dect_cell *cell = container_of(grp, struct dect_cell, trg);
  20134. + struct dect_transceiver_slot *ts;
  20135. + struct dect_transceiver *trx;
  20136. + u8 scn;
  20137. +
  20138. + /* TX timers run at the beginning of a slot, update the time first */
  20139. + dect_timer_base_update(cell, DECT_TIMER_TX, slot);
  20140. + dect_cluster_time_ind(cell, DECT_TIMER_TX, slot);
  20141. + dect_run_timers(cell, DECT_TIMER_TX);
  20142. +
  20143. + dect_cell_state_process(cell);
  20144. +
  20145. + dect_foreach_transceiver(trx, grp) {
  20146. + if (trx->state != DECT_TRANSCEIVER_LOCKED)
  20147. + continue;
  20148. + ts = &trx->slots[slot];
  20149. +
  20150. + dect_raw_tx_configure(cell, trx, ts);
  20151. +
  20152. + switch (ts->state) {
  20153. + case DECT_SLOT_SCANNING:
  20154. + scn = trx->irc->tx_scn;
  20155. +
  20156. + if (cell->flags & DECT_CELL_MONITOR &&
  20157. + slot >= DECT_HALF_FRAME_SIZE)
  20158. + scn = dect_prev_carrier(cell->si.ssi.rfcars, scn);
  20159. +
  20160. + dect_set_carrier(trx, slot, scn);
  20161. + break;
  20162. + case DECT_SLOT_TX:
  20163. + dect_mac_xmit_frame(trx, ts);
  20164. + break;
  20165. + }
  20166. + }
  20167. +
  20168. + if (slot == DECT_FRAME_SIZE - 1)
  20169. + cell->si.ssi.pscn = dect_next_carrier(cell->si.ssi.rfcars,
  20170. + cell->si.ssi.pscn);
  20171. +}
  20172. +
  20173. +static void dect_fp_init_primary(struct dect_cell *cell,
  20174. + struct dect_transceiver *trx)
  20175. +{
  20176. + dect_transceiver_enable(trx);
  20177. + dect_irc_enable(cell, trx->irc);
  20178. +}
  20179. +
  20180. +static void dect_cell_enable_transceiver(struct dect_cell *cell,
  20181. + struct dect_transceiver *trx)
  20182. +{
  20183. + /* The primary transceiver of a FP is a timing master. All other
  20184. + * transceivers need to synchronize.
  20185. + */
  20186. + if (trx->index == 0 && cell->mode == DECT_MODE_FP &&
  20187. + !(cell->flags & DECT_CELL_SLAVE)) {
  20188. + trx->mode = DECT_TRANSCEIVER_MASTER;
  20189. + dect_fp_init_primary(cell, trx);
  20190. + } else {
  20191. + trx->mode = DECT_TRANSCEIVER_SLAVE;
  20192. + dect_attempt_lock(cell, trx);
  20193. + }
  20194. +}
  20195. +
  20196. +static int dect_cell_preload(const struct dect_cell_handle *ch,
  20197. + const struct dect_ari *pari, u8 rpn,
  20198. + const struct dect_si *si)
  20199. +{
  20200. + struct dect_cell *cell = dect_cell(ch);
  20201. +
  20202. + /* Initialise identity */
  20203. + spin_lock_bh(&cell->lock);
  20204. + cell->idi.e = false;
  20205. + memcpy(&cell->idi.pari, pari, sizeof(cell->idi.pari));
  20206. + cell->idi.rpn = rpn;
  20207. + cell->fmid = dect_build_fmid(&cell->idi);
  20208. +
  20209. + cell->si.ssi.rfcars = 0x3ff;
  20210. + memcpy(&cell->si.erfc, &si->erfc, sizeof(cell->si.erfc));
  20211. + memcpy(&cell->si.fpc, &si->fpc, sizeof(cell->si.fpc));
  20212. + memcpy(&cell->si.efpc, &si->efpc, sizeof(cell->si.efpc));
  20213. + memcpy(&cell->si.efpc2, &si->efpc2, sizeof(cell->si.efpc2));
  20214. + memcpy(&cell->si.mfn, &si->mfn, sizeof(cell->si.mfn));
  20215. + memcpy(cell->si.sari, si->sari, sizeof(cell->si.sari));
  20216. + cell->si.num_saris = si->num_saris;
  20217. + dect_timer_synchronize_mfn(cell, cell->si.mfn.num);
  20218. + spin_unlock_bh(&cell->lock);
  20219. + return 0;
  20220. +}
  20221. +
  20222. +static int dect_cell_enable(const struct dect_cell_handle *ch)
  20223. +{
  20224. + struct dect_cell *cell = dect_cell(ch);
  20225. + struct dect_transceiver *trx;
  20226. +
  20227. + cell->state |= DECT_CELL_ENABLED;
  20228. + dect_foreach_transceiver(trx, &cell->trg) {
  20229. + dect_cell_enable_transceiver(cell, trx);
  20230. + if (cell->mode == DECT_MODE_PP)
  20231. + break;
  20232. + }
  20233. + return 0;
  20234. +}
  20235. +
  20236. +static void dect_scan_report(struct dect_cell *cell,
  20237. + struct dect_transceiver *trx,
  20238. + enum dect_scan_status status)
  20239. +{
  20240. + const struct dect_cluster_handle *clh = cell->handle.clh;
  20241. + const struct dect_irc *irc = trx->irc;
  20242. + struct dect_scan_result res;
  20243. +
  20244. + switch (status) {
  20245. + case DECT_SCAN_FAIL:
  20246. + break;
  20247. + case DECT_SCAN_TIMEOUT:
  20248. + pr_debug("timeout\n");
  20249. + case DECT_SCAN_COMPLETE:
  20250. + res.lreq = irc->lreq;
  20251. + res.rssi = irc->rssi;
  20252. + res.idi = irc->idi;
  20253. + res.si = irc->si;
  20254. + clh->ops->scan_report(clh, &res);
  20255. + break;
  20256. + }
  20257. +
  20258. + return dect_restart_scan(cell, trx);
  20259. +}
  20260. +
  20261. +static int dect_cell_scan(const struct dect_cell_handle *ch,
  20262. + const struct dect_llme_req *lreq,
  20263. + const struct dect_ari *pari,
  20264. + const struct dect_ari *pari_mask)
  20265. +{
  20266. + struct dect_cell *cell = dect_cell(ch);
  20267. + struct dect_transceiver *trx = cell->trg.trx[0];
  20268. +
  20269. + if (trx == NULL)
  20270. + return -ENODEV;
  20271. + // FIXME
  20272. + memcpy(&trx->irc->lreq, lreq, sizeof(trx->irc->lreq));
  20273. + dect_initiate_scan(trx, pari, pari_mask, dect_scan_report);
  20274. + return 0;
  20275. +}
  20276. +
  20277. +static int dect_cell_set_mode(const struct dect_cell_handle *ch,
  20278. + enum dect_cluster_modes mode)
  20279. +{
  20280. + struct dect_cell *cell = dect_cell(ch);
  20281. +
  20282. + cell->mode = mode;
  20283. + return 0;
  20284. +}
  20285. +
  20286. +static void dect_cell_page_req(const struct dect_cell_handle *ch,
  20287. + struct sk_buff *skb)
  20288. +{
  20289. + struct dect_cell *cell = dect_cell(ch);
  20290. +
  20291. + DECT_BMC_CB(skb)->stamp = dect_mfn(cell, DECT_TIMER_TX);
  20292. + dect_queue_page(cell, skb);
  20293. +}
  20294. +
  20295. +static const struct dect_csf_ops dect_csf_ops = {
  20296. + .set_mode = dect_cell_set_mode,
  20297. + .scan = dect_cell_scan,
  20298. + .enable = dect_cell_enable,
  20299. + .preload = dect_cell_preload,
  20300. + .page_req = dect_cell_page_req,
  20301. + .tbc_establish_req = dect_tbc_establish_req,
  20302. + .tbc_establish_res = dect_tbc_establish_res,
  20303. + .tbc_dis_req = dect_tbc_dis_req,
  20304. + .tbc_enc_key_req = dect_tbc_enc_key_req,
  20305. + .tbc_enc_eks_req = dect_tbc_enc_eks_req,
  20306. + .tbc_enc_req = dect_tbc_enc_req,
  20307. + .tbc_data_req = dect_tbc_data_req,
  20308. +};
  20309. +
  20310. +static int dect_cell_bind(struct dect_cell *cell, u8 index)
  20311. +{
  20312. + struct dect_cluster_handle *clh;
  20313. + struct dect_cluster *cl;
  20314. +
  20315. + if (cell->flags & DECT_CELL_CCP) {
  20316. + clh = dect_ccp_cell_init(cell, index);
  20317. + if (IS_ERR(clh))
  20318. + return PTR_ERR(clh);
  20319. + } else {
  20320. + cl = dect_cluster_get_by_index(index);
  20321. + if (cl == NULL)
  20322. + return -ENOENT;
  20323. + clh = &cl->handle;
  20324. + }
  20325. +
  20326. + return clh->ops->bind(clh, &cell->handle);
  20327. +}
  20328. +
  20329. +static void dect_cell_shutdown(struct dect_cell *cell)
  20330. +{
  20331. + struct dect_cluster_handle *clh = cell->handle.clh;
  20332. + struct dect_transceiver *trx;
  20333. +
  20334. + if (clh != NULL)
  20335. + clh->ops->unbind(clh, &cell->handle);
  20336. +
  20337. + dect_foreach_transceiver(trx, &cell->trg)
  20338. + dect_cell_detach_transceiver(cell, trx);
  20339. + dect_cell_bmc_disable(cell);
  20340. + skb_queue_purge(&cell->raw_tx_queue);
  20341. + dect_chl_flush(cell);
  20342. +}
  20343. +
  20344. +/**
  20345. + * dect_mac_init_cell - Initialize a DECT cell
  20346. + */
  20347. +static void dect_cell_init(struct dect_cell *cell)
  20348. +{
  20349. + spin_lock_init(&cell->lock);
  20350. + INIT_LIST_HEAD(&cell->bcs);
  20351. + INIT_LIST_HEAD(&cell->dbcs);
  20352. + INIT_LIST_HEAD(&cell->tbcs);
  20353. + INIT_LIST_HEAD(&cell->dmbs);
  20354. + INIT_LIST_HEAD(&cell->chl_pending);
  20355. + INIT_LIST_HEAD(&cell->chanlists);
  20356. + dect_timer_base_init(cell->timer_base, DECT_TIMER_TX);
  20357. + dect_timer_base_init(cell->timer_base, DECT_TIMER_RX);
  20358. + skb_queue_head_init(&cell->raw_tx_queue);
  20359. + dect_cell_bmc_init(cell);
  20360. + cell->blind_full_slots = (1 << DECT_HALF_FRAME_SIZE) - 1;
  20361. + cell->trg_blind_full_slots = (1 << DECT_HALF_FRAME_SIZE) - 1;
  20362. + dect_transceiver_group_init(&cell->trg);
  20363. + cell->handle.ops = &dect_csf_ops;
  20364. +}
  20365. +
  20366. +/**
  20367. + * dect_cell_attach_transceiver - attach a transceiver to a DECT cell
  20368. + *
  20369. + * Attach the transceiver to the cell's transceiver group and initialize
  20370. + * an idle receiver control instance.
  20371. + */
  20372. +int dect_cell_attach_transceiver(struct dect_cell *cell,
  20373. + struct dect_transceiver *trx)
  20374. +{
  20375. + int err;
  20376. +
  20377. + if (trx->cell != NULL)
  20378. + return -EBUSY;
  20379. +
  20380. + err = dect_transceiver_group_add(&cell->trg, trx);
  20381. + if (err < 0)
  20382. + goto err1;
  20383. +
  20384. + err = -ENOMEM;
  20385. + if (!dect_irc_init(cell, trx))
  20386. + goto err2;
  20387. +
  20388. + trx->cell = cell;
  20389. + if (cell->state & DECT_CELL_ENABLED)
  20390. + dect_cell_enable_transceiver(cell, trx);
  20391. +
  20392. + return 0;
  20393. +
  20394. +err2:
  20395. + dect_transceiver_group_remove(&cell->trg, trx);
  20396. +err1:
  20397. + return err;
  20398. +}
  20399. +
  20400. +/**
  20401. + * dect_cell_detach_transceiver - detach a transceiver from a DECT cell
  20402. + *
  20403. + * Detach the transceiver from the cell's transceiver group and release
  20404. + * the associated resources.
  20405. + */
  20406. +void dect_cell_detach_transceiver(struct dect_cell *cell,
  20407. + struct dect_transceiver *trx)
  20408. +{
  20409. + dect_irc_disable(cell, trx->irc);
  20410. + dect_transceiver_disable(trx);
  20411. + dect_transceiver_group_remove(&cell->trg, trx);
  20412. + kfree(trx->irc);
  20413. + trx->cell = NULL;
  20414. +
  20415. + dect_notify_cell(DECT_NEW_CELL, cell, NULL, 0);
  20416. +}
  20417. +
  20418. +/*
  20419. + * Cell netlink interface
  20420. + */
  20421. +
  20422. +static u32 dect_cell_alloc_index(void)
  20423. +{
  20424. + static u32 index;
  20425. +
  20426. + for (;;) {
  20427. + if (++index == 0)
  20428. + index = 1;
  20429. + if (!dect_cell_get_by_index(index))
  20430. + return index;
  20431. + }
  20432. +}
  20433. +
  20434. +static int dect_fill_cell(struct sk_buff *skb,
  20435. + const struct dect_cell *cell,
  20436. + u16 type, u32 portid, u32 seq, u16 flags)
  20437. +{
  20438. + const struct dect_transceiver *trx;
  20439. + struct nlmsghdr *nlh;
  20440. + struct dectmsg *dm;
  20441. + struct nlattr *nest;
  20442. +
  20443. + nlh = nlmsg_put(skb, portid, seq, type, sizeof(*dm), flags);
  20444. + if (nlh == NULL)
  20445. + return -EMSGSIZE;
  20446. + dm = nlmsg_data(nlh);
  20447. + dm->dm_index = cell->index;
  20448. +
  20449. + if (nla_put_string(skb, DECTA_CELL_NAME, cell->name))
  20450. + goto nla_put_failure;
  20451. + if (cell->flags != 0) {
  20452. + if (nla_put_u32(skb, DECTA_CELL_FLAGS, cell->flags))
  20453. + goto nla_put_failure;
  20454. + }
  20455. + if (cell->trg.trxmask != 0) {
  20456. + nest = nla_nest_start(skb, DECTA_CELL_TRANSCEIVERS);
  20457. + if (nest == NULL)
  20458. + goto nla_put_failure;
  20459. + dect_foreach_transceiver(trx, &cell->trg)
  20460. + if (nla_put_string(skb, DECTA_LIST_ELEM, trx->name))
  20461. + goto nla_put_failure;
  20462. + nla_nest_end(skb, nest);
  20463. + }
  20464. + if (cell->handle.clh != NULL) {
  20465. + if (nla_put_u8(skb, DECTA_CELL_CLUSTER,
  20466. + cell->handle.clh->index))
  20467. + goto nla_put_failure;
  20468. + }
  20469. +
  20470. + nlmsg_end(skb, nlh);
  20471. + return skb->len;
  20472. +
  20473. +nla_put_failure:
  20474. + nlmsg_cancel(skb, nlh);
  20475. + return -EMSGSIZE;
  20476. +}
  20477. +
  20478. +static int dect_dump_cell(struct sk_buff *skb,
  20479. + struct netlink_callback *cb)
  20480. +{
  20481. + const struct dect_cell *cell;
  20482. + unsigned int idx, s_idx;
  20483. +
  20484. + s_idx = cb->args[0];
  20485. + idx = 0;
  20486. + list_for_each_entry(cell, &dect_cell_list, list) {
  20487. + if (idx < s_idx)
  20488. + goto cont;
  20489. + if (dect_fill_cell(skb, cell, DECT_NEW_CELL,
  20490. + NETLINK_CB(cb->skb).portid,
  20491. + cb->nlh->nlmsg_seq, NLM_F_MULTI) <= 0)
  20492. + break;
  20493. +cont:
  20494. + idx++;
  20495. + }
  20496. + cb->args[0] = idx;
  20497. +
  20498. + return skb->len;
  20499. +}
  20500. +
  20501. +static void dect_notify_cell(u16 event, const struct dect_cell *cell,
  20502. + const struct nlmsghdr *nlh, u32 portid)
  20503. +{
  20504. + struct sk_buff *skb;
  20505. + bool report = nlh ? nlmsg_report(nlh) : 0;
  20506. + u32 seq = nlh ? nlh->nlmsg_seq : 0;
  20507. + int err = -ENOBUFS;
  20508. +
  20509. + skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
  20510. + if (skb == NULL)
  20511. + goto err;
  20512. +
  20513. + err = dect_fill_cell(skb, cell, event, portid, seq, NLMSG_DONE);
  20514. + if (err < 0) {
  20515. + WARN_ON(err == -EMSGSIZE);
  20516. + kfree_skb(skb);
  20517. + goto err;
  20518. + }
  20519. + nlmsg_notify(dect_nlsk, skb, portid, DECTNLGRP_CELL, report,
  20520. + GFP_KERNEL);
  20521. +err:
  20522. + if (err < 0)
  20523. + netlink_set_err(dect_nlsk, portid, DECTNLGRP_CELL, err);
  20524. +}
  20525. +
  20526. +static const struct nla_policy dect_cell_policy[DECTA_CELL_MAX + 1] = {
  20527. + [DECTA_CELL_NAME] = { .type = NLA_STRING, .len = DECTNAMSIZ },
  20528. + [DECTA_CELL_FLAGS] = { .type = NLA_U32 },
  20529. + [DECTA_CELL_CLUSTER] = { .type = NLA_U8 },
  20530. +};
  20531. +
  20532. +static int dect_new_cell(const struct sk_buff *skb,
  20533. + const struct nlmsghdr *nlh,
  20534. + const struct nlattr *tb[DECTA_CELL_MAX + 1])
  20535. +{
  20536. + struct dect_cell *cell;
  20537. + struct dectmsg *dm;
  20538. + u32 flags = 0;
  20539. + u8 cli = 0;
  20540. + int err;
  20541. +
  20542. + dm = nlmsg_data(nlh);
  20543. + if (dm->dm_index != 0)
  20544. + cell = dect_cell_get_by_index(dm->dm_index);
  20545. + else if (tb[DECTA_CELL_NAME] != NULL)
  20546. + cell = dect_cell_get_by_name(tb[DECTA_CELL_NAME]);
  20547. + else
  20548. + return -EINVAL;
  20549. +
  20550. + if (tb[DECTA_CELL_FLAGS] != NULL) {
  20551. + flags = nla_get_u32(tb[DECTA_CELL_FLAGS]);
  20552. + if (flags & ~(DECT_CELL_CCP | DECT_CELL_SLAVE |
  20553. + DECT_CELL_MONITOR))
  20554. + return -EINVAL;
  20555. + }
  20556. +
  20557. + if (tb[DECTA_CELL_CLUSTER] != NULL)
  20558. + cli = nla_get_u8(tb[DECTA_CELL_CLUSTER]);
  20559. +
  20560. + if (cell != NULL) {
  20561. + if (nlh->nlmsg_flags & NLM_F_EXCL)
  20562. + return -EEXIST;
  20563. +
  20564. + if (tb[DECTA_CELL_CLUSTER] != NULL) {
  20565. + if (cell->handle.clh != NULL)
  20566. + return -EBUSY;
  20567. + if (cli != 0)
  20568. + return dect_cell_bind(cell, cli);
  20569. + }
  20570. + return 0;
  20571. + }
  20572. +
  20573. + if (!(nlh->nlmsg_flags & NLM_F_CREATE))
  20574. + return -ENOENT;
  20575. +
  20576. + cell = kzalloc(sizeof(*cell), GFP_KERNEL);
  20577. + if (cell == NULL)
  20578. + return -ENOMEM;
  20579. + cell->index = dect_cell_alloc_index();
  20580. + nla_strlcpy(cell->name, tb[DECTA_CELL_NAME], sizeof(cell->name));
  20581. + cell->flags = flags;
  20582. + dect_cell_init(cell);
  20583. +
  20584. + if (cli != 0) {
  20585. + err = dect_cell_bind(cell, cli);
  20586. + if (err < 0)
  20587. + goto err;
  20588. + }
  20589. +
  20590. + list_add_tail(&cell->list, &dect_cell_list);
  20591. + dect_notify_cell(DECT_NEW_CELL, cell, nlh, NETLINK_CB(skb).portid);
  20592. + return 0;
  20593. +
  20594. +err:
  20595. + kfree(cell);
  20596. + return err;
  20597. +}
  20598. +
  20599. +static int dect_del_cell(const struct sk_buff *skb,
  20600. + const struct nlmsghdr *nlh,
  20601. + const struct nlattr *tb[DECTA_CELL_MAX + 1])
  20602. +{
  20603. + struct dect_cell *cell = NULL;
  20604. + struct dectmsg *dm;
  20605. +
  20606. + dm = nlmsg_data(nlh);
  20607. + if (dm->dm_index != 0)
  20608. + cell = dect_cell_get_by_index(dm->dm_index);
  20609. + else if (tb[DECTA_CELL_NAME] != NULL)
  20610. + cell = dect_cell_get_by_name(tb[DECTA_CELL_NAME]);
  20611. + if (cell == NULL)
  20612. + return -ENODEV;
  20613. +
  20614. + cell = dect_cell_get_by_name(tb[DECTA_CELL_NAME]);
  20615. + if (cell == NULL)
  20616. + return -ENOENT;
  20617. +
  20618. + dect_cell_shutdown(cell);
  20619. + list_del(&cell->list);
  20620. + dect_notify_cell(DECT_DEL_CELL, cell, nlh, NETLINK_CB(skb).portid);
  20621. + kfree(cell);
  20622. + return 0;
  20623. +}
  20624. +
  20625. +static int dect_get_cell(const struct sk_buff *in_skb,
  20626. + const struct nlmsghdr *nlh,
  20627. + const struct nlattr *tb[DECTA_CELL_MAX + 1])
  20628. +{
  20629. + u32 portid = NETLINK_CB(in_skb).portid;
  20630. + const struct dect_cell *cell = NULL;
  20631. + struct dectmsg *dm;
  20632. + struct sk_buff *skb;
  20633. + int err;
  20634. +
  20635. + dm = nlmsg_data(nlh);
  20636. + if (dm->dm_index != 0)
  20637. + cell = dect_cell_get_by_index(dm->dm_index);
  20638. + else if (tb[DECTA_CELL_NAME] != NULL)
  20639. + cell = dect_cell_get_by_name(tb[DECTA_CELL_NAME]);
  20640. + if (cell == NULL)
  20641. + return -ENODEV;
  20642. +
  20643. + skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
  20644. + if (skb == NULL)
  20645. + return -ENOMEM;
  20646. + err = dect_fill_cell(skb, cell, DECT_NEW_CELL, portid, nlh->nlmsg_seq,
  20647. + NLMSG_DONE);
  20648. + if (err < 0)
  20649. + goto err1;
  20650. + return nlmsg_unicast(dect_nlsk, skb, portid);
  20651. +
  20652. +err1:
  20653. + kfree_skb(skb);
  20654. + return err;
  20655. +}
  20656. +
  20657. +static const struct dect_netlink_handler dect_cell_handlers[] = {
  20658. + {
  20659. + /* DECT_NEW_CELL */
  20660. + .policy = dect_cell_policy,
  20661. + .maxtype = DECTA_CELL_MAX,
  20662. + .doit = dect_new_cell,
  20663. + },
  20664. + {
  20665. + /* DECT_DEL_CELL */
  20666. + .policy = dect_cell_policy,
  20667. + .maxtype = DECTA_CELL_MAX,
  20668. + .doit = dect_del_cell,
  20669. + },
  20670. + {
  20671. + /* DECT_GET_CELL */
  20672. + .policy = dect_cell_policy,
  20673. + .maxtype = DECTA_CELL_MAX,
  20674. + .doit = dect_get_cell,
  20675. + .dump = dect_dump_cell,
  20676. + },
  20677. +};
  20678. +
  20679. +static int __init dect_csf_module_init(void)
  20680. +{
  20681. + int err;
  20682. +
  20683. + err = dect_transceiver_module_init();
  20684. + if (err < 0)
  20685. + return err;
  20686. +
  20687. + dect_netlink_register_handlers(dect_cell_handlers, DECT_NEW_CELL,
  20688. + ARRAY_SIZE(dect_cell_handlers));
  20689. + return 0;
  20690. +}
  20691. +
  20692. +static void __exit dect_csf_module_exit(void)
  20693. +{
  20694. + dect_netlink_unregister_handlers(DECT_NEW_CELL,
  20695. + ARRAY_SIZE(dect_cell_handlers));
  20696. + dect_transceiver_module_exit();
  20697. +}
  20698. +
  20699. +module_init(dect_csf_module_init);
  20700. +module_exit(dect_csf_module_exit);
  20701. +MODULE_LICENSE("GPL");
  20702. diff --git a/net/dect/raw.c b/net/dect/raw.c
  20703. new file mode 100644
  20704. index 0000000..97ccf71
  20705. --- /dev/null
  20706. +++ b/net/dect/raw.c
  20707. @@ -0,0 +1,267 @@
  20708. +/*
  20709. + * DECT RAW sockets
  20710. + *
  20711. + * Copyright (c) 2009 Patrick McHardy <[email protected]>
  20712. + *
  20713. + * This program is free software; you can redistribute it and/or modify
  20714. + * it under the terms of the GNU General Public License version 2 as
  20715. + * published by the Free Software Foundation.
  20716. + */
  20717. +
  20718. +#include <linux/kernel.h>
  20719. +#include <linux/module.h>
  20720. +#include <linux/init.h>
  20721. +#include <linux/socket.h>
  20722. +#include <linux/net.h>
  20723. +#include <linux/dect.h>
  20724. +#include <net/sock.h>
  20725. +#include <net/dect/dect.h>
  20726. +#include <net/dect/mac_csf.h>
  20727. +
  20728. +static HLIST_HEAD(dect_raw_sockets);
  20729. +
  20730. +struct dect_raw_sk {
  20731. + struct sock sk;
  20732. +};
  20733. +
  20734. +static inline struct dect_raw_sk *dect_raw_sk(struct sock *sk)
  20735. +{
  20736. + return (struct dect_raw_sk *)sk;
  20737. +}
  20738. +
  20739. +static void __dect_raw_rcv(struct sk_buff *skb)
  20740. +{
  20741. + struct dect_cell *cell = DECT_TRX_CB(skb)->trx->cell;
  20742. + struct sk_buff *skb2;
  20743. + struct sock *sk;
  20744. +
  20745. + sk_for_each_bound(sk, &dect_raw_sockets) {
  20746. + if (sk->sk_bound_dev_if &&
  20747. + sk->sk_bound_dev_if != cell->index)
  20748. + continue;
  20749. + if (skb->sk == sk)
  20750. + continue;
  20751. +
  20752. + skb2 = skb_clone(skb, GFP_ATOMIC);
  20753. + if (skb2 == NULL) {
  20754. + sk->sk_err = -ENOMEM;
  20755. + sk->sk_error_report(sk);
  20756. + } else {
  20757. + /* Release the transceiver reference, it is only valid
  20758. + * in IRQ and softirq context.
  20759. + */
  20760. + DECT_TRX_CB(skb2)->trx = NULL;
  20761. + if (dect_sock_queue_rcv_skb(sk, skb2) < 0)
  20762. + kfree_skb(skb2);
  20763. + }
  20764. + }
  20765. +}
  20766. +
  20767. +static void dect_raw_close(struct sock *sk, long timeout)
  20768. +{
  20769. + sk_common_release(sk);
  20770. +}
  20771. +
  20772. +static int dect_raw_bind(struct sock *sk, struct sockaddr *uaddr, int len)
  20773. +{
  20774. + struct sockaddr_dect *addr = (struct sockaddr_dect *)uaddr;
  20775. +
  20776. + if (len < sizeof(*addr) || addr->dect_family != AF_DECT)
  20777. + return -EINVAL;
  20778. +
  20779. + if (addr->dect_index != 0 &&
  20780. + !dect_cell_get_by_index(addr->dect_index))
  20781. + return -ENODEV;
  20782. +
  20783. + lock_sock(sk);
  20784. + sk->sk_bound_dev_if = addr->dect_index;
  20785. + if (!hlist_unhashed(&sk->sk_bind_node))
  20786. + __sk_del_bind_node(sk);
  20787. + sk_add_bind_node(sk, &dect_raw_sockets);
  20788. + release_sock(sk);
  20789. + return 0;
  20790. +}
  20791. +
  20792. +static void dect_raw_unhash(struct sock *sk)
  20793. +{
  20794. + if (!hlist_unhashed(&sk->sk_bind_node))
  20795. + __sk_del_bind_node(sk);
  20796. +}
  20797. +
  20798. +static int dect_raw_getname(struct sock *sk, struct sockaddr *uaddr, int *len,
  20799. + int peer)
  20800. +{
  20801. + struct sockaddr_dect *addr = (struct sockaddr_dect *)uaddr;
  20802. +
  20803. + if (peer)
  20804. + return -EOPNOTSUPP;
  20805. +
  20806. + addr->dect_family = AF_DECT;
  20807. + addr->dect_index = sk->sk_bound_dev_if;
  20808. + *len = sizeof(*addr);
  20809. + return 0;
  20810. +}
  20811. +
  20812. +static int dect_raw_recvmsg(struct sock *sk,
  20813. + struct msghdr *msg, size_t len,
  20814. + int noblock, int flags, int *addrlen)
  20815. +{
  20816. + struct sockaddr_dect *addr;
  20817. + struct dect_raw_auxdata aux;
  20818. + struct sk_buff *skb;
  20819. + size_t copied = 0;
  20820. + int err;
  20821. +
  20822. + if (flags & MSG_OOB)
  20823. + return -EOPNOTSUPP;
  20824. +
  20825. + skb = skb_recv_datagram(sk, flags, noblock, &err);
  20826. + if (skb == NULL)
  20827. + goto out;
  20828. +
  20829. + copied = skb->len;
  20830. + if (len < copied) {
  20831. + msg->msg_flags |= MSG_TRUNC;
  20832. + copied = len;
  20833. + }
  20834. +
  20835. + err = skb_copy_datagram_msg(skb, 0, msg, copied);
  20836. + if (err < 0)
  20837. + goto out_free;
  20838. +
  20839. + if (msg->msg_name != NULL) {
  20840. + addr = (struct sockaddr_dect *)msg->msg_name;
  20841. + addr->dect_family = AF_DECT;
  20842. + addr->dect_index = DECT_SK_CB(skb)->index;
  20843. + msg->msg_namelen = sizeof(*addr);
  20844. + }
  20845. +
  20846. + sock_recv_timestamp(msg, sk, skb);
  20847. +
  20848. + aux.mfn = DECT_TRX_CB(skb)->mfn;
  20849. + aux.frame = DECT_TRX_CB(skb)->frame;
  20850. + aux.slot = DECT_TRX_CB(skb)->slot;
  20851. + aux.rssi = DECT_TRX_CB(skb)->rssi;
  20852. + put_cmsg(msg, SOL_DECT, DECT_RAW_AUXDATA, sizeof(aux), &aux);
  20853. +
  20854. + if (flags & MSG_TRUNC)
  20855. + copied = skb->len;
  20856. +out_free:
  20857. + skb_free_datagram(sk, skb);
  20858. +out:
  20859. + return err ? : copied;
  20860. +}
  20861. +
  20862. +static int dect_raw_sendmsg(struct sock *sk,
  20863. + struct msghdr *msg, size_t len)
  20864. +{
  20865. + struct sockaddr_dect *addr = msg->msg_name;
  20866. + struct dect_raw_auxdata *aux = NULL;
  20867. + struct dect_cell *cell;
  20868. + struct sk_buff *skb;
  20869. + struct cmsghdr *cmsg;
  20870. + size_t size;
  20871. + int index;
  20872. + int err;
  20873. +
  20874. + if (msg->msg_namelen) {
  20875. + if (addr->dect_family != AF_DECT)
  20876. + return -EINVAL;
  20877. + index = addr->dect_index;
  20878. + } else
  20879. + index = sk->sk_bound_dev_if;
  20880. +
  20881. + cell = dect_cell_get_by_index(index);
  20882. + if (cell == NULL)
  20883. + return -ENODEV;
  20884. +
  20885. + for (cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL; cmsg = CMSG_NXTHDR(msg, cmsg)) {
  20886. + if (!CMSG_OK(msg, cmsg))
  20887. + return -EINVAL;
  20888. + if (cmsg->cmsg_level != SOL_DECT)
  20889. + continue;
  20890. +
  20891. + switch (cmsg->cmsg_type) {
  20892. + case DECT_RAW_AUXDATA:
  20893. + if (cmsg->cmsg_len != CMSG_LEN(sizeof(*aux)))
  20894. + return -EINVAL;
  20895. + aux = (struct dect_raw_auxdata *)CMSG_DATA(cmsg);
  20896. + break;
  20897. + default:
  20898. + return -EINVAL;
  20899. + }
  20900. + }
  20901. +
  20902. + if (aux == NULL)
  20903. + return -EINVAL;
  20904. +
  20905. + size = DECT_PREAMBLE_SIZE + len;
  20906. + skb = sock_alloc_send_skb(sk, size, msg->msg_flags & MSG_DONTWAIT, &err);
  20907. + if (skb == NULL)
  20908. + goto err1;
  20909. +
  20910. + /* Reserve space for preamble */
  20911. + skb_reset_mac_header(skb);
  20912. + skb_reserve(skb, DECT_PREAMBLE_SIZE);
  20913. +
  20914. + err = memcpy_from_msg(skb_put(skb, len), msg, len);
  20915. + if (err < 0)
  20916. + goto err2;
  20917. +
  20918. + DECT_TRX_CB(skb)->mfn = aux->mfn;
  20919. + DECT_TRX_CB(skb)->frame = aux->frame;
  20920. + DECT_TRX_CB(skb)->slot = aux->slot;
  20921. +
  20922. + skb_queue_tail(&cell->raw_tx_queue, skb);
  20923. + return len;
  20924. +
  20925. +err2:
  20926. + kfree_skb(skb);
  20927. +err1:
  20928. + return err;
  20929. +}
  20930. +
  20931. +static struct dect_proto dect_raw_proto = {
  20932. + .type = SOCK_RAW,
  20933. + .protocol = DECT_RAW,
  20934. + .capability = CAP_NET_RAW,
  20935. + .ops = &dect_dgram_ops,
  20936. + .proto.name = "DECT_RAW",
  20937. + .proto.owner = THIS_MODULE,
  20938. + .proto.obj_size = sizeof(struct dect_raw_sk),
  20939. + .proto.close = dect_raw_close,
  20940. + .proto.bind = dect_raw_bind,
  20941. + .proto.unhash = dect_raw_unhash,
  20942. + .proto.recvmsg = dect_raw_recvmsg,
  20943. + .proto.sendmsg = dect_raw_sendmsg,
  20944. + .getname = dect_raw_getname,
  20945. +};
  20946. +
  20947. +static int __init dect_raw_init(void)
  20948. +{
  20949. + int err;
  20950. +
  20951. + BUILD_BUG_ON(sizeof(struct sockaddr_dect) >
  20952. + sizeof(struct sockaddr));
  20953. + err = dect_proto_register(&dect_raw_proto);
  20954. + if (err < 0)
  20955. + return err;
  20956. + rcu_assign_pointer(dect_raw_rcv_hook, __dect_raw_rcv);
  20957. + return 0;
  20958. +}
  20959. +
  20960. +static void __exit dect_raw_exit(void)
  20961. +{
  20962. + rcu_assign_pointer(dect_raw_rcv_hook, NULL);
  20963. + synchronize_rcu();
  20964. + dect_proto_unregister(&dect_raw_proto);
  20965. +}
  20966. +
  20967. +module_init(dect_raw_init);
  20968. +module_exit(dect_raw_exit);
  20969. +
  20970. +MODULE_AUTHOR("Patrick McHardy <[email protected]>");
  20971. +MODULE_DESCRIPTION("DECT RAW sockets");
  20972. +MODULE_LICENSE("GPL");
  20973. +
  20974. +MODULE_ALIAS_NET_PF_PROTO(PF_DECT, DECT_RAW);
  20975. diff --git a/net/dect/transceiver.c b/net/dect/transceiver.c
  20976. new file mode 100644
  20977. index 0000000..a4ac3e7
  20978. --- /dev/null
  20979. +++ b/net/dect/transceiver.c
  20980. @@ -0,0 +1,1063 @@
  20981. +/*
  20982. + * DECT transceiver and transceiver group functions
  20983. + *
  20984. + * Copyright (c) 2009 Patrick McHardy <[email protected]>
  20985. + *
  20986. + * This program is free software; you can redistribute it and/or modify
  20987. + * it under the terms of the GNU General Public License version 2 as
  20988. + * published by the Free Software Foundation.
  20989. + */
  20990. +
  20991. +//#define DEBUG
  20992. +#include <linux/kernel.h>
  20993. +#include <linux/module.h>
  20994. +#include <linux/init.h>
  20995. +#include <linux/mutex.h>
  20996. +#include <linux/list.h>
  20997. +#include <linux/notifier.h>
  20998. +#include <net/dect/dect.h>
  20999. +#include <net/dect/mac_csf.h>
  21000. +#include <net/dect/transceiver.h>
  21001. +
  21002. +static LIST_HEAD(dect_transceiver_list);
  21003. +static int dect_transceiver_notify(struct dect_transceiver *trx,
  21004. + unsigned long event);
  21005. +
  21006. +#define trx_debug(trx, fmt, args...) \
  21007. + pr_debug("%s: " fmt, trx->name, ## args)
  21008. +
  21009. +static const struct dect_band *dect_band[DECT_BAND_NUM];
  21010. +static const u8 dect_pkt_size[] = {
  21011. + [DECT_PACKET_P00] = DECT_P00_SIZE,
  21012. + [DECT_PACKET_P08] = DECT_P08_SIZE,
  21013. + [DECT_PACKET_P32] = DECT_P32_SIZE,
  21014. + [DECT_PACKET_P640j] = DECT_P640j_SIZE,
  21015. + [DECT_PACKET_P672j] = DECT_P672j_SIZE,
  21016. + [DECT_PACKET_P80] = DECT_P80_SIZE,
  21017. +};
  21018. +
  21019. +/**
  21020. + * dect_transceiver_alloc_skb - allocate a transceiver RX skb
  21021. + *
  21022. + * @trx: transceiver
  21023. + * @slot: slot number
  21024. + *
  21025. + * Allocate a skb according to the receiving channel characteristics.
  21026. + */
  21027. +struct sk_buff *dect_transceiver_alloc_skb(struct dect_transceiver *trx, u8 slot)
  21028. +{
  21029. + const struct dect_transceiver_slot *ts = &trx->slots[slot];
  21030. + unsigned int align;
  21031. + struct sk_buff *skb;
  21032. +
  21033. + align = __alignof__(u64) - DECT_PREAMBLE_SIZE;
  21034. +
  21035. + skb = alloc_skb(dect_pkt_size[ts->chd.pkt] + align, GFP_ATOMIC);
  21036. + if (skb == NULL)
  21037. + return NULL;
  21038. + DECT_TRX_CB(skb)->trx = trx;
  21039. + DECT_TRX_CB(skb)->slot = ts->chd.slot;
  21040. + /* Reserve room for preamble and set up adjacent packet data pointer */
  21041. + skb_reserve(skb, DECT_PREAMBLE_SIZE + align);
  21042. + skb_put(skb, dect_pkt_size[ts->chd.pkt] - DECT_PREAMBLE_SIZE);
  21043. + return skb;
  21044. +}
  21045. +EXPORT_SYMBOL_GPL(dect_transceiver_alloc_skb);
  21046. +
  21047. +/* Transceiver virtual clock maintenance:
  21048. + *
  21049. + * The transceiver layer processes the received frames from some slots in
  21050. + * the past while the transceiver is transceiving on the following slots.
  21051. + * Additionally the transceiver needs to be maintained for the upcoming
  21052. + * slots. Therefore there are three different reference frames of time:
  21053. + *
  21054. + * [ RX ][ TRX ][ TX ]
  21055. + * slot_0 -> slot_23
  21056. + *
  21057. + * - Real time, which is only known to the transceiver
  21058. + *
  21059. + * - RX time, which is a virtual clock following real time by at least one
  21060. + * slot and advancing as received slots are processed. A transceiver must
  21061. + * generate enough events so that the RX time never lags behind the TRX
  21062. + * time for more than one TDMA half frame.
  21063. + *
  21064. + * - TX time, which is a virtual clock leading RX time by a usually constant
  21065. + * amount of slots large enough so that packets queued to the transceiver
  21066. + * will reach the transceiver in time to be sent. It always leads real time,
  21067. + * but must never have a distance greater than one TDMA half frame from RX
  21068. + * time, resulting in a maximal distance of 11 to real time.
  21069. + *
  21070. + * Transceivers periodically notify the transceiver layer of an elapsed amount
  21071. + * of time and the frames that were received during that period. The events
  21072. + * batches generated by multiple transceivers contained in a group are merged
  21073. + * and processed as a single chronological event stream.
  21074. + *
  21075. + * The following steps are performed during processing (for every slot):
  21076. + *
  21077. + * - Received packets are passed to the MAC layer
  21078. + * - A RX tick is generated, ending the last RX slot
  21079. + * - A TX tick with some offset in the future is generated, beginning the
  21080. + * next TX slot
  21081. + *
  21082. + * The RX and TX ticks are used by the MAC layer to maintain two timer bases
  21083. + * for performing maintenance operations after a slot was received or before
  21084. + * a slot will be transmitted.
  21085. + */
  21086. +
  21087. +/**
  21088. + * dect_transceiver_queue_event - queue a transceiver event for BH processing
  21089. + *
  21090. + * @trx: DECT transceiver
  21091. + * @event: Transceiver event
  21092. + */
  21093. +void dect_transceiver_queue_event(struct dect_transceiver *trx,
  21094. + struct dect_transceiver_event *event)
  21095. +{
  21096. + struct dect_transceiver_group *grp = &trx->cell->trg;
  21097. +
  21098. + spin_lock(&grp->lock);
  21099. + list_add_tail(&event->list, &grp->events);
  21100. + spin_unlock(&grp->lock);
  21101. +
  21102. + tasklet_hi_schedule(&grp->tasklet);
  21103. +}
  21104. +EXPORT_SYMBOL_GPL(dect_transceiver_queue_event);
  21105. +
  21106. +static struct dect_transceiver_event *
  21107. +dect_dequeue_event(struct dect_transceiver_group *grp)
  21108. +{
  21109. + struct dect_transceiver_event *event;
  21110. + unsigned long flags;
  21111. +
  21112. + event = NULL;
  21113. + spin_lock_irqsave(&grp->lock, flags);
  21114. + if (!list_empty(&grp->events)) {
  21115. + event = list_first_entry(&grp->events,
  21116. + struct dect_transceiver_event,
  21117. + list);
  21118. + list_del(&event->list);
  21119. + }
  21120. + spin_unlock_irqrestore(&grp->lock, flags);
  21121. + return event;
  21122. +}
  21123. +
  21124. +static void dect_tg_merge_events(struct dect_transceiver_group *grp,
  21125. + struct dect_transceiver *trx,
  21126. + struct dect_transceiver_event *event)
  21127. +{
  21128. + struct sk_buff *skb;
  21129. + u8 slot, idx, i;
  21130. +
  21131. + /* Transfer the packets to the slot input queues and mark the
  21132. + * slot events.
  21133. + */
  21134. + trx_debug(trx, "merge %u events pos %u rssi_mask %x\n",
  21135. + trx->ops->eventrate, event->slotpos, event->rssi_mask);
  21136. +
  21137. + for (i = 0; i < trx->ops->eventrate; i++) {
  21138. + slot = event->slotpos + i;
  21139. + idx = slot % ARRAY_SIZE(grp->slots);
  21140. +
  21141. + skb = skb_peek(&event->rx_queue);
  21142. + if (skb != NULL && DECT_TRX_CB(skb)->slot == slot) {
  21143. + __skb_unlink(skb, &event->rx_queue);
  21144. + __skb_queue_tail(&grp->slots[idx].queue, skb);
  21145. + } else if (event->rssi_mask & (1 << i))
  21146. + grp->slots[idx].rssi[trx->index] = event->rssi[i];
  21147. +
  21148. + grp->slots[idx].mask |= 1 << trx->index;
  21149. + }
  21150. +}
  21151. +
  21152. +static bool seqno_before(u32 seq1, u32 seq2)
  21153. +{
  21154. + return (s32)(seq2 - seq1) > 0;
  21155. +}
  21156. +
  21157. +static bool seqno_after(u32 seq1, u32 seq2)
  21158. +{
  21159. + return seqno_before(seq2, seq1);
  21160. +}
  21161. +
  21162. +static void dect_tg_process_events(struct dect_transceiver_group *grp)
  21163. +{
  21164. + struct dect_transceiver *trx;
  21165. + struct dect_transceiver_slot *ts;
  21166. + struct sk_buff *skb;
  21167. + u8 idx, d, i;
  21168. + u16 late;
  21169. +
  21170. + pr_debug("process events slot_low=%u slot_high=%u distance=%u\n",
  21171. + grp->slot_low, grp->slot_high,
  21172. + dect_slot_distance(grp->slot_low, grp->slot_high));
  21173. +
  21174. + while (grp->slot_low != grp->slot_high) {
  21175. + /*
  21176. + * If more than one half frame is missing, only forward the
  21177. + * clock since the slot positions refer to slots in the
  21178. + * following half frame.
  21179. + */
  21180. + d = dect_slot_distance(grp->slot_low, grp->slot_high);
  21181. + if (d > ARRAY_SIZE(grp->slots))
  21182. + goto tick;
  21183. +
  21184. + idx = grp->slot_low % ARRAY_SIZE(grp->slots);
  21185. +
  21186. + /* Check for transceivers which are lagging by more than their
  21187. + * event rate window and mark the current window entirely as
  21188. + * lost.
  21189. + */
  21190. + late = grp->slots[idx].mask ^ grp->trxmask;
  21191. + while (late != 0) {
  21192. + trx = grp->trx[ffs(late) - 1];
  21193. + late &= ~(1 << trx->index);
  21194. +
  21195. + if (!seqno_before(trx->seqno + trx->ops->eventrate,
  21196. + grp->seqno) &&
  21197. + d <= trx->ops->eventrate)
  21198. + continue;
  21199. +
  21200. + trx_debug(trx, "late for window %u\n", grp->slot_low);
  21201. + for (i = 0; i < trx->ops->eventrate; i++)
  21202. + grp->slots[(idx + i) % 12].mask |= 1 << trx->index;
  21203. + trx->stats.event_late++;
  21204. + }
  21205. +
  21206. + if (grp->slots[idx].mask != grp->trxmask) {
  21207. + pr_debug("slot %u incomplete: mask %x trx %x\n",
  21208. + grp->slot_low, grp->slots[idx].mask, grp->trxmask);
  21209. + break;
  21210. + }
  21211. +
  21212. + while ((skb = __skb_dequeue(&grp->slots[idx].queue))) {
  21213. + trx = DECT_TRX_CB(skb)->trx;
  21214. + ts = &trx->slots[DECT_TRX_CB(skb)->slot];
  21215. + dect_mac_rcv(trx, ts, skb);
  21216. + }
  21217. +
  21218. + for (i = 0; i < ARRAY_SIZE(grp->slots[idx].rssi); i++) {
  21219. + if (grp->slots[idx].rssi[i] == 0)
  21220. + continue;
  21221. + trx = grp->trx[i];
  21222. + ts = &trx->slots[grp->slot_low];
  21223. + dect_mac_report_rssi(trx, ts, grp->slots[idx].rssi[i]);
  21224. + grp->slots[idx].rssi[i] = 0;
  21225. + }
  21226. +
  21227. + grp->slots[idx].mask = 0;
  21228. +tick:
  21229. + dect_mac_rx_tick(grp, dect_next_slotnum(grp->slot_low));
  21230. + dect_mac_tx_tick(grp, dect_slot_add(grp->slot_low,
  21231. + 2 * grp->latency));
  21232. +
  21233. + grp->slot_low = dect_next_slotnum(grp->slot_low);
  21234. + }
  21235. +}
  21236. +
  21237. +/*
  21238. + * Softirq transceiver group event processing
  21239. + */
  21240. +static void dect_transceiver_tasklet(unsigned long data)
  21241. +{
  21242. + struct dect_transceiver_group *grp = (struct dect_transceiver_group *)data;
  21243. + struct dect_transceiver *trx;
  21244. + struct dect_transceiver_event *event;
  21245. + struct sk_buff *skb;
  21246. +
  21247. +again:
  21248. + event = dect_dequeue_event(grp);
  21249. + if (event == NULL) {
  21250. + dect_tg_process_events(grp);
  21251. + return;
  21252. + }
  21253. +
  21254. + trx = event->trx;
  21255. +
  21256. + trx_debug(trx, "event handler: trx: seq %u pos %u grp: seq %u pos %u\n",
  21257. + trx->seqno, event->slotpos, grp->seqno, grp->slot_low);
  21258. +
  21259. + /* Before a transceiver is locked, its timing might vary and isn't
  21260. + * synchronized to the remaining group. The MAC layer handles this
  21261. + * manually.
  21262. + */
  21263. + if (trx->state != DECT_TRANSCEIVER_LOCKED) {
  21264. + skb = __skb_dequeue(&event->rx_queue);
  21265. + if (skb != NULL)
  21266. + dect_mac_irc_rcv(trx, skb);
  21267. + dect_mac_irc_tick(trx);
  21268. + goto out;
  21269. + }
  21270. +
  21271. + /* If a secondary transceiver enters locked state or a tranceiver missed
  21272. + * a previous window, its sequence number is out of sync. Resync it once
  21273. + * it starts reporting events in the current window.
  21274. + *
  21275. + * FIXME: driver should ignore frames with missed interrupts completely
  21276. + */
  21277. + if (seqno_before(trx->seqno + trx->ops->eventrate, grp->seqno)) {
  21278. + if (event->slotpos != grp->slot_low) {
  21279. + trx_debug(trx, "unsynchronized\n");
  21280. + __skb_queue_purge(&event->rx_queue);
  21281. + goto out;
  21282. + }
  21283. +
  21284. + trx->seqno = grp->seqno;
  21285. + if (grp->slot_high != grp->slot_low)
  21286. + trx->seqno -= trx->ops->eventrate;
  21287. +
  21288. + trx_debug(trx, "synchronized to seqno %u\n", trx->seqno);
  21289. + }
  21290. +
  21291. + /* Merge the events and update the sequence number. The transceiver
  21292. + * with the highest sequence number determines the slot position for
  21293. + * the entire group.
  21294. + */
  21295. + dect_tg_merge_events(grp, trx, event);
  21296. +
  21297. + trx->seqno += trx->ops->eventrate;
  21298. + if (seqno_after(trx->seqno, grp->seqno)) {
  21299. + grp->seqno = trx->seqno;
  21300. + grp->slot_high =
  21301. + dect_slot_add(event->slotpos, trx->ops->eventrate);
  21302. + }
  21303. +
  21304. +out:
  21305. + dect_release_transceiver_event(event);
  21306. + goto again;
  21307. +}
  21308. +
  21309. +static void dect_transceiver_group_compute_features(struct dect_transceiver_group *grp)
  21310. +{
  21311. + struct dect_transceiver *trx;
  21312. + u32 features;
  21313. +
  21314. + features = ~0;
  21315. + dect_foreach_transceiver(trx, grp)
  21316. + features &= trx->ops->features;
  21317. + grp->features = features;
  21318. +}
  21319. +
  21320. +int dect_transceiver_group_add(struct dect_transceiver_group *grp,
  21321. + struct dect_transceiver *trx)
  21322. +{
  21323. + u8 index;
  21324. +
  21325. + index = ffz(grp->trxmask);
  21326. + if (index >= ARRAY_SIZE(grp->trx))
  21327. + return -EMFILE;
  21328. +
  21329. + trx->index = index;
  21330. + grp->trx[index] = trx;
  21331. + if (trx->ops->latency > grp->latency)
  21332. + grp->latency = trx->ops->latency;
  21333. +
  21334. + grp->trxmask |= 1 << index;
  21335. +
  21336. + dect_transceiver_group_compute_features(grp);
  21337. + return 0;
  21338. +}
  21339. +
  21340. +void dect_transceiver_group_remove(struct dect_transceiver_group *grp,
  21341. + struct dect_transceiver *trx)
  21342. +{
  21343. + grp->trxmask &= ~(1 << trx->index);
  21344. + /* Synchronize with interrupt and softirq processing */
  21345. + synchronize_rcu();
  21346. + grp->trx[trx->index] = NULL;
  21347. +
  21348. + dect_transceiver_group_compute_features(grp);
  21349. +}
  21350. +
  21351. +void dect_transceiver_group_init(struct dect_transceiver_group *grp)
  21352. +{
  21353. + unsigned int i;
  21354. +
  21355. + spin_lock_init(&grp->lock);
  21356. + INIT_LIST_HEAD(&grp->events);
  21357. + for (i = 0; i < ARRAY_SIZE(grp->slots); i++)
  21358. + __skb_queue_head_init(&grp->slots[i].queue);
  21359. +
  21360. + tasklet_init(&grp->tasklet, dect_transceiver_tasklet,
  21361. + (unsigned long)grp);
  21362. +}
  21363. +
  21364. +void dect_transceiver_disable(struct dect_transceiver *trx)
  21365. +{
  21366. + trx->ops->disable(trx);
  21367. + trx->state = DECT_TRANSCEIVER_STOPPED;
  21368. +}
  21369. +
  21370. +void dect_transceiver_enable(struct dect_transceiver *trx)
  21371. +{
  21372. + if (trx->mode == DECT_TRANSCEIVER_MASTER)
  21373. + trx->state = DECT_TRANSCEIVER_LOCKED;
  21374. + else
  21375. + trx->state = DECT_TRANSCEIVER_UNLOCKED;
  21376. +
  21377. + trx->ops->enable(trx);
  21378. +}
  21379. +
  21380. +void dect_transceiver_confirm(struct dect_transceiver *trx)
  21381. +{
  21382. + trx_debug(trx, "confirm\n");
  21383. + trx->state = DECT_TRANSCEIVER_LOCK_PENDING;
  21384. + trx->slots[DECT_SCAN_SLOT].state = DECT_SLOT_RX;
  21385. + trx->ops->confirm(trx);
  21386. +}
  21387. +
  21388. +void dect_transceiver_unlock(struct dect_transceiver *trx)
  21389. +{
  21390. + trx_debug(trx, "unlock\n");
  21391. + trx->ops->unlock(trx);
  21392. + trx->slots[DECT_SCAN_SLOT].state = DECT_SLOT_SCANNING;
  21393. + trx->state = DECT_TRANSCEIVER_UNLOCKED;
  21394. +}
  21395. +
  21396. +int dect_transceiver_set_band(struct dect_transceiver *trx, u8 bandnum)
  21397. +{
  21398. + const struct dect_band *band;
  21399. +
  21400. + band = dect_band[bandnum];
  21401. + if (band == NULL)
  21402. + return -ENOENT;
  21403. + trx->carriers = trx->ops->set_band(trx, band);
  21404. + trx->band = band;
  21405. + return 0;
  21406. +}
  21407. +
  21408. +void dect_transceiver_lock(struct dect_transceiver *trx, u8 slot)
  21409. +{
  21410. + trx_debug(trx, "lock to slot %u\n", slot);
  21411. + trx->slots[DECT_SCAN_SLOT].state = DECT_SLOT_IDLE;
  21412. + trx->state = DECT_TRANSCEIVER_LOCKED;
  21413. + trx->ops->lock(trx, slot);
  21414. +}
  21415. +
  21416. +static void dect_transceiver_set_blind(struct dect_transceiver *trx, u8 slot)
  21417. +{
  21418. + u8 n = DECT_FRAME_SIZE - 1 - slot;
  21419. +
  21420. + trx->slots[slot].blinded++;
  21421. + trx->blind_full_slots |= 1 << n;
  21422. +}
  21423. +
  21424. +static void dect_transceiver_set_visible(struct dect_transceiver *trx, u8 slot)
  21425. +{
  21426. + u8 n = DECT_FRAME_SIZE - 1 - slot;
  21427. +
  21428. + if (--trx->slots[slot].blinded == 0)
  21429. + trx->blind_full_slots &= ~(1 << n);
  21430. +}
  21431. +
  21432. +static bool dect_transceiver_slot_blind(const struct dect_transceiver *trx, u8 slot)
  21433. +{
  21434. + u8 n = DECT_FRAME_SIZE - 1 - slot;
  21435. +
  21436. + return trx->blind_full_slots & (1 << n);
  21437. +}
  21438. +
  21439. +bool dect_transceiver_channel_available(const struct dect_transceiver *trx,
  21440. + const struct dect_channel_desc *chd)
  21441. +{
  21442. + u8 slot = chd->slot, prev, next;
  21443. +
  21444. + if (trx->slots[slot].state == DECT_SLOT_RX ||
  21445. + trx->slots[slot].state == DECT_SLOT_TX)
  21446. + return false;
  21447. +
  21448. + switch ((int)chd->pkt) {
  21449. + case DECT_PACKET_P80:
  21450. + case DECT_PACKET_P640j:
  21451. + case DECT_PACKET_P672j:
  21452. + if (dect_transceiver_slot_blind(trx, slot + 1))
  21453. + return false;
  21454. + case DECT_PACKET_P32:
  21455. + case DECT_PACKET_P08:
  21456. + case DECT_PACKET_P00:
  21457. + if (dect_transceiver_slot_blind(trx, slot))
  21458. + return false;
  21459. + break;
  21460. + }
  21461. +
  21462. + /* In case of slow hopping transceivers the adjacent slots must be
  21463. + * available as well. Scanning slots are not blind, so they must be
  21464. + * checked for explicitly.
  21465. + */
  21466. + if (trx->ops->features & DECT_TRANSCEIVER_SLOW_HOPPING) {
  21467. + prev = dect_prev_slotnum(slot);
  21468. + if (trx->slots[prev].state == DECT_SLOT_SCANNING)
  21469. + return false;
  21470. + next = dect_next_slotnum(slot);
  21471. + if (trx->slots[next].state == DECT_SLOT_SCANNING)
  21472. + return false;
  21473. + }
  21474. +
  21475. + return true;
  21476. +}
  21477. +
  21478. +static bool dect_tg_update_blind_full_slots(struct dect_transceiver_group *trg)
  21479. +{
  21480. + const struct dect_transceiver *trx;
  21481. + u32 blind_full_slots;
  21482. +
  21483. + blind_full_slots = (~0U) & DECT_SLOT_MASK;
  21484. + dect_foreach_transceiver(trx, trg)
  21485. + blind_full_slots &= trx->blind_full_slots;
  21486. +
  21487. + if (trg->blind_full_slots != blind_full_slots) {
  21488. + trg->blind_full_slots = blind_full_slots;
  21489. + return true;
  21490. + } else
  21491. + return false;
  21492. +}
  21493. +
  21494. +/**
  21495. + * dect_transceiver_reserve - reserve transceiver resources for a physical channel
  21496. + *
  21497. + * Reserve the slot positions necessary to estabish the specified physical
  21498. + * channel. The chosen transceivers and the global groups blind full slot
  21499. + * masks are updated.
  21500. + *
  21501. + * Returns true when the global visibility state has changed.
  21502. + */
  21503. +bool dect_transceiver_reserve(struct dect_transceiver_group *trg,
  21504. + struct dect_transceiver *trx,
  21505. + const struct dect_channel_desc *chd)
  21506. +{
  21507. + u8 slot = chd->slot;
  21508. +
  21509. + switch ((int)chd->pkt) {
  21510. + case DECT_PACKET_P80:
  21511. + case DECT_PACKET_P640j:
  21512. + case DECT_PACKET_P672j:
  21513. + dect_transceiver_set_blind(trx, slot + 1);
  21514. + case DECT_PACKET_P32:
  21515. + case DECT_PACKET_P08:
  21516. + case DECT_PACKET_P00:
  21517. + dect_transceiver_set_blind(trx, slot);
  21518. + break;
  21519. + }
  21520. +
  21521. + /* Set adjacent slots blind if the transceiver is slow hopping */
  21522. + if (trx->ops->features & DECT_TRANSCEIVER_SLOW_HOPPING) {
  21523. + dect_transceiver_set_blind(trx, dect_prev_slotnum(slot));
  21524. + dect_transceiver_set_blind(trx, dect_next_slotnum(slot));
  21525. + }
  21526. +
  21527. + return dect_tg_update_blind_full_slots(trg);
  21528. +}
  21529. +
  21530. +/**
  21531. + * dect_transceiver_release - release transceiver resources of a phyiscal channel
  21532. + *
  21533. + * Release the slot positions used by the specified physical channel. The
  21534. + * transceiver and the global group blind full slot masks are updated.
  21535. + *
  21536. + * Returns true when the global visibility state has changed.
  21537. + */
  21538. +bool dect_transceiver_release(struct dect_transceiver_group *trg,
  21539. + struct dect_transceiver *trx,
  21540. + const struct dect_channel_desc *chd)
  21541. +{
  21542. + u8 slot = chd->slot;
  21543. +
  21544. + switch ((int)chd->pkt) {
  21545. + case DECT_PACKET_P80:
  21546. + case DECT_PACKET_P640j:
  21547. + case DECT_PACKET_P672j:
  21548. + dect_transceiver_set_visible(trx, slot + 1);
  21549. + case DECT_PACKET_P32:
  21550. + case DECT_PACKET_P08:
  21551. + case DECT_PACKET_P00:
  21552. + dect_transceiver_set_visible(trx, slot);
  21553. + break;
  21554. + }
  21555. +
  21556. + /* Set adjacent slots unblind if the transceiver is slow hopping */
  21557. + if (trx->ops->features & DECT_TRANSCEIVER_SLOW_HOPPING) {
  21558. + dect_transceiver_set_visible(trx, dect_next_slotnum(slot));
  21559. + dect_transceiver_set_visible(trx, dect_prev_slotnum(slot));
  21560. + }
  21561. +
  21562. + return dect_tg_update_blind_full_slots(trg);
  21563. +}
  21564. +
  21565. +struct dect_transceiver *dect_transceiver_alloc(const struct dect_transceiver_ops *ops,
  21566. + unsigned int priv)
  21567. +{
  21568. + struct dect_transceiver *trx;
  21569. + unsigned int nevents, size, i;
  21570. +
  21571. + /* Allocate enough event structures for one TDMA half frame */
  21572. + nevents = DECT_HALF_FRAME_SIZE / ops->eventrate;
  21573. + size = nevents * sizeof(trx->event[0]) + priv;
  21574. +
  21575. + trx = kzalloc(sizeof(*trx) + size, GFP_KERNEL);
  21576. + if (trx == NULL)
  21577. + return NULL;
  21578. +
  21579. + trx->state = DECT_TRANSCEIVER_STOPPED;
  21580. + trx->ops = ops;
  21581. + for (i = 0; i < DECT_FRAME_SIZE; i++)
  21582. + trx->slots[i].chd.slot = i;
  21583. +
  21584. + for (i = 0; i < nevents; i++) {
  21585. + skb_queue_head_init(&trx->event[i].rx_queue);
  21586. + trx->event[i].trx = trx;
  21587. + }
  21588. + return trx;
  21589. +}
  21590. +EXPORT_SYMBOL_GPL(dect_transceiver_alloc);
  21591. +
  21592. +void dect_transceiver_free(struct dect_transceiver *trx)
  21593. +{
  21594. + kfree(trx);
  21595. +}
  21596. +EXPORT_SYMBOL_GPL(dect_transceiver_free);
  21597. +
  21598. +static int dect_transceiver_alloc_name(struct dect_transceiver *trx)
  21599. +{
  21600. + struct dect_transceiver *t;
  21601. + unsigned long *inuse;
  21602. + int i;
  21603. +
  21604. + inuse = (unsigned long *)get_zeroed_page(GFP_KERNEL);
  21605. + if (inuse == NULL)
  21606. + return -ENOMEM;
  21607. +
  21608. + list_for_each_entry(t, &dect_transceiver_list, list) {
  21609. + if (!sscanf(t->name, "trx%d", &i))
  21610. + continue;
  21611. + if (i > BITS_PER_BYTE * PAGE_SIZE)
  21612. + continue;
  21613. + set_bit(i, inuse);
  21614. + }
  21615. +
  21616. + i = find_first_zero_bit(inuse, BITS_PER_BYTE * PAGE_SIZE);
  21617. + free_page((unsigned long)inuse);
  21618. + if (i == BITS_PER_BYTE * PAGE_SIZE)
  21619. + return -ENFILE;
  21620. +
  21621. + snprintf(trx->name, sizeof(trx->name), "trx%d", i);
  21622. + return 0;
  21623. +}
  21624. +
  21625. +int dect_register_transceiver(struct dect_transceiver *trx)
  21626. +{
  21627. + int err;
  21628. +
  21629. + dect_lock();
  21630. + err = dect_transceiver_alloc_name(trx);
  21631. + if (err < 0)
  21632. + goto out;
  21633. +
  21634. + err = dect_transceiver_set_band(trx, DECT_DEFAULT_BAND);
  21635. + if (err < 0)
  21636. + goto out;
  21637. +
  21638. + list_add_tail(&trx->list, &dect_transceiver_list);
  21639. + dect_transceiver_notify(trx, DECT_TRANSCEIVER_REGISTER);
  21640. +out:
  21641. + dect_unlock();
  21642. +
  21643. + return err;
  21644. +}
  21645. +EXPORT_SYMBOL_GPL(dect_register_transceiver);
  21646. +
  21647. +void dect_unregister_transceiver(struct dect_transceiver *trx)
  21648. +{
  21649. + dect_lock();
  21650. + list_del(&trx->list);
  21651. + dect_transceiver_notify(trx, DECT_TRANSCEIVER_UNREGISTER);
  21652. + dect_unlock();
  21653. +
  21654. + synchronize_rcu();
  21655. + trx->ops->destructor(trx);
  21656. +}
  21657. +EXPORT_SYMBOL_GPL(dect_unregister_transceiver);
  21658. +
  21659. +/*
  21660. + * Transceiver netlink interface
  21661. + */
  21662. +
  21663. +static struct dect_transceiver *dect_transceiver_get_by_name(const struct nlattr *nla)
  21664. +{
  21665. + struct dect_transceiver *trx;
  21666. +
  21667. + list_for_each_entry(trx, &dect_transceiver_list, list) {
  21668. + if (!nla_strcmp(nla, trx->name))
  21669. + return trx;
  21670. + }
  21671. + return NULL;
  21672. +}
  21673. +
  21674. +static int dect_fill_slot(struct sk_buff *skb,
  21675. + const struct dect_transceiver *trx, u8 slot)
  21676. +{
  21677. + const struct dect_transceiver_slot *ts = &trx->slots[slot];
  21678. +
  21679. + if (nla_put_u8(skb, DECTA_SLOT_NUM, slot) ||
  21680. + nla_put_u8(skb, DECTA_SLOT_STATE, ts->state) ||
  21681. + nla_put_u32(skb, DECTA_SLOT_FLAGS, ts->flags))
  21682. + goto nla_put_failure;
  21683. +
  21684. + if (ts->state != DECT_SLOT_IDLE) {
  21685. + if (nla_put_u8(skb, DECTA_SLOT_PACKET, ts->chd.pkt) ||
  21686. + nla_put_u8(skb, DECTA_SLOT_CARRIER, ts->chd.carrier) ||
  21687. + nla_put_u32(skb, DECTA_SLOT_FREQUENCY,
  21688. + trx->band->frequency[ts->chd.carrier]))
  21689. + goto nla_put_failure;
  21690. + }
  21691. + if (ts->state == DECT_SLOT_RX) {
  21692. + nla_put_u32(skb, DECTA_SLOT_PHASEOFF, ts->phaseoff);
  21693. + nla_put_u8(skb, DECTA_SLOT_RSSI,
  21694. + ts->rssi >> DECT_RSSI_AVG_SCALE);
  21695. + }
  21696. + if (nla_put_u32(skb, DECTA_SLOT_RX_BYTES, ts->rx_bytes) ||
  21697. + nla_put_u32(skb, DECTA_SLOT_RX_PACKETS, ts->rx_packets) ||
  21698. + nla_put_u32(skb, DECTA_SLOT_RX_A_CRC_ERRORS, ts->rx_a_crc_errors) ||
  21699. + nla_put_u32(skb, DECTA_SLOT_RX_X_CRC_ERRORS, ts->rx_x_crc_errors) ||
  21700. + nla_put_u32(skb, DECTA_SLOT_RX_Z_CRC_ERRORS, ts->rx_z_crc_errors) ||
  21701. + nla_put_u32(skb, DECTA_SLOT_TX_BYTES, ts->tx_bytes) ||
  21702. + nla_put_u32(skb, DECTA_SLOT_TX_PACKETS, ts->tx_packets))
  21703. + goto nla_put_failure;
  21704. +
  21705. + return 0;
  21706. +
  21707. +nla_put_failure:
  21708. + return -1;
  21709. +}
  21710. +
  21711. +static int dect_fill_transceiver(struct sk_buff *skb,
  21712. + const struct dect_transceiver *trx,
  21713. + u16 type, u32 portid, u32 seq, u16 flags)
  21714. +{
  21715. + const struct dect_transceiver_stats *stats = &trx->stats;
  21716. + struct nlattr *nest, *chan;
  21717. + struct nlmsghdr *nlh;
  21718. + struct dectmsg *dm;
  21719. + u8 slot;
  21720. +
  21721. + nlh = nlmsg_put(skb, portid, seq, type, sizeof(*dm), flags);
  21722. + if (nlh == NULL)
  21723. + return -EMSGSIZE;
  21724. +
  21725. + dm = nlmsg_data(nlh);
  21726. +
  21727. + if (nla_put_string(skb, DECTA_TRANSCEIVER_NAME, trx->name) ||
  21728. + nla_put_string(skb, DECTA_TRANSCEIVER_TYPE, trx->ops->name) ||
  21729. + nla_put_u32(skb, DECTA_TRANSCEIVER_FEATURES, trx->ops->features))
  21730. + goto nla_put_failure;
  21731. + if (trx->cell != NULL &&
  21732. + nla_put_u8(skb, DECTA_TRANSCEIVER_LINK, trx->cell->index))
  21733. + goto nla_put_failure;
  21734. +
  21735. + nest = nla_nest_start(skb, DECTA_TRANSCEIVER_STATS);
  21736. + if (nest == NULL)
  21737. + goto nla_put_failure;
  21738. + if (nla_put_u32(skb, DECTA_TRANSCEIVER_STATS_EVENT_BUSY,
  21739. + stats->event_busy) ||
  21740. + nla_put_u32(skb, DECTA_TRANSCEIVER_STATS_EVENT_LATE,
  21741. + stats->event_late))
  21742. + goto nla_put_failure;
  21743. + nla_nest_end(skb, nest);
  21744. +
  21745. + if (nla_put_u8(skb, DECTA_TRANSCEIVER_BAND, trx->band->band))
  21746. + goto nla_put_failure;
  21747. +
  21748. + nest = nla_nest_start(skb, DECTA_TRANSCEIVER_SLOTS);
  21749. + if (nest == NULL)
  21750. + goto nla_put_failure;
  21751. + for (slot = 0; slot < DECT_FRAME_SIZE; slot++) {
  21752. + chan = nla_nest_start(skb, DECTA_LIST_ELEM);
  21753. + if (chan == NULL)
  21754. + goto nla_put_failure;
  21755. + if (dect_fill_slot(skb, trx, slot) < 0)
  21756. + goto nla_put_failure;
  21757. + nla_nest_end(skb, chan);
  21758. + }
  21759. + nla_nest_end(skb, nest);
  21760. +
  21761. + nlmsg_end(skb, nlh);
  21762. + return skb->len;
  21763. +
  21764. +nla_put_failure:
  21765. + nlmsg_cancel(skb, nlh);
  21766. + return -EMSGSIZE;
  21767. +}
  21768. +
  21769. +static const struct nla_policy dect_transceiver_policy[DECTA_TRANSCEIVER_MAX + 1] = {
  21770. + [DECTA_TRANSCEIVER_NAME] = { .type = NLA_STRING, .len = DECTNAMSIZ },
  21771. + [DECTA_TRANSCEIVER_LINK] = { .type = NLA_U8 },
  21772. +};
  21773. +
  21774. +static int dect_new_transceiver(const struct sk_buff *in_skb,
  21775. + const struct nlmsghdr *nlh,
  21776. + const struct nlattr *tb[DECTA_TRANSCEIVER_MAX + 1])
  21777. +{
  21778. + struct dect_transceiver *trx;
  21779. + struct dect_cell *cell;
  21780. + struct dectmsg *dm;
  21781. + int index;
  21782. +
  21783. + dm = nlmsg_data(nlh);
  21784. +
  21785. + if (tb[DECTA_TRANSCEIVER_NAME] == NULL)
  21786. + return -EINVAL;
  21787. +
  21788. + trx = dect_transceiver_get_by_name(tb[DECTA_TRANSCEIVER_NAME]);
  21789. + if (trx == NULL) {
  21790. + if (nlh->nlmsg_flags & NLM_F_CREATE)
  21791. + return -EOPNOTSUPP;
  21792. + return -ENOENT;
  21793. + }
  21794. + if (nlh->nlmsg_flags & NLM_F_EXCL)
  21795. + return -EEXIST;
  21796. +
  21797. + if (tb[DECTA_TRANSCEIVER_LINK] != NULL) {
  21798. + index = nla_get_u8(tb[DECTA_TRANSCEIVER_LINK]);
  21799. + if (index == -1)
  21800. + dect_cell_detach_transceiver(trx->cell, trx);
  21801. + else {
  21802. + cell = dect_cell_get_by_index(index);
  21803. + if (cell == NULL)
  21804. + return -ENOENT;
  21805. + return dect_cell_attach_transceiver(cell, trx);
  21806. + }
  21807. + }
  21808. + return 0;
  21809. +}
  21810. +
  21811. +static int dect_get_transceiver(const struct sk_buff *in_skb,
  21812. + const struct nlmsghdr *nlh,
  21813. + const struct nlattr *tb[DECTA_TRANSCEIVER_MAX + 1])
  21814. +{
  21815. + u32 portid = NETLINK_CB(in_skb).portid;
  21816. + const struct dect_transceiver *trx;
  21817. + struct sk_buff *skb;
  21818. + int err;
  21819. +
  21820. + if (tb[DECTA_TRANSCEIVER_NAME] == NULL)
  21821. + return -EINVAL;
  21822. +
  21823. + trx = dect_transceiver_get_by_name(tb[DECTA_TRANSCEIVER_NAME]);
  21824. + if (trx == NULL)
  21825. + return -ENOENT;
  21826. +
  21827. + skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
  21828. + if (skb == NULL)
  21829. + return -ENOMEM;
  21830. + err = dect_fill_transceiver(skb, trx, DECT_NEW_TRANSCEIVER, portid,
  21831. + nlh->nlmsg_seq, NLMSG_DONE);
  21832. + if (err < 0)
  21833. + goto err1;
  21834. + return nlmsg_unicast(dect_nlsk, skb, portid);
  21835. +
  21836. +err1:
  21837. + kfree_skb(skb);
  21838. + return err;
  21839. +}
  21840. +
  21841. +static int dect_dump_transceiver(struct sk_buff *skb,
  21842. + struct netlink_callback *cb)
  21843. +{
  21844. + const struct dect_transceiver *trx;
  21845. + unsigned int idx, s_idx;
  21846. +
  21847. + s_idx = cb->args[0];
  21848. + idx = 0;
  21849. + list_for_each_entry(trx, &dect_transceiver_list, list) {
  21850. + if (idx < s_idx)
  21851. + goto cont;
  21852. + if (dect_fill_transceiver(skb, trx, DECT_NEW_TRANSCEIVER,
  21853. + NETLINK_CB(cb->skb).portid,
  21854. + cb->nlh->nlmsg_seq, NLM_F_MULTI) <= 0)
  21855. + break;
  21856. +cont:
  21857. + idx++;
  21858. + }
  21859. + cb->args[0] = idx;
  21860. +
  21861. + return skb->len;
  21862. +}
  21863. +
  21864. +static void dect_notify_transceiver(u16 event, const struct dect_transceiver *trx,
  21865. + const struct nlmsghdr *nlh, u32 portid)
  21866. +{
  21867. + struct sk_buff *skb;
  21868. + bool report = nlh ? nlmsg_report(nlh) : 0;
  21869. + u32 seq = nlh ? nlh->nlmsg_seq : 0;
  21870. + int err = -ENOBUFS;
  21871. +
  21872. + skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
  21873. + if (skb == NULL)
  21874. + goto err;
  21875. +
  21876. + err = dect_fill_transceiver(skb, trx, event, portid, seq, NLMSG_DONE);
  21877. + if (err < 0) {
  21878. + WARN_ON(err == -EMSGSIZE);
  21879. + kfree_skb(skb);
  21880. + goto err;
  21881. + }
  21882. + nlmsg_notify(dect_nlsk, skb, portid, DECTNLGRP_TRANSCEIVER, report,
  21883. + GFP_KERNEL);
  21884. +err:
  21885. + if (err < 0)
  21886. + netlink_set_err(dect_nlsk, portid, DECTNLGRP_TRANSCEIVER, err);
  21887. +}
  21888. +
  21889. +static int dect_transceiver_notify(struct dect_transceiver *trx,
  21890. + unsigned long event)
  21891. +{
  21892. + struct dect_cell *cell = trx->cell;
  21893. +
  21894. + switch (event) {
  21895. + case DECT_TRANSCEIVER_REGISTER:
  21896. + dect_notify_transceiver(DECT_NEW_TRANSCEIVER, trx, NULL, 0);
  21897. + break;
  21898. + case DECT_TRANSCEIVER_UNREGISTER:
  21899. + if (cell != NULL)
  21900. + dect_cell_detach_transceiver(cell, trx);
  21901. + dect_notify_transceiver(DECT_DEL_TRANSCEIVER, trx, NULL, 0);
  21902. + break;
  21903. + }
  21904. + return 0;
  21905. +};
  21906. +
  21907. +
  21908. +static const struct dect_netlink_handler dect_transceiver_handlers[] = {
  21909. + {
  21910. + /* DECT_NEW_TRANSCEIVER */
  21911. + .policy = dect_transceiver_policy,
  21912. + .maxtype = DECTA_TRANSCEIVER_MAX,
  21913. + .doit = dect_new_transceiver,
  21914. + },
  21915. + {
  21916. + /* DECT_DEL_TRANSCEIVER */
  21917. + },
  21918. + {
  21919. + /* DECT_GET_TRANSCEIVER */
  21920. + .policy = dect_transceiver_policy,
  21921. + .maxtype = DECTA_TRANSCEIVER_MAX,
  21922. + .doit = dect_get_transceiver,
  21923. + .dump = dect_dump_transceiver,
  21924. + },
  21925. +};
  21926. +
  21927. +/*
  21928. + * RF-bands:
  21929. + */
  21930. +
  21931. +struct dect_band_desc {
  21932. + u8 band;
  21933. + u8 carriers;
  21934. + s16 c1_off;
  21935. + u8 c2;
  21936. + s16 c2_off;
  21937. +};
  21938. +
  21939. +static const struct dect_band_desc dect_band_desc[] __initdata = {
  21940. + /* 1880 MHz to 1900 MHz RF band 00000 */
  21941. + { 0, 10, 0, -1, 0, },
  21942. + /* 1880 MHz to 1978 MHz and 2010 MHz to 2025 MHz RF band 00001 */
  21943. + { 1, 64, 0, 56, 19, },
  21944. + /* 1880 MHz to 1925 MHz and 2010 MHz to 2025 MHz RF band 00010 */
  21945. + { 2, 33, 0, 25, 50, },
  21946. + /* 1880 MHz to 1900 MHz, 1915 MHz to 1940 MHz and 2010 MHz to
  21947. + * 2025 MHz RF band 00011 */
  21948. + { 3, 33, 10, 25, 50, },
  21949. + /* 1880 MHz to 1900 MHz, 1935 MHz to 1960 MHz and 2010 MHz to
  21950. + * 2025 MHz RF band 00100 */
  21951. + { 4, 33, 22, 25, 50, },
  21952. + /* 1880 MHz to 1900 MHZ, 1955 MHz to 1980 MHz and 2010 MHz to
  21953. + * 2025 MHz RF band 00101 */
  21954. + { 5, 33, 34, 25, 50, },
  21955. + /* 902 MHz to 928 MHz RF band 01000 */
  21956. + { 8, 24, -576, -1, 0, },
  21957. + /* 2400 MHz to 2483,5 MHz RF band 01001 */
  21958. + { 9, 55, 292, -1, 0, },
  21959. +};
  21960. +
  21961. +/*
  21962. + * A nominal DECT RF carrier is one whose center frequency is generated by
  21963. + * the formula:
  21964. + *
  21965. + * Fg = F0 - g \D7 1,728 MHz, where g is any integer
  21966. + */
  21967. +static u32 __init dect_calc_frequency(s16 g)
  21968. +{
  21969. + if (g >= 0 && g < 10)
  21970. + return DECT_FREQUENCY_F0 - g * DECT_CARRIER_WIDTH;
  21971. + else
  21972. + return DECT_FREQUENCY_F0 + (g - 9) * DECT_CARRIER_WIDTH;
  21973. +}
  21974. +
  21975. +static int __init dect_init_band(const struct dect_band_desc *desc)
  21976. +{
  21977. + struct dect_band *band;
  21978. + unsigned int size;
  21979. + u8 carrier;
  21980. +
  21981. + size = sizeof(*band) + desc->carriers * sizeof(band->frequency[0]);
  21982. + band = kmalloc(size, GFP_KERNEL);
  21983. + if (band == NULL)
  21984. + return -ENOMEM;
  21985. +
  21986. + band->band = desc->band;
  21987. + band->carriers = desc->carriers;
  21988. +
  21989. + for (carrier = 0; carrier < 10; carrier++)
  21990. + band->frequency[carrier] =
  21991. + dect_calc_frequency(carrier);
  21992. +
  21993. + for (; carrier < min(desc->carriers, desc->c2); carrier++)
  21994. + band->frequency[carrier] =
  21995. + dect_calc_frequency(carrier + desc->c1_off);
  21996. +
  21997. + for (; carrier < desc->carriers; carrier++)
  21998. + band->frequency[carrier] =
  21999. + dect_calc_frequency(carrier + desc->c2_off);
  22000. +
  22001. + printk("RF-band %u:\n", band->band);
  22002. + for (carrier = 0; carrier < band->carriers; carrier++) {
  22003. + printk(" carrier %u: %u.%03uMHz\n", carrier,
  22004. + band->frequency[carrier] / 1000,
  22005. + band->frequency[carrier] % 1000);
  22006. + }
  22007. + printk("\n");
  22008. +
  22009. + dect_band[band->band] = band;
  22010. + return 0;
  22011. +}
  22012. +
  22013. +int __init dect_transceiver_module_init(void)
  22014. +{
  22015. + unsigned int i;
  22016. + int err;
  22017. +
  22018. + for (i = 0; i < ARRAY_SIZE(dect_band_desc); i++) {
  22019. + err = dect_init_band(&dect_band_desc[i]);
  22020. + if (err < 0)
  22021. + goto err1;
  22022. + }
  22023. +
  22024. + dect_netlink_register_handlers(dect_transceiver_handlers,
  22025. + DECT_NEW_TRANSCEIVER,
  22026. + ARRAY_SIZE(dect_transceiver_handlers));
  22027. + return 0;
  22028. +
  22029. +err1:
  22030. + dect_transceiver_module_exit();
  22031. + return err;
  22032. +}
  22033. +
  22034. +void dect_transceiver_module_exit(void)
  22035. +{
  22036. + u8 band;
  22037. +
  22038. + dect_netlink_unregister_handlers(DECT_NEW_TRANSCEIVER,
  22039. + ARRAY_SIZE(dect_transceiver_handlers));
  22040. +
  22041. + for (band = 0; band < ARRAY_SIZE(dect_band); band++)
  22042. + kfree(dect_band[band]);
  22043. +}