// SPDX-License-Identifier: GPL-2.0-only /* * Shared Transport Line discipline driver Core * This hooks up ST KIM driver and ST LL driver * Copyright (C) 2009-2010 Texas Instruments * Author: Pavan Savoy <[email protected]> */ #define pr_fmt(fmt) … #include <linux/module.h> #include <linux/kernel.h> #include <linux/tty.h> #include <linux/seq_file.h> #include <linux/skbuff.h> #include <linux/ti_wilink_st.h> #include <linux/netdevice.h> /* * function pointer pointing to either, * st_kim_recv during registration to receive fw download responses * st_int_recv after registration to receive proto stack responses */ static void (*st_recv)(void *disc_data, const u8 *ptr, size_t count); /********************************************************************/ static void add_channel_to_table(struct st_data_s *st_gdata, struct st_proto_s *new_proto) { … } static void remove_channel_from_table(struct st_data_s *st_gdata, struct st_proto_s *proto) { … } /* * called from KIM during firmware download. * * This is a wrapper function to tty->ops->write_room. * It returns number of free space available in * uart tx buffer. */ int st_get_uart_wr_room(struct st_data_s *st_gdata) { … } /* * can be called in from * -- KIM (during fw download) * -- ST Core (during st_write) * * This is the internal write function - a wrapper * to tty->ops->write */ int st_int_write(struct st_data_s *st_gdata, const unsigned char *data, int count) { … } /* * push the skb received to relevant * protocol stacks */ static void st_send_frame(unsigned char chnl_id, struct st_data_s *st_gdata) { … } /* * st_reg_complete - to call registration complete callbacks * of all protocol stack drivers * This function is being called with spin lock held, protocol drivers are * only expected to complete their waits and do nothing more than that. */ static void st_reg_complete(struct st_data_s *st_gdata, int err) { … } static inline int st_check_data_len(struct st_data_s *st_gdata, unsigned char chnl_id, int len) { … } /* * st_wakeup_ack - internal function for action when wake-up ack * received */ static inline void st_wakeup_ack(struct st_data_s *st_gdata, unsigned char cmd) { … } /* * st_int_recv - ST's internal receive function. * Decodes received RAW data and forwards to corresponding * client drivers (Bluetooth,FM,GPS..etc). * This can receive various types of packets, * HCI-Events, ACL, SCO, 4 types of HCI-LL PM packets * CH-8 packets from FM, CH-9 packets from GPS cores. */ static void st_int_recv(void *disc_data, const u8 *ptr, size_t count) { … } /* * st_int_dequeue - internal de-Q function. * If the previous data set was not written * completely, return that skb which has the pending data. * In normal cases, return top of txq. */ static struct sk_buff *st_int_dequeue(struct st_data_s *st_gdata) { … } /* * st_int_enqueue - internal Q-ing function. * Will either Q the skb to txq or the tx_waitq * depending on the ST LL state. * If the chip is asleep, then Q it onto waitq and * wakeup the chip. * txq and waitq needs protection since the other contexts * may be sending data, waking up chip. */ static void st_int_enqueue(struct st_data_s *st_gdata, struct sk_buff *skb) { … } /* * internal wakeup function * called from either * - TTY layer when write's finished * - st_write (in context of the protocol stack) */ static void work_fn_write_wakeup(struct work_struct *work) { … } void st_tx_wakeup(struct st_data_s *st_data) { … } /********************************************************************/ /* functions called from ST KIM */ void kim_st_list_protocols(struct st_data_s *st_gdata, void *buf) { … } /********************************************************************/ /* * functions called from protocol stack drivers * to be EXPORT-ed */ long st_register(struct st_proto_s *new_proto) { … } EXPORT_SYMBOL_GPL(…); /* * to unregister a protocol - * to be called from protocol stack driver */ long st_unregister(struct st_proto_s *proto) { … } /* * called in protocol stack drivers * via the write function pointer */ long st_write(struct sk_buff *skb) { … } /* for protocols making use of shared transport */ EXPORT_SYMBOL_GPL(…); /********************************************************************/ /* * functions called from TTY layer */ static int st_tty_open(struct tty_struct *tty) { … } static void st_tty_close(struct tty_struct *tty) { … } static void st_tty_receive(struct tty_struct *tty, const u8 *data, const u8 *tty_flags, size_t count) { … } /* * wake-up function called in from the TTY layer * inside the internal wakeup function will be called */ static void st_tty_wakeup(struct tty_struct *tty) { … } static void st_tty_flush_buffer(struct tty_struct *tty) { … } static struct tty_ldisc_ops st_ldisc_ops = …; /********************************************************************/ int st_core_init(struct st_data_s **core_data) { … } void st_core_exit(struct st_data_s *st_gdata) { … }