2021-10-11 16:38:30 +03:00
// SPDX-License-Identifier: GPL-2.0-or-later
2015-06-11 12:25:47 +03:00
/*
* Copyright ( C ) 2015 , Marvell International Ltd .
*
2021-10-11 16:38:30 +03:00
* Inspired ( hugely ) by HCI LDISC implementation in Bluetooth .
2015-06-11 12:25:47 +03:00
*
* Copyright ( C ) 2000 - 2001 Qualcomm Incorporated
* Copyright ( C ) 2002 - 2003 Maxim Krasnyansky < maxk @ qualcomm . com >
* Copyright ( C ) 2004 - 2005 Marcel Holtmann < marcel @ holtmann . org >
*/
# include <linux/module.h>
# include <linux/kernel.h>
# include <linux/init.h>
# include <linux/types.h>
# include <linux/fcntl.h>
# include <linux/interrupt.h>
# include <linux/ptrace.h>
# include <linux/poll.h>
# include <linux/slab.h>
# include <linux/tty.h>
# include <linux/errno.h>
# include <linux/string.h>
# include <linux/signal.h>
# include <linux/ioctl.h>
# include <linux/skbuff.h>
# include <net/nfc/nci.h>
# include <net/nfc/nci_core.h>
/* TX states */
# define NCI_UART_SENDING 1
# define NCI_UART_TX_WAKEUP 2
static struct nci_uart * nci_uart_drivers [ NCI_UART_DRIVER_MAX ] ;
static inline struct sk_buff * nci_uart_dequeue ( struct nci_uart * nu )
{
struct sk_buff * skb = nu - > tx_skb ;
if ( ! skb )
skb = skb_dequeue ( & nu - > tx_q ) ;
else
nu - > tx_skb = NULL ;
return skb ;
}
static inline int nci_uart_queue_empty ( struct nci_uart * nu )
{
if ( nu - > tx_skb )
return 0 ;
return skb_queue_empty ( & nu - > tx_q ) ;
}
static int nci_uart_tx_wakeup ( struct nci_uart * nu )
{
if ( test_and_set_bit ( NCI_UART_SENDING , & nu - > tx_state ) ) {
set_bit ( NCI_UART_TX_WAKEUP , & nu - > tx_state ) ;
return 0 ;
}
schedule_work ( & nu - > write_work ) ;
return 0 ;
}
static void nci_uart_write_work ( struct work_struct * work )
{
struct nci_uart * nu = container_of ( work , struct nci_uart , write_work ) ;
struct tty_struct * tty = nu - > tty ;
struct sk_buff * skb ;
restart :
clear_bit ( NCI_UART_TX_WAKEUP , & nu - > tx_state ) ;
if ( nu - > ops . tx_start )
nu - > ops . tx_start ( nu ) ;
while ( ( skb = nci_uart_dequeue ( nu ) ) ) {
int len ;
set_bit ( TTY_DO_WRITE_WAKEUP , & tty - > flags ) ;
len = tty - > ops - > write ( tty , skb - > data , skb - > len ) ;
skb_pull ( skb , len ) ;
if ( skb - > len ) {
nu - > tx_skb = skb ;
break ;
}
kfree_skb ( skb ) ;
}
if ( test_bit ( NCI_UART_TX_WAKEUP , & nu - > tx_state ) )
goto restart ;
if ( nu - > ops . tx_done & & nci_uart_queue_empty ( nu ) )
nu - > ops . tx_done ( nu ) ;
clear_bit ( NCI_UART_SENDING , & nu - > tx_state ) ;
}
static int nci_uart_set_driver ( struct tty_struct * tty , unsigned int driver )
{
struct nci_uart * nu = NULL ;
int ret ;
if ( driver > = NCI_UART_DRIVER_MAX )
return - EINVAL ;
if ( ! nci_uart_drivers [ driver ] )
return - ENOENT ;
nu = kzalloc ( sizeof ( * nu ) , GFP_KERNEL ) ;
if ( ! nu )
return - ENOMEM ;
memcpy ( nu , nci_uart_drivers [ driver ] , sizeof ( struct nci_uart ) ) ;
nu - > tty = tty ;
tty - > disc_data = nu ;
skb_queue_head_init ( & nu - > tx_q ) ;
INIT_WORK ( & nu - > write_work , nci_uart_write_work ) ;
spin_lock_init ( & nu - > rx_lock ) ;
ret = nu - > ops . open ( nu ) ;
if ( ret ) {
tty - > disc_data = NULL ;
kfree ( nu ) ;
} else if ( ! try_module_get ( nu - > owner ) ) {
nu - > ops . close ( nu ) ;
tty - > disc_data = NULL ;
kfree ( nu ) ;
return - ENOENT ;
}
return ret ;
}
/* ------ LDISC part ------ */
/* nci_uart_tty_open
*
* Called when line discipline changed to NCI_UART .
*
* Arguments :
* tty pointer to tty info structure
* Return Value :
* 0 if success , otherwise error code
*/
static int nci_uart_tty_open ( struct tty_struct * tty )
{
/* Error if the tty has no write op instead of leaving an exploitable
* hole
*/
if ( ! tty - > ops - > write )
return - EOPNOTSUPP ;
tty - > disc_data = NULL ;
tty - > receive_room = 65536 ;
2016-01-11 09:40:53 +03:00
/* Flush any pending characters in the driver */
2015-06-11 12:25:47 +03:00
tty_driver_flush_buffer ( tty ) ;
return 0 ;
}
/* nci_uart_tty_close()
*
* Called when the line discipline is changed to something
* else , the tty is closed , or the tty detects a hangup .
*/
static void nci_uart_tty_close ( struct tty_struct * tty )
{
struct nci_uart * nu = ( void * ) tty - > disc_data ;
/* Detach from the tty */
tty - > disc_data = NULL ;
if ( ! nu )
return ;
2018-09-20 12:37:44 +03:00
kfree_skb ( nu - > tx_skb ) ;
kfree_skb ( nu - > rx_skb ) ;
2015-06-11 12:25:47 +03:00
skb_queue_purge ( & nu - > tx_q ) ;
nu - > ops . close ( nu ) ;
nu - > tty = NULL ;
module_put ( nu - > owner ) ;
cancel_work_sync ( & nu - > write_work ) ;
kfree ( nu ) ;
}
/* nci_uart_tty_wakeup()
*
* Callback for transmit wakeup . Called when low level
* device driver can accept more send data .
*
* Arguments : tty pointer to associated tty instance data
* Return Value : None
*/
static void nci_uart_tty_wakeup ( struct tty_struct * tty )
{
struct nci_uart * nu = ( void * ) tty - > disc_data ;
if ( ! nu )
return ;
clear_bit ( TTY_DO_WRITE_WAKEUP , & tty - > flags ) ;
if ( tty ! = nu - > tty )
return ;
nci_uart_tx_wakeup ( nu ) ;
}
2021-03-02 09:21:46 +03:00
/* -- Default recv_buf handler --
*
* This handler supposes that NCI frames are sent over UART link without any
* framing . It reads NCI header , retrieve the packet size and once all packet
* bytes are received it passes it to nci_uart driver for processing .
*/
static int nci_uart_default_recv_buf ( struct nci_uart * nu , const u8 * data ,
int count )
{
int chunk_len ;
if ( ! nu - > ndev ) {
nfc_err ( nu - > tty - > dev ,
" receive data from tty but no NCI dev is attached yet, drop buffer \n " ) ;
return 0 ;
}
/* Decode all incoming data in packets
* and enqueue then for processing .
*/
while ( count > 0 ) {
/* If this is the first data of a packet, allocate a buffer */
if ( ! nu - > rx_skb ) {
nu - > rx_packet_len = - 1 ;
nu - > rx_skb = nci_skb_alloc ( nu - > ndev ,
NCI_MAX_PACKET_SIZE ,
GFP_ATOMIC ) ;
if ( ! nu - > rx_skb )
return - ENOMEM ;
}
/* Eat byte after byte till full packet header is received */
if ( nu - > rx_skb - > len < NCI_CTRL_HDR_SIZE ) {
skb_put_u8 ( nu - > rx_skb , * data + + ) ;
- - count ;
continue ;
}
/* Header was received but packet len was not read */
if ( nu - > rx_packet_len < 0 )
nu - > rx_packet_len = NCI_CTRL_HDR_SIZE +
nci_plen ( nu - > rx_skb - > data ) ;
/* Compute how many bytes are missing and how many bytes can
* be consumed .
*/
chunk_len = nu - > rx_packet_len - nu - > rx_skb - > len ;
if ( count < chunk_len )
chunk_len = count ;
skb_put_data ( nu - > rx_skb , data , chunk_len ) ;
data + = chunk_len ;
count - = chunk_len ;
Networking changes for 5.13.
Core:
- bpf:
- allow bpf programs calling kernel functions (initially to
reuse TCP congestion control implementations)
- enable task local storage for tracing programs - remove the
need to store per-task state in hash maps, and allow tracing
programs access to task local storage previously added for
BPF_LSM
- add bpf_for_each_map_elem() helper, allowing programs to
walk all map elements in a more robust and easier to verify
fashion
- sockmap: support UDP and cross-protocol BPF_SK_SKB_VERDICT
redirection
- lpm: add support for batched ops in LPM trie
- add BTF_KIND_FLOAT support - mostly to allow use of BTF
on s390 which has floats in its headers files
- improve BPF syscall documentation and extend the use of kdoc
parsing scripts we already employ for bpf-helpers
- libbpf, bpftool: support static linking of BPF ELF files
- improve support for encapsulation of L2 packets
- xdp: restructure redirect actions to avoid a runtime lookup,
improving performance by 4-8% in microbenchmarks
- xsk: build skb by page (aka generic zerocopy xmit) - improve
performance of software AF_XDP path by 33% for devices
which don't need headers in the linear skb part (e.g. virtio)
- nexthop: resilient next-hop groups - improve path stability
on next-hops group changes (incl. offload for mlxsw)
- ipv6: segment routing: add support for IPv4 decapsulation
- icmp: add support for RFC 8335 extended PROBE messages
- inet: use bigger hash table for IP ID generation
- tcp: deal better with delayed TX completions - make sure we don't
give up on fast TCP retransmissions only because driver is
slow in reporting that it completed transmitting the original
- tcp: reorder tcp_congestion_ops for better cache locality
- mptcp:
- add sockopt support for common TCP options
- add support for common TCP msg flags
- include multiple address ids in RM_ADDR
- add reset option support for resetting one subflow
- udp: GRO L4 improvements - improve 'forward' / 'frag_list'
co-existence with UDP tunnel GRO, allowing the first to take
place correctly even for encapsulated UDP traffic
- micro-optimize dev_gro_receive() and flow dissection, avoid
retpoline overhead on VLAN and TEB GRO
- use less memory for sysctls, add a new sysctl type, to allow using
u8 instead of "int" and "long" and shrink networking sysctls
- veth: allow GRO without XDP - this allows aggregating UDP
packets before handing them off to routing, bridge, OvS, etc.
- allow specifing ifindex when device is moved to another namespace
- netfilter:
- nft_socket: add support for cgroupsv2
- nftables: add catch-all set element - special element used
to define a default action in case normal lookup missed
- use net_generic infra in many modules to avoid allocating
per-ns memory unnecessarily
- xps: improve the xps handling to avoid potential out-of-bound
accesses and use-after-free when XPS change race with other
re-configuration under traffic
- add a config knob to turn off per-cpu netdev refcnt to catch
underflows in testing
Device APIs:
- add WWAN subsystem to organize the WWAN interfaces better and
hopefully start driving towards more unified and vendor-
-independent APIs
- ethtool:
- add interface for reading IEEE MIB stats (incl. mlx5 and
bnxt support)
- allow network drivers to dump arbitrary SFP EEPROM data,
current offset+length API was a poor fit for modern SFP
which define EEPROM in terms of pages (incl. mlx5 support)
- act_police, flow_offload: add support for packet-per-second
policing (incl. offload for nfp)
- psample: add additional metadata attributes like transit delay
for packets sampled from switch HW (and corresponding egress
and policy-based sampling in the mlxsw driver)
- dsa: improve support for sandwiched LAGs with bridge and DSA
- netfilter:
- flowtable: use direct xmit in topologies with IP
forwarding, bridging, vlans etc.
- nftables: counter hardware offload support
- Bluetooth:
- improvements for firmware download w/ Intel devices
- add support for reading AOSP vendor capabilities
- add support for virtio transport driver
- mac80211:
- allow concurrent monitor iface and ethernet rx decap
- set priority and queue mapping for injected frames
- phy: add support for Clause-45 PHY Loopback
- pci/iov: add sysfs MSI-X vector assignment interface
to distribute MSI-X resources to VFs (incl. mlx5 support)
New hardware/drivers:
- dsa: mv88e6xxx: add support for Marvell mv88e6393x -
11-port Ethernet switch with 8x 1-Gigabit Ethernet
and 3x 10-Gigabit interfaces.
- dsa: support for legacy Broadcom tags used on BCM5325, BCM5365
and BCM63xx switches
- Microchip KSZ8863 and KSZ8873; 3x 10/100Mbps Ethernet switches
- ath11k: support for QCN9074 a 802.11ax device
- Bluetooth: Broadcom BCM4330 and BMC4334
- phy: Marvell 88X2222 transceiver support
- mdio: add BCM6368 MDIO mux bus controller
- r8152: support RTL8153 and RTL8156 (USB Ethernet) chips
- mana: driver for Microsoft Azure Network Adapter (MANA)
- Actions Semi Owl Ethernet MAC
- can: driver for ETAS ES58X CAN/USB interfaces
Pure driver changes:
- add XDP support to: enetc, igc, stmmac
- add AF_XDP support to: stmmac
- virtio:
- page_to_skb() use build_skb when there's sufficient tailroom
(21% improvement for 1000B UDP frames)
- support XDP even without dedicated Tx queues - share the Tx
queues with the stack when necessary
- mlx5:
- flow rules: add support for mirroring with conntrack,
matching on ICMP, GTP, flex filters and more
- support packet sampling with flow offloads
- persist uplink representor netdev across eswitch mode
changes
- allow coexistence of CQE compression and HW time-stamping
- add ethtool extended link error state reporting
- ice, iavf: support flow filters, UDP Segmentation Offload
- dpaa2-switch:
- move the driver out of staging
- add spanning tree (STP) support
- add rx copybreak support
- add tc flower hardware offload on ingress traffic
- ionic:
- implement Rx page reuse
- support HW PTP time-stamping
- octeon: support TC hardware offloads - flower matching on ingress
and egress ratelimitting.
- stmmac:
- add RX frame steering based on VLAN priority in tc flower
- support frame preemption (FPE)
- intel: add cross time-stamping freq difference adjustment
- ocelot:
- support forwarding of MRP frames in HW
- support multiple bridges
- support PTP Sync one-step timestamping
- dsa: mv88e6xxx, dpaa2-switch: offload bridge port flags like
learning, flooding etc.
- ipa: add IPA v4.5, v4.9 and v4.11 support (Qualcomm SDX55, SM8350,
SC7280 SoCs)
- mt7601u: enable TDLS support
- mt76:
- add support for 802.3 rx frames (mt7915/mt7615)
- mt7915 flash pre-calibration support
- mt7921/mt7663 runtime power management fixes
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-----BEGIN PGP SIGNATURE-----
iQIzBAABCAAdFiEE6jPA+I1ugmIBA4hXMUZtbf5SIrsFAmCKFPIACgkQMUZtbf5S
Irtw0g/+NA8bWdHNgG4H5rya0pv2z3IieLRmSdDfKRQQXcJpklawc5MKVVaTee/Q
5/QqgPdCsu1LAU6JXBKsKmyDDaMlQKdWuKbOqDSiAQKoMesZStTEHf9d851ZzgxA
Cdb6O7BD3lBl/IN+oxNG+KcmD1LKquTPKGySq2mQtEdLO12ekAsranzmj4voKffd
q9tBShpXQ7Dq77DLYfiQXVCvsizNcbbJFuxX0o9Lpb9+61ZyYAbogZSa9ypiZZwR
I/9azRBtJg7UV1aD/cLuAfy66Qh7t63+rCxVazs5Os8jVO26P/jQdisnnOe/x+p9
wYEmKm3GSu0V4SAPxkWW+ooKusflCeqDoMIuooKt6kbP6BRj540veGw3Ww/m5YFr
7pLQkTSP/tSjuGQIdBE1LOP5LBO8DZeC8Kiop9V0fzAW9hFSZbEq25WW0bPj8QQO
zA4Z7yWlslvxcfY2BdJX3wD8klaINkl/8fDWZFFsBdfFX2VeLtm7Xfduw34BJpvU
rYT3oWr6PhtkPAKR32SUcemSfeWgIVU41eSshzRz3kez1NngBUuLlSGGSEaKbes5
pZVt6pYFFVByyf6MTHFEoQvafZfEw04JILZpo4R5V8iTHzom0kD3Py064sBiXEw2
B6t+OW4qgcxGblpFkK2lD4kR2s1TPUs0ckVO6sAy1x8q60KKKjY=
=vcbA
-----END PGP SIGNATURE-----
Merge tag 'net-next-5.13' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next
Pull networking updates from Jakub Kicinski:
"Core:
- bpf:
- allow bpf programs calling kernel functions (initially to
reuse TCP congestion control implementations)
- enable task local storage for tracing programs - remove the
need to store per-task state in hash maps, and allow tracing
programs access to task local storage previously added for
BPF_LSM
- add bpf_for_each_map_elem() helper, allowing programs to walk
all map elements in a more robust and easier to verify fashion
- sockmap: support UDP and cross-protocol BPF_SK_SKB_VERDICT
redirection
- lpm: add support for batched ops in LPM trie
- add BTF_KIND_FLOAT support - mostly to allow use of BTF on
s390 which has floats in its headers files
- improve BPF syscall documentation and extend the use of kdoc
parsing scripts we already employ for bpf-helpers
- libbpf, bpftool: support static linking of BPF ELF files
- improve support for encapsulation of L2 packets
- xdp: restructure redirect actions to avoid a runtime lookup,
improving performance by 4-8% in microbenchmarks
- xsk: build skb by page (aka generic zerocopy xmit) - improve
performance of software AF_XDP path by 33% for devices which don't
need headers in the linear skb part (e.g. virtio)
- nexthop: resilient next-hop groups - improve path stability on
next-hops group changes (incl. offload for mlxsw)
- ipv6: segment routing: add support for IPv4 decapsulation
- icmp: add support for RFC 8335 extended PROBE messages
- inet: use bigger hash table for IP ID generation
- tcp: deal better with delayed TX completions - make sure we don't
give up on fast TCP retransmissions only because driver is slow in
reporting that it completed transmitting the original
- tcp: reorder tcp_congestion_ops for better cache locality
- mptcp:
- add sockopt support for common TCP options
- add support for common TCP msg flags
- include multiple address ids in RM_ADDR
- add reset option support for resetting one subflow
- udp: GRO L4 improvements - improve 'forward' / 'frag_list'
co-existence with UDP tunnel GRO, allowing the first to take place
correctly even for encapsulated UDP traffic
- micro-optimize dev_gro_receive() and flow dissection, avoid
retpoline overhead on VLAN and TEB GRO
- use less memory for sysctls, add a new sysctl type, to allow using
u8 instead of "int" and "long" and shrink networking sysctls
- veth: allow GRO without XDP - this allows aggregating UDP packets
before handing them off to routing, bridge, OvS, etc.
- allow specifing ifindex when device is moved to another namespace
- netfilter:
- nft_socket: add support for cgroupsv2
- nftables: add catch-all set element - special element used to
define a default action in case normal lookup missed
- use net_generic infra in many modules to avoid allocating
per-ns memory unnecessarily
- xps: improve the xps handling to avoid potential out-of-bound
accesses and use-after-free when XPS change race with other
re-configuration under traffic
- add a config knob to turn off per-cpu netdev refcnt to catch
underflows in testing
Device APIs:
- add WWAN subsystem to organize the WWAN interfaces better and
hopefully start driving towards more unified and vendor-
independent APIs
- ethtool:
- add interface for reading IEEE MIB stats (incl. mlx5 and bnxt
support)
- allow network drivers to dump arbitrary SFP EEPROM data,
current offset+length API was a poor fit for modern SFP which
define EEPROM in terms of pages (incl. mlx5 support)
- act_police, flow_offload: add support for packet-per-second
policing (incl. offload for nfp)
- psample: add additional metadata attributes like transit delay for
packets sampled from switch HW (and corresponding egress and
policy-based sampling in the mlxsw driver)
- dsa: improve support for sandwiched LAGs with bridge and DSA
- netfilter:
- flowtable: use direct xmit in topologies with IP forwarding,
bridging, vlans etc.
- nftables: counter hardware offload support
- Bluetooth:
- improvements for firmware download w/ Intel devices
- add support for reading AOSP vendor capabilities
- add support for virtio transport driver
- mac80211:
- allow concurrent monitor iface and ethernet rx decap
- set priority and queue mapping for injected frames
- phy: add support for Clause-45 PHY Loopback
- pci/iov: add sysfs MSI-X vector assignment interface to distribute
MSI-X resources to VFs (incl. mlx5 support)
New hardware/drivers:
- dsa: mv88e6xxx: add support for Marvell mv88e6393x - 11-port
Ethernet switch with 8x 1-Gigabit Ethernet and 3x 10-Gigabit
interfaces.
- dsa: support for legacy Broadcom tags used on BCM5325, BCM5365 and
BCM63xx switches
- Microchip KSZ8863 and KSZ8873; 3x 10/100Mbps Ethernet switches
- ath11k: support for QCN9074 a 802.11ax device
- Bluetooth: Broadcom BCM4330 and BMC4334
- phy: Marvell 88X2222 transceiver support
- mdio: add BCM6368 MDIO mux bus controller
- r8152: support RTL8153 and RTL8156 (USB Ethernet) chips
- mana: driver for Microsoft Azure Network Adapter (MANA)
- Actions Semi Owl Ethernet MAC
- can: driver for ETAS ES58X CAN/USB interfaces
Pure driver changes:
- add XDP support to: enetc, igc, stmmac
- add AF_XDP support to: stmmac
- virtio:
- page_to_skb() use build_skb when there's sufficient tailroom
(21% improvement for 1000B UDP frames)
- support XDP even without dedicated Tx queues - share the Tx
queues with the stack when necessary
- mlx5:
- flow rules: add support for mirroring with conntrack, matching
on ICMP, GTP, flex filters and more
- support packet sampling with flow offloads
- persist uplink representor netdev across eswitch mode changes
- allow coexistence of CQE compression and HW time-stamping
- add ethtool extended link error state reporting
- ice, iavf: support flow filters, UDP Segmentation Offload
- dpaa2-switch:
- move the driver out of staging
- add spanning tree (STP) support
- add rx copybreak support
- add tc flower hardware offload on ingress traffic
- ionic:
- implement Rx page reuse
- support HW PTP time-stamping
- octeon: support TC hardware offloads - flower matching on ingress
and egress ratelimitting.
- stmmac:
- add RX frame steering based on VLAN priority in tc flower
- support frame preemption (FPE)
- intel: add cross time-stamping freq difference adjustment
- ocelot:
- support forwarding of MRP frames in HW
- support multiple bridges
- support PTP Sync one-step timestamping
- dsa: mv88e6xxx, dpaa2-switch: offload bridge port flags like
learning, flooding etc.
- ipa: add IPA v4.5, v4.9 and v4.11 support (Qualcomm SDX55, SM8350,
SC7280 SoCs)
- mt7601u: enable TDLS support
- mt76:
- add support for 802.3 rx frames (mt7915/mt7615)
- mt7915 flash pre-calibration support
- mt7921/mt7663 runtime power management fixes"
* tag 'net-next-5.13' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next: (2451 commits)
net: selftest: fix build issue if INET is disabled
net: netrom: nr_in: Remove redundant assignment to ns
net: tun: Remove redundant assignment to ret
net: phy: marvell: add downshift support for M88E1240
net: dsa: ksz: Make reg_mib_cnt a u8 as it never exceeds 255
net/sched: act_ct: Remove redundant ct get and check
icmp: standardize naming of RFC 8335 PROBE constants
bpf, selftests: Update array map tests for per-cpu batched ops
bpf: Add batched ops support for percpu array
bpf: Implement formatted output helpers with bstr_printf
seq_file: Add a seq_bprintf function
sfc: adjust efx->xdp_tx_queue_count with the real number of initialized queues
net:nfc:digital: Fix a double free in digital_tg_recv_dep_req
net: fix a concurrency bug in l2tp_tunnel_register()
net/smc: Remove redundant assignment to rc
mpls: Remove redundant assignment to err
llc2: Remove redundant assignment to rc
net/tls: Remove redundant initialization of record
rds: Remove redundant assignment to nr_sig
dt-bindings: net: mdio-gpio: add compatible for microchip,mdio-smi0
...
2021-04-29 21:57:23 +03:00
/* Check if packet is fully received */
2021-03-02 09:21:46 +03:00
if ( nu - > rx_packet_len = = nu - > rx_skb - > len ) {
/* Pass RX packet to driver */
if ( nu - > ops . recv ( nu , nu - > rx_skb ) ! = 0 )
nfc_err ( nu - > tty - > dev , " corrupted RX packet \n " ) ;
/* Next packet will be a new one */
nu - > rx_skb = NULL ;
}
}
return 0 ;
}
2015-06-11 12:25:47 +03:00
/* nci_uart_tty_receive()
*
* Called by tty low level driver when receive data is
* available .
*
2021-04-05 13:54:35 +03:00
* Arguments : tty pointer to tty instance data
2015-06-11 12:25:47 +03:00
* data pointer to received data
* flags pointer to flags for data
* count count of received data in bytes
*
* Return Value : None
*/
static void nci_uart_tty_receive ( struct tty_struct * tty , const u8 * data ,
2021-05-05 12:19:04 +03:00
const char * flags , int count )
2015-06-11 12:25:47 +03:00
{
struct nci_uart * nu = ( void * ) tty - > disc_data ;
if ( ! nu | | tty ! = nu - > tty )
return ;
spin_lock ( & nu - > rx_lock ) ;
2021-03-02 09:21:46 +03:00
nci_uart_default_recv_buf ( nu , data , count ) ;
2015-06-11 12:25:47 +03:00
spin_unlock ( & nu - > rx_lock ) ;
tty_unthrottle ( tty ) ;
}
/* nci_uart_tty_ioctl()
*
* Process IOCTL system call for the tty device .
*
* Arguments :
*
* tty pointer to tty instance data
* cmd IOCTL command code
* arg argument for IOCTL call ( cmd dependent )
*
* Return Value : Command dependent
*/
2021-11-22 12:45:29 +03:00
static int nci_uart_tty_ioctl ( struct tty_struct * tty , unsigned int cmd ,
unsigned long arg )
2015-06-11 12:25:47 +03:00
{
struct nci_uart * nu = ( void * ) tty - > disc_data ;
int err = 0 ;
switch ( cmd ) {
case NCIUARTSETDRIVER :
if ( ! nu )
return nci_uart_set_driver ( tty , ( unsigned int ) arg ) ;
else
return - EBUSY ;
break ;
default :
2021-09-14 12:11:24 +03:00
err = n_tty_ioctl_helper ( tty , cmd , arg ) ;
2015-06-11 12:25:47 +03:00
break ;
}
return err ;
}
/* We don't provide read/write/poll interface for user space. */
static ssize_t nci_uart_tty_read ( struct tty_struct * tty , struct file * file ,
2021-01-19 00:31:30 +03:00
unsigned char * buf , size_t nr ,
void * * cookie , unsigned long offset )
2015-06-11 12:25:47 +03:00
{
return 0 ;
}
static ssize_t nci_uart_tty_write ( struct tty_struct * tty , struct file * file ,
const unsigned char * data , size_t count )
{
return 0 ;
}
2017-07-03 07:01:49 +03:00
static __poll_t nci_uart_tty_poll ( struct tty_struct * tty ,
2015-06-11 12:25:47 +03:00
struct file * filp , poll_table * wait )
{
return 0 ;
}
static int nci_uart_send ( struct nci_uart * nu , struct sk_buff * skb )
{
/* Queue TX packet */
skb_queue_tail ( & nu - > tx_q , skb ) ;
/* Try to start TX (if possible) */
nci_uart_tx_wakeup ( nu ) ;
return 0 ;
}
int nci_uart_register ( struct nci_uart * nu )
{
if ( ! nu | | ! nu - > ops . open | |
! nu - > ops . recv | | ! nu - > ops . close )
return - EINVAL ;
/* Set the send callback */
nu - > ops . send = nci_uart_send ;
/* Add this driver in the driver list */
2015-06-15 18:34:23 +03:00
if ( nci_uart_drivers [ nu - > driver ] ) {
2015-06-11 12:25:47 +03:00
pr_err ( " driver %d is already registered \n " , nu - > driver ) ;
return - EBUSY ;
}
nci_uart_drivers [ nu - > driver ] = nu ;
pr_info ( " NCI uart driver '%s [%d]' registered \n " , nu - > name , nu - > driver ) ;
return 0 ;
}
EXPORT_SYMBOL_GPL ( nci_uart_register ) ;
void nci_uart_unregister ( struct nci_uart * nu )
{
pr_info ( " NCI uart driver '%s [%d]' unregistered \n " , nu - > name ,
nu - > driver ) ;
/* Remove this driver from the driver list */
nci_uart_drivers [ nu - > driver ] = NULL ;
}
EXPORT_SYMBOL_GPL ( nci_uart_unregister ) ;
void nci_uart_set_config ( struct nci_uart * nu , int baudrate , int flow_ctrl )
{
struct ktermios new_termios ;
if ( ! nu - > tty )
return ;
down_read ( & nu - > tty - > termios_rwsem ) ;
new_termios = nu - > tty - > termios ;
up_read ( & nu - > tty - > termios_rwsem ) ;
tty_termios_encode_baud_rate ( & new_termios , baudrate , baudrate ) ;
if ( flow_ctrl )
new_termios . c_cflag | = CRTSCTS ;
else
new_termios . c_cflag & = ~ CRTSCTS ;
tty_set_termios ( nu - > tty , & new_termios ) ;
}
EXPORT_SYMBOL_GPL ( nci_uart_set_config ) ;
static struct tty_ldisc_ops nci_uart_ldisc = {
. owner = THIS_MODULE ,
2021-05-05 12:19:07 +03:00
. num = N_NCI ,
2015-06-11 12:25:47 +03:00
. name = " n_nci " ,
. open = nci_uart_tty_open ,
. close = nci_uart_tty_close ,
. read = nci_uart_tty_read ,
. write = nci_uart_tty_write ,
. poll = nci_uart_tty_poll ,
. receive_buf = nci_uart_tty_receive ,
. write_wakeup = nci_uart_tty_wakeup ,
. ioctl = nci_uart_tty_ioctl ,
2018-09-14 05:12:15 +03:00
. compat_ioctl = nci_uart_tty_ioctl ,
2015-06-11 12:25:47 +03:00
} ;
static int __init nci_uart_init ( void )
{
2021-05-05 12:19:07 +03:00
return tty_register_ldisc ( & nci_uart_ldisc ) ;
2015-06-11 12:25:47 +03:00
}
static void __exit nci_uart_exit ( void )
{
2021-05-05 12:19:09 +03:00
tty_unregister_ldisc ( & nci_uart_ldisc ) ;
2015-06-11 12:25:47 +03:00
}
module_init ( nci_uart_init ) ;
module_exit ( nci_uart_exit ) ;
MODULE_AUTHOR ( " Marvell International Ltd. " ) ;
MODULE_DESCRIPTION ( " NFC NCI UART driver " ) ;
MODULE_LICENSE ( " GPL " ) ;
MODULE_ALIAS_LDISC ( N_NCI ) ;