linux/drivers/staging/fwserial/fwserial.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2#ifndef _FIREWIRE_FWSERIAL_H
   3#define _FIREWIRE_FWSERIAL_H
   4
   5#include <linux/kernel.h>
   6#include <linux/tty.h>
   7#include <linux/tty_driver.h>
   8#include <linux/tty_flip.h>
   9#include <linux/list.h>
  10#include <linux/firewire.h>
  11#include <linux/firewire-constants.h>
  12#include <linux/spinlock.h>
  13#include <linux/rcupdate.h>
  14#include <linux/mutex.h>
  15#include <linux/serial.h>
  16#include <linux/serial_reg.h>
  17#include <linux/module.h>
  18#include <linux/seq_file.h>
  19#include <linux/debugfs.h>
  20
  21#include "dma_fifo.h"
  22
  23#ifdef FWTTY_PROFILING
  24#define DISTRIBUTION_MAX_SIZE     8192
  25#define DISTRIBUTION_MAX_INDEX    (ilog2(DISTRIBUTION_MAX_SIZE) + 1)
  26static inline void fwtty_profile_data(unsigned int stat[], unsigned int val)
  27{
  28        int n = (val) ? min(ilog2(val) + 1, DISTRIBUTION_MAX_INDEX) : 0;
  29        ++stat[n];
  30}
  31#else
  32#define DISTRIBUTION_MAX_INDEX    0
  33#define fwtty_profile_data(st, n)
  34#endif
  35
  36/* Parameters for both VIRT_CABLE_PLUG & VIRT_CABLE_PLUG_RSP mgmt codes */
  37struct virt_plug_params {
  38        __be32  status_hi;
  39        __be32  status_lo;
  40        __be32  fifo_hi;
  41        __be32  fifo_lo;
  42        __be32  fifo_len;
  43};
  44
  45struct peer_work_params {
  46        union {
  47                struct virt_plug_params plug_req;
  48        };
  49};
  50
  51/**
  52 * fwtty_peer: structure representing local & remote unit devices
  53 * @unit: unit child device of fw_device node
  54 * @serial: back pointer to associated fw_serial aggregate
  55 * @guid: unique 64-bit guid for this unit device
  56 * @generation: most recent bus generation
  57 * @node_id: most recent node_id
  58 * @speed: link speed of peer (0 = S100, 2 = S400, ... 5 = S3200)
  59 * @mgmt_addr: bus addr region to write mgmt packets to
  60 * @status_addr: bus addr register to write line status to
  61 * @fifo_addr: bus addr region to write serial output to
  62 * @fifo_len:  max length for single write to fifo_addr
  63 * @list: link for insertion into fw_serial's peer_list
  64 * @rcu: for deferring peer reclamation
  65 * @lock: spinlock to synchonize changes to state & port fields
  66 * @work: only one work item can be queued at any one time
  67 *        Note: pending work is canceled prior to removal, so this
  68 *        peer is valid for at least the lifetime of the work function
  69 * @work_params: parameter block for work functions
  70 * @timer: timer for resetting peer state if remote request times out
  71 * @state: current state
  72 * @connect: work item for auto-connecting
  73 * @connect_retries: # of connections already attempted
  74 * @port: associated tty_port (usable if state == FWSC_ATTACHED)
  75 */
  76struct fwtty_peer {
  77        struct fw_unit          *unit;
  78        struct fw_serial        *serial;
  79        u64                     guid;
  80        int                     generation;
  81        int                     node_id;
  82        unsigned int            speed;
  83        int                     max_payload;
  84        u64                     mgmt_addr;
  85
  86        /* these are usable only if state == FWSC_ATTACHED */
  87        u64                     status_addr;
  88        u64                     fifo_addr;
  89        int                     fifo_len;
  90
  91        struct list_head        list;
  92        struct rcu_head         rcu;
  93
  94        spinlock_t              lock;
  95        work_func_t             workfn;
  96        struct work_struct      work;
  97        struct peer_work_params work_params;
  98        struct timer_list       timer;
  99        int                     state;
 100        struct delayed_work     connect;
 101        int                     connect_retries;
 102
 103        struct fwtty_port       *port;
 104};
 105
 106#define to_peer(ptr, field)     (container_of(ptr, struct fwtty_peer, field))
 107
 108/* state values for fwtty_peer.state field */
 109enum fwtty_peer_state {
 110        FWPS_GONE,
 111        FWPS_NOT_ATTACHED,
 112        FWPS_ATTACHED,
 113        FWPS_PLUG_PENDING,
 114        FWPS_PLUG_RESPONDING,
 115        FWPS_UNPLUG_PENDING,
 116        FWPS_UNPLUG_RESPONDING,
 117
 118        FWPS_NO_MGMT_ADDR = -1,
 119};
 120
 121#define CONNECT_RETRY_DELAY     HZ
 122#define MAX_CONNECT_RETRIES     10
 123
 124/* must be holding peer lock for these state funclets */
 125static inline void peer_set_state(struct fwtty_peer *peer, int new)
 126{
 127        peer->state = new;
 128}
 129
 130static inline struct fwtty_port *peer_revert_state(struct fwtty_peer *peer)
 131{
 132        struct fwtty_port *port = peer->port;
 133
 134        peer->port = NULL;
 135        peer_set_state(peer, FWPS_NOT_ATTACHED);
 136        return port;
 137}
 138
 139struct fwserial_mgmt_pkt {
 140        struct {
 141                __be16          len;
 142                __be16          code;
 143        } hdr;
 144        union {
 145                struct virt_plug_params plug_req;
 146                struct virt_plug_params plug_rsp;
 147        };
 148} __packed;
 149
 150/* fwserial_mgmt_packet codes */
 151#define FWSC_RSP_OK                     0x0000
 152#define FWSC_RSP_NACK                   0x8000
 153#define FWSC_CODE_MASK                  0x0fff
 154
 155#define FWSC_VIRT_CABLE_PLUG            1
 156#define FWSC_VIRT_CABLE_UNPLUG          2
 157#define FWSC_VIRT_CABLE_PLUG_RSP        3
 158#define FWSC_VIRT_CABLE_UNPLUG_RSP      4
 159
 160/* 1 min. plug timeout -- suitable for userland authorization */
 161#define VIRT_CABLE_PLUG_TIMEOUT         (60 * HZ)
 162
 163struct stats {
 164        unsigned int    xchars;
 165        unsigned int    dropped;
 166        unsigned int    tx_stall;
 167        unsigned int    fifo_errs;
 168        unsigned int    sent;
 169        unsigned int    lost;
 170        unsigned int    throttled;
 171        unsigned int    reads[DISTRIBUTION_MAX_INDEX + 1];
 172        unsigned int    writes[DISTRIBUTION_MAX_INDEX + 1];
 173        unsigned int    txns[DISTRIBUTION_MAX_INDEX + 1];
 174        unsigned int    unthrottle[DISTRIBUTION_MAX_INDEX + 1];
 175};
 176
 177struct fwconsole_ops {
 178        void (*notify)(int code, void *data);
 179        void (*stats)(struct stats *stats, void *data);
 180        void (*proc_show)(struct seq_file *m, void *data);
 181};
 182
 183/* codes for console ops notify */
 184#define FWCON_NOTIFY_ATTACH             1
 185#define FWCON_NOTIFY_DETACH             2
 186
 187/**
 188 * fwtty_port: structure used to track/represent underlying tty_port
 189 * @port: underlying tty_port
 190 * @device: tty device
 191 * @index: index into port_table for this particular port
 192 *    note: minor = index + minor_start assigned by tty_alloc_driver()
 193 * @serial: back pointer to the containing fw_serial
 194 * @rx_handler: bus address handler for unique addr region used by remotes
 195 *              to communicate with this port. Every port uses
 196 *              fwtty_port_handler() for per port transactions.
 197 * @fwcon_ops: ops for attached fw_console (if any)
 198 * @con_data: private data for fw_console
 199 * @wait_tx: waitqueue for sleeping until writer/drain completes tx
 200 * @emit_breaks: delayed work responsible for generating breaks when the
 201 *               break line status is active
 202 * @cps : characters per second computed from the termios settings
 203 * @break_last: timestamp in jiffies from last emit_breaks
 204 * @hangup: work responsible for HUPing when carrier is dropped/lost
 205 * @mstatus: loose virtualization of LSR/MSR
 206 *         bits 15..0  correspond to TIOCM_* bits
 207 *         bits 19..16 reserved for mctrl
 208 *         bit 20      OOB_TX_THROTTLE
 209 *         bits 23..21 reserved
 210 *         bits 31..24 correspond to UART_LSR_* bits
 211 * @lock: spinlock for protecting concurrent access to fields below it
 212 * @mctrl: loose virtualization of MCR
 213 *         bits 15..0  correspond to TIOCM_* bits
 214 *         bit 16      OOB_RX_THROTTLE
 215 *         bits 19..17 reserved
 216 *         bits 31..20 reserved for mstatus
 217 * @drain: delayed work scheduled to ensure that writes are flushed.
 218 *         The work can race with the writer but concurrent sending is
 219 *         prevented with the IN_TX flag. Scheduled under lock to
 220 *         limit scheduling when fifo has just been drained.
 221 * @tx_fifo: fifo used to store & block-up writes for dma to remote
 222 * @max_payload: max bytes transmissible per dma (based on peer's max_payload)
 223 * @status_mask: UART_LSR_* bitmask significant to rx (based on termios)
 224 * @ignore_mask: UART_LSR_* bitmask of states to ignore (also based on termios)
 225 * @break_ctl: if set, port is 'sending break' to remote
 226 * @write_only: self-explanatory
 227 * @overrun: previous rx was lost (partially or completely)
 228 * @loopback: if set, port is in loopback mode
 229 * @flags: atomic bit flags
 230 *         bit 0: IN_TX - gate to allow only one cpu to send from the dma fifo
 231 *                        at a time.
 232 *         bit 1: STOP_TX - force tx to exit while sending
 233 * @peer: rcu-pointer to associated fwtty_peer (if attached)
 234 *        NULL if no peer attached
 235 * @icount: predefined statistics reported by the TIOCGICOUNT ioctl
 236 * @stats: additional statistics reported in /proc/tty/driver/firewire_serial
 237 */
 238struct fwtty_port {
 239        struct tty_port            port;
 240        struct device              *device;
 241        unsigned int               index;
 242        struct fw_serial           *serial;
 243        struct fw_address_handler  rx_handler;
 244
 245        struct fwconsole_ops       *fwcon_ops;
 246        void                       *con_data;
 247
 248        wait_queue_head_t          wait_tx;
 249        struct delayed_work        emit_breaks;
 250        unsigned int               cps;
 251        unsigned long              break_last;
 252
 253        struct work_struct         hangup;
 254
 255        unsigned int               mstatus;
 256
 257        spinlock_t                 lock;
 258        unsigned int               mctrl;
 259        struct delayed_work        drain;
 260        struct dma_fifo            tx_fifo;
 261        int                        max_payload;
 262        unsigned int               status_mask;
 263        unsigned int               ignore_mask;
 264        unsigned int               break_ctl:1,
 265                                   write_only:1,
 266                                   overrun:1,
 267                                   loopback:1;
 268        unsigned long              flags;
 269
 270        struct fwtty_peer __rcu    *peer;
 271
 272        struct async_icount        icount;
 273        struct stats               stats;
 274};
 275
 276#define to_port(ptr, field)     (container_of(ptr, struct fwtty_port, field))
 277
 278/* bit #s for flags field */
 279#define IN_TX                      0
 280#define STOP_TX                    1
 281
 282/* bitmasks for special mctrl/mstatus bits */
 283#define OOB_RX_THROTTLE   0x00010000
 284#define MCTRL_RSRVD       0x000e0000
 285#define OOB_TX_THROTTLE   0x00100000
 286#define MSTATUS_RSRVD     0x00e00000
 287
 288#define MCTRL_MASK        (TIOCM_DTR | TIOCM_RTS | TIOCM_OUT1 | TIOCM_OUT2 | \
 289                           TIOCM_LOOP | OOB_RX_THROTTLE | MCTRL_RSRVD)
 290
 291/* XXX even every 1/50th secs. may be unnecessarily accurate */
 292/* delay in jiffies between brk emits */
 293#define FREQ_BREAKS        (HZ / 50)
 294
 295/* Ports are allocated in blocks of num_ports for each fw_card */
 296#define MAX_CARD_PORTS           CONFIG_FWTTY_MAX_CARD_PORTS
 297#define MAX_TOTAL_PORTS          CONFIG_FWTTY_MAX_TOTAL_PORTS
 298
 299/* tuning parameters */
 300#define FWTTY_PORT_TXFIFO_LEN   4096
 301#define FWTTY_PORT_MAX_PEND_DMA    8    /* costs a cache line per pend */
 302#define DRAIN_THRESHOLD         1024
 303#define MAX_ASYNC_PAYLOAD       4096    /* ohci-defined limit          */
 304#define WRITER_MINIMUM           128
 305/* TODO: how to set watermark to AR context size? see fwtty_rx() */
 306#define HIGH_WATERMARK         32768    /* AR context is 32K           */
 307
 308/*
 309 * Size of bus addr region above 4GB used per port as the recv addr
 310 * - must be at least as big as the MAX_ASYNC_PAYLOAD
 311 */
 312#define FWTTY_PORT_RXFIFO_LEN   MAX_ASYNC_PAYLOAD
 313
 314/**
 315 * fw_serial: aggregate used to associate tty ports with specific fw_card
 316 * @card: fw_card associated with this fw_serial device (1:1 association)
 317 * @kref: reference-counted multi-port management allows delayed destroy
 318 * @self: local unit device as 'peer'. Not valid until local unit device
 319 *         is enumerated.
 320 * @list: link for insertion into fwserial_list
 321 * @peer_list: list of local & remote unit devices attached to this card
 322 * @ports: fixed array of tty_ports provided by this serial device
 323 */
 324struct fw_serial {
 325        struct fw_card    *card;
 326        struct kref       kref;
 327
 328        struct dentry     *debugfs;
 329        struct fwtty_peer *self;
 330
 331        struct list_head  list;
 332        struct list_head  peer_list;
 333
 334        struct fwtty_port *ports[MAX_CARD_PORTS];
 335};
 336
 337#define to_serial(ptr, field)   (container_of(ptr, struct fw_serial, field))
 338
 339#define TTY_DEV_NAME                "fwtty"     /* ttyFW was taken           */
 340static const char tty_dev_name[] =  TTY_DEV_NAME;
 341static const char loop_dev_name[] = "fwloop";
 342
 343extern struct tty_driver *fwtty_driver;
 344
 345/*
 346 * Returns the max send async payload size in bytes based on the unit device
 347 * link speed. Self-limiting asynchronous bandwidth (via reducing the payload)
 348 * is not necessary and does not work, because
 349 *   1) asynchronous traffic will absorb all available bandwidth (less that
 350 *      being used for isochronous traffic)
 351 *   2) isochronous arbitration always wins.
 352 */
 353static inline int link_speed_to_max_payload(unsigned int speed)
 354{
 355        /* Max async payload is 4096 - see IEEE 1394-2008 tables 6-4, 16-18 */
 356        return min(512 << speed, 4096);
 357}
 358
 359#endif /* _FIREWIRE_FWSERIAL_H */
 360