blob: 38e6271c4bea0f36b6daf531bbeb82311edd0841 [file] [log] [blame]
Neels Hofmeyr17518fe2017-06-20 04:35:06 +02001/*! \file sercomm.h
2 * Osmocom Sercomm HDLC (de)multiplex.
3 */
4
Vadim Yanitskiy395db202022-09-28 23:51:42 +07005#pragma once
Harald Weltec68af6a2017-04-30 21:21:52 +02006
7#include <osmocom/core/msgb.h>
8
Harald Welte77117132017-05-15 17:33:02 +02009/*! \defgroup sercomm Seriall Communications (HDLC)
10 * @{
Neels Hofmeyr17518fe2017-06-20 04:35:06 +020011 * \file sercomm.h */
Harald Welte77117132017-05-15 17:33:02 +020012
Neels Hofmeyr87e45502017-06-20 00:17:59 +020013/*! A low sercomm_dlci means high priority. A high DLCI means low priority */
Harald Weltec68af6a2017-04-30 21:21:52 +020014enum sercomm_dlci {
15 SC_DLCI_HIGHEST = 0,
16 SC_DLCI_DEBUG = 4,
17 SC_DLCI_L1A_L23 = 5,
18 SC_DLCI_LOADER = 9,
19 SC_DLCI_CONSOLE = 10,
20 SC_DLCI_ECHO = 128,
21 _SC_DLCI_MAX
22};
23
Harald Welte13588362017-04-30 23:57:55 +020024struct osmo_sercomm_inst;
Neels Hofmeyr87e45502017-06-20 00:17:59 +020025/*! call-back function for per-DLC receive handler
Harald Welteea3d3ba2017-05-02 21:24:48 +020026 * \param[in] sercomm instance on which msg was received
27 * \param[in] dlci DLC Identifier of received msg
28 * \param[in] msg received message that needs to be processed */
Harald Welte13588362017-04-30 23:57:55 +020029typedef void (*dlci_cb_t)(struct osmo_sercomm_inst *sercomm, uint8_t dlci, struct msgb *msg);
Harald Weltecc95f4b2017-04-30 21:39:33 +020030
Neels Hofmeyr87e45502017-06-20 00:17:59 +020031/*! one instance of a sercomm multiplex/demultiplex */
Harald Welte13588362017-04-30 23:57:55 +020032struct osmo_sercomm_inst {
Neels Hofmeyr87e45502017-06-20 00:17:59 +020033 /*! Has this instance been initialized? */
Harald Weltecc95f4b2017-04-30 21:39:33 +020034 int initialized;
Neels Hofmeyr87e45502017-06-20 00:17:59 +020035 /*! UART Identifier */
Harald Weltecc95f4b2017-04-30 21:39:33 +020036 int uart_id;
37
Neels Hofmeyr87e45502017-06-20 00:17:59 +020038 /*! transmit side */
Harald Weltecc95f4b2017-04-30 21:39:33 +020039 struct {
Neels Hofmeyr87e45502017-06-20 00:17:59 +020040 /*! per-DLC queue of pending transmit msgbs */
Harald Weltecc95f4b2017-04-30 21:39:33 +020041 struct llist_head dlci_queues[_SC_DLCI_MAX];
Neels Hofmeyr87e45502017-06-20 00:17:59 +020042 /*! msgb currently being transmitted */
Harald Weltecc95f4b2017-04-30 21:39:33 +020043 struct msgb *msg;
Neels Hofmeyr87e45502017-06-20 00:17:59 +020044 /*! transmit state */
Harald Weltecc95f4b2017-04-30 21:39:33 +020045 int state;
Neels Hofmeyr87e45502017-06-20 00:17:59 +020046 /*! next to-be-transmitted char in msg */
Harald Weltecc95f4b2017-04-30 21:39:33 +020047 uint8_t *next_char;
48 } tx;
49
Neels Hofmeyr87e45502017-06-20 00:17:59 +020050 /*! receive side */
Harald Weltecc95f4b2017-04-30 21:39:33 +020051 struct {
Neels Hofmeyr87e45502017-06-20 00:17:59 +020052 /*! per-DLC handler call-back functions */
Harald Weltecc95f4b2017-04-30 21:39:33 +020053 dlci_cb_t dlci_handler[_SC_DLCI_MAX];
Neels Hofmeyr87e45502017-06-20 00:17:59 +020054 /*! msgb allocation size for rx msgs */
Harald Weltef6adcd72017-05-01 00:19:13 +020055 unsigned int msg_size;
Neels Hofmeyr87e45502017-06-20 00:17:59 +020056 /*! currently received msgb */
Harald Weltecc95f4b2017-04-30 21:39:33 +020057 struct msgb *msg;
Neels Hofmeyr87e45502017-06-20 00:17:59 +020058 /*! receive state */
Harald Weltecc95f4b2017-04-30 21:39:33 +020059 int state;
Neels Hofmeyr87e45502017-06-20 00:17:59 +020060 /*! DLCI of currently received msgb */
Harald Weltecc95f4b2017-04-30 21:39:33 +020061 uint8_t dlci;
Neels Hofmeyr87e45502017-06-20 00:17:59 +020062 /*! CTRL of currently received msgb */
Harald Weltecc95f4b2017-04-30 21:39:33 +020063 uint8_t ctrl;
64 } rx;
65};
66
67
Harald Welte13588362017-04-30 23:57:55 +020068void osmo_sercomm_init(struct osmo_sercomm_inst *sercomm);
69int osmo_sercomm_initialized(struct osmo_sercomm_inst *sercomm);
Harald Weltec68af6a2017-04-30 21:21:52 +020070
71/* User Interface: Tx */
Harald Welte13588362017-04-30 23:57:55 +020072void osmo_sercomm_sendmsg(struct osmo_sercomm_inst *sercomm, uint8_t dlci, struct msgb *msg);
Harald Welte13588362017-04-30 23:57:55 +020073unsigned int osmo_sercomm_tx_queue_depth(struct osmo_sercomm_inst *sercomm, uint8_t dlci);
Harald Weltec68af6a2017-04-30 21:21:52 +020074
75/* User Interface: Rx */
Harald Welte13588362017-04-30 23:57:55 +020076int osmo_sercomm_register_rx_cb(struct osmo_sercomm_inst *sercomm, uint8_t dlci, dlci_cb_t cb);
Harald Weltec68af6a2017-04-30 21:21:52 +020077
Harald Welte799bef52017-05-15 17:16:48 +020078int osmo_sercomm_change_speed(struct osmo_sercomm_inst *sercomm, uint32_t bdrt);
79
Harald Weltec68af6a2017-04-30 21:21:52 +020080/* Driver Interface */
81
Harald Welte13588362017-04-30 23:57:55 +020082int osmo_sercomm_drv_pull(struct osmo_sercomm_inst *sercomm, uint8_t *ch);
Harald Welte13588362017-04-30 23:57:55 +020083int osmo_sercomm_drv_rx_char(struct osmo_sercomm_inst *sercomm, uint8_t ch);
Harald Weltec68af6a2017-04-30 21:21:52 +020084
Harald Welte799bef52017-05-15 17:16:48 +020085extern void sercomm_drv_lock(unsigned long *flags);
86extern void sercomm_drv_unlock(unsigned long *flags);
Harald Welte77117132017-05-15 17:33:02 +020087
Neels Hofmeyr87e45502017-06-20 00:17:59 +020088/*! low-level driver routine to request start of transmission
Harald Welte77117132017-05-15 17:33:02 +020089 * The Sercomm code calls this function to inform the low-level driver
90 * that some data is pending for transmission, and the low-level driver
91 * should (if not active already) start enabling tx_empty interrupts
92 * and pull drivers out of sercomm using osmo_sercomm_drv_pull() until
93 * the latter returns 0.
94 * \param[in] sercomm Osmocom sercomm instance for which to change
95 */
Harald Welte799bef52017-05-15 17:16:48 +020096extern void sercomm_drv_start_tx(struct osmo_sercomm_inst *sercomm);
Harald Welte77117132017-05-15 17:33:02 +020097
Neels Hofmeyr87e45502017-06-20 00:17:59 +020098/*! low-level driver routine to execute baud-rate change
Harald Welte77117132017-05-15 17:33:02 +020099 * \param[in] sercomm Osmocom sercomm instance for which to change
100 * \param[in] bdrt New Baud-Rate (integer)
101 * \returns 0 on success; negative in case of error
102 */
Harald Welte799bef52017-05-15 17:16:48 +0200103extern int sercomm_drv_baudrate_chg(struct osmo_sercomm_inst *sercomm, uint32_t bdrt);
104
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200105/*! Sercomm msgb allocator function */
Harald Welte13588362017-04-30 23:57:55 +0200106static inline struct msgb *osmo_sercomm_alloc_msgb(unsigned int len)
Harald Weltec68af6a2017-04-30 21:21:52 +0200107{
108 return msgb_alloc_headroom(len+4, 4, "sercomm_tx");
109}
110
Harald Welte77117132017-05-15 17:33:02 +0200111/*! @} */