blob: 072f4d9cc81e41c98b36e1f4df373f1cc2892d67 [file] [log] [blame]
Neels Hofmeyr17518fe2017-06-20 04:35:06 +02001/*! \file sercomm.h
2 * Osmocom Sercomm HDLC (de)multiplex.
3 */
4
Harald Weltec68af6a2017-04-30 21:21:52 +02005#ifndef _SERCOMM_H
6#define _SERCOMM_H
7
8#include <osmocom/core/msgb.h>
9
Harald Welte77117132017-05-15 17:33:02 +020010/*! \defgroup sercomm Seriall Communications (HDLC)
11 * @{
Neels Hofmeyr17518fe2017-06-20 04:35:06 +020012 * \file sercomm.h */
Harald Welte77117132017-05-15 17:33:02 +020013
Neels Hofmeyr87e45502017-06-20 00:17:59 +020014/*! A low sercomm_dlci means high priority. A high DLCI means low priority */
Harald Weltec68af6a2017-04-30 21:21:52 +020015enum sercomm_dlci {
16 SC_DLCI_HIGHEST = 0,
17 SC_DLCI_DEBUG = 4,
18 SC_DLCI_L1A_L23 = 5,
19 SC_DLCI_LOADER = 9,
20 SC_DLCI_CONSOLE = 10,
21 SC_DLCI_ECHO = 128,
22 _SC_DLCI_MAX
23};
24
Harald Welte13588362017-04-30 23:57:55 +020025struct osmo_sercomm_inst;
Neels Hofmeyr87e45502017-06-20 00:17:59 +020026/*! call-back function for per-DLC receive handler
Harald Welteea3d3ba2017-05-02 21:24:48 +020027 * \param[in] sercomm instance on which msg was received
28 * \param[in] dlci DLC Identifier of received msg
29 * \param[in] msg received message that needs to be processed */
Harald Welte13588362017-04-30 23:57:55 +020030typedef void (*dlci_cb_t)(struct osmo_sercomm_inst *sercomm, uint8_t dlci, struct msgb *msg);
Harald Weltecc95f4b2017-04-30 21:39:33 +020031
Neels Hofmeyr87e45502017-06-20 00:17:59 +020032/*! one instance of a sercomm multiplex/demultiplex */
Harald Welte13588362017-04-30 23:57:55 +020033struct osmo_sercomm_inst {
Neels Hofmeyr87e45502017-06-20 00:17:59 +020034 /*! Has this instance been initialized? */
Harald Weltecc95f4b2017-04-30 21:39:33 +020035 int initialized;
Neels Hofmeyr87e45502017-06-20 00:17:59 +020036 /*! UART Identifier */
Harald Weltecc95f4b2017-04-30 21:39:33 +020037 int uart_id;
38
Neels Hofmeyr87e45502017-06-20 00:17:59 +020039 /*! transmit side */
Harald Weltecc95f4b2017-04-30 21:39:33 +020040 struct {
Neels Hofmeyr87e45502017-06-20 00:17:59 +020041 /*! per-DLC queue of pending transmit msgbs */
Harald Weltecc95f4b2017-04-30 21:39:33 +020042 struct llist_head dlci_queues[_SC_DLCI_MAX];
Neels Hofmeyr87e45502017-06-20 00:17:59 +020043 /*! msgb currently being transmitted */
Harald Weltecc95f4b2017-04-30 21:39:33 +020044 struct msgb *msg;
Neels Hofmeyr87e45502017-06-20 00:17:59 +020045 /*! transmit state */
Harald Weltecc95f4b2017-04-30 21:39:33 +020046 int state;
Neels Hofmeyr87e45502017-06-20 00:17:59 +020047 /*! next to-be-transmitted char in msg */
Harald Weltecc95f4b2017-04-30 21:39:33 +020048 uint8_t *next_char;
49 } tx;
50
Neels Hofmeyr87e45502017-06-20 00:17:59 +020051 /*! receive side */
Harald Weltecc95f4b2017-04-30 21:39:33 +020052 struct {
Neels Hofmeyr87e45502017-06-20 00:17:59 +020053 /*! per-DLC handler call-back functions */
Harald Weltecc95f4b2017-04-30 21:39:33 +020054 dlci_cb_t dlci_handler[_SC_DLCI_MAX];
Neels Hofmeyr87e45502017-06-20 00:17:59 +020055 /*! msgb allocation size for rx msgs */
Harald Weltef6adcd72017-05-01 00:19:13 +020056 unsigned int msg_size;
Neels Hofmeyr87e45502017-06-20 00:17:59 +020057 /*! currently received msgb */
Harald Weltecc95f4b2017-04-30 21:39:33 +020058 struct msgb *msg;
Neels Hofmeyr87e45502017-06-20 00:17:59 +020059 /*! receive state */
Harald Weltecc95f4b2017-04-30 21:39:33 +020060 int state;
Neels Hofmeyr87e45502017-06-20 00:17:59 +020061 /*! DLCI of currently received msgb */
Harald Weltecc95f4b2017-04-30 21:39:33 +020062 uint8_t dlci;
Neels Hofmeyr87e45502017-06-20 00:17:59 +020063 /*! CTRL of currently received msgb */
Harald Weltecc95f4b2017-04-30 21:39:33 +020064 uint8_t ctrl;
65 } rx;
66};
67
68
Harald Welte13588362017-04-30 23:57:55 +020069void osmo_sercomm_init(struct osmo_sercomm_inst *sercomm);
70int osmo_sercomm_initialized(struct osmo_sercomm_inst *sercomm);
Harald Weltec68af6a2017-04-30 21:21:52 +020071
72/* User Interface: Tx */
Harald Welte13588362017-04-30 23:57:55 +020073void osmo_sercomm_sendmsg(struct osmo_sercomm_inst *sercomm, uint8_t dlci, struct msgb *msg);
Harald Welte13588362017-04-30 23:57:55 +020074unsigned int osmo_sercomm_tx_queue_depth(struct osmo_sercomm_inst *sercomm, uint8_t dlci);
Harald Weltec68af6a2017-04-30 21:21:52 +020075
76/* User Interface: Rx */
Harald Welte13588362017-04-30 23:57:55 +020077int osmo_sercomm_register_rx_cb(struct osmo_sercomm_inst *sercomm, uint8_t dlci, dlci_cb_t cb);
Harald Weltec68af6a2017-04-30 21:21:52 +020078
Harald Welte799bef52017-05-15 17:16:48 +020079int osmo_sercomm_change_speed(struct osmo_sercomm_inst *sercomm, uint32_t bdrt);
80
Harald Weltec68af6a2017-04-30 21:21:52 +020081/* Driver Interface */
82
Harald Welte13588362017-04-30 23:57:55 +020083int osmo_sercomm_drv_pull(struct osmo_sercomm_inst *sercomm, uint8_t *ch);
Harald Welte13588362017-04-30 23:57:55 +020084int osmo_sercomm_drv_rx_char(struct osmo_sercomm_inst *sercomm, uint8_t ch);
Harald Weltec68af6a2017-04-30 21:21:52 +020085
Harald Welte799bef52017-05-15 17:16:48 +020086extern void sercomm_drv_lock(unsigned long *flags);
87extern void sercomm_drv_unlock(unsigned long *flags);
Harald Welte77117132017-05-15 17:33:02 +020088
Neels Hofmeyr87e45502017-06-20 00:17:59 +020089/*! low-level driver routine to request start of transmission
Harald Welte77117132017-05-15 17:33:02 +020090 * The Sercomm code calls this function to inform the low-level driver
91 * that some data is pending for transmission, and the low-level driver
92 * should (if not active already) start enabling tx_empty interrupts
93 * and pull drivers out of sercomm using osmo_sercomm_drv_pull() until
94 * the latter returns 0.
95 * \param[in] sercomm Osmocom sercomm instance for which to change
96 */
Harald Welte799bef52017-05-15 17:16:48 +020097extern void sercomm_drv_start_tx(struct osmo_sercomm_inst *sercomm);
Harald Welte77117132017-05-15 17:33:02 +020098
Neels Hofmeyr87e45502017-06-20 00:17:59 +020099/*! low-level driver routine to execute baud-rate change
Harald Welte77117132017-05-15 17:33:02 +0200100 * \param[in] sercomm Osmocom sercomm instance for which to change
101 * \param[in] bdrt New Baud-Rate (integer)
102 * \returns 0 on success; negative in case of error
103 */
Harald Welte799bef52017-05-15 17:16:48 +0200104extern int sercomm_drv_baudrate_chg(struct osmo_sercomm_inst *sercomm, uint32_t bdrt);
105
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200106/*! Sercomm msgb allocator function */
Harald Welte13588362017-04-30 23:57:55 +0200107static inline struct msgb *osmo_sercomm_alloc_msgb(unsigned int len)
Harald Weltec68af6a2017-04-30 21:21:52 +0200108{
109 return msgb_alloc_headroom(len+4, 4, "sercomm_tx");
110}
111
Harald Welte77117132017-05-15 17:33:02 +0200112/*! @} */
113
Harald Weltec68af6a2017-04-30 21:21:52 +0200114#endif /* _SERCOMM_H */