From nobody Wed Nov 27 08:36:38 2024 Received: from mail-ej1-f53.google.com (mail-ej1-f53.google.com [209.85.218.53]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B3ACB15B0F2 for ; Thu, 10 Oct 2024 19:15:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.53 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728587721; cv=none; b=LbdVDMfj8+/bn6CJ3r637N9iplk9PviaqcGfvV+p9gx2e/05jhYumko2fyM0XZQNmLcTHUlzld8HF5cvCYaStQ2j3pm2kFEWi+50m/cb6w46E85C3QtKL97A6E/ImaCXoCNePU9JLPqftP+XGM/KMvMCmbN1jF/QiG1dpk5TTNA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728587721; c=relaxed/simple; bh=CFH7fBtaQbO+DMtRmRoKzeoMpMzHPQK+sJM/IN1KsgI=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=axgkQWota25gEB+gyiDhjHwRxoTmvYFlf3D6MyOZF1Di0/+g3sfv1J6XT+W+qHTytsWiYJo7X6w6gQgITRAVEkjL3W2H0KgENGxSzynec95rpLt70TYrpS9cN2VOIIFAzOf0TSo7UfAzrTaDZgZ8MTVGX7MXwqvu7RlVmlRgO8A= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=S8kEMZah; arc=none smtp.client-ip=209.85.218.53 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="S8kEMZah" Received: by mail-ej1-f53.google.com with SMTP id a640c23a62f3a-a999521d0c3so215899266b.1 for ; Thu, 10 Oct 2024 12:15:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1728587714; x=1729192514; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=889JvIvG2h3l36X+7CfunUm2Tslw5EYsT054sNTXbgQ=; b=S8kEMZahW8Fa3bv2AXtuhmqtvDG0IvZNWYPh3rIhUPSkSKBbs7oPs8VYFdH5MAaVf/ C/rt/Pp6vrfDfCDjVEdewA/5wQN3wuT/gI2WbhgjpUHMcLZhjv7EmptgEX564rsMp+Cu VmNNbUUB3kABWzJaOp/mKHzHJPliDWnUZW6ZUmS9UFcd+8ccf1rG3jpRz+/iy2UfZ754 3K4Rx837oViXYiIIU06Il6/IZP5PtsDY/tO561G9q/+pMq0KcfThjlHX67FJpRChcvtw gCRaFUK1PVQaxiBdLZyGb9vn+BkNYVCSSgyzvqrFK1ehczaMl3QG8r9CkdxNIMRwZyo6 1kCQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1728587714; x=1729192514; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=889JvIvG2h3l36X+7CfunUm2Tslw5EYsT054sNTXbgQ=; b=YzOjy0U/H4oZoCdAli6NQhlrBSc4JMQ/cvY/ftj/hggYkZKa1PAQw5e5ToA95dkKRo QHC4V55pIPFPrKPriAy87GnI4hwcad8zAHjB49KDv8hr4u9lNSSuNjaP2CRRXBp4uQ6/ 8RQEKL5Zl1fay5SSBHhTc3LEfYx4OEZzuYDfdSCDFGvUgxPRA/BnDVQG2PifYBpKudiL yIW2GwXZPlUzIBH6o4qt0iIm1Yjf9tiLeQNQZyM5dnc5EA8t1CLEQWdEG8l6bRNSB0nL lk7ztVZLThRFprg6m1aBQN4dczNb3HN6rJvH0rC1EhVc4CNr7HfwgoBBc0GLLQJGBqRh RUXA== X-Forwarded-Encrypted: i=1; AJvYcCXFOmFQ5lIOAiMHCWaninxDLn+yA10rxMB50hxJ/mMautwPfjo1mlPtu/v+7fUUSPOX1wQ6hJ9sRU2aZ84=@vger.kernel.org X-Gm-Message-State: AOJu0YzNwj4amj2vwfULq95OXmaKJ8+K94/Mp+1kTz79PBUPZxiP70pr PL56iokRlfBs56b84/9tT0WzZmU7GhEIKwmCWJ3gUmnXzp79AxYR X-Google-Smtp-Source: AGHT+IEJTUfyXLk3RUGEez71K5/av9TAeyvF6rQCr6aCeLtKWYzUBpEBkiTY9/WPmsvqKM9oqM2Faw== X-Received: by 2002:a17:907:6d19:b0:a99:3c32:b538 with SMTP id a640c23a62f3a-a99b95a7430mr4839366b.42.1728587713032; Thu, 10 Oct 2024 12:15:13 -0700 (PDT) Received: from kernel-710.speedport.ip (p54a0712c.dip0.t-ipconnect.de. [84.160.113.44]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-a99a7ec580bsm128429666b.29.2024.10.10.12.15.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 10 Oct 2024 12:15:12 -0700 (PDT) From: Philipp Hortmann To: Greg Kroah-Hartman , linux-staging@lists.linux.dev, linux-kernel@vger.kernel.org Cc: Philipp Hortmann Subject: [PATCH] staging: gdm724x: Remove unused driver Date: Thu, 10 Oct 2024 21:15:06 +0200 Message-ID: <20241010191508.21055-1-philipp.g.hortmann@gmail.com> X-Mailer: git-send-email 2.43.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Won Kang from gct contributed the driver in 2013. The following reasons lead to the removal: - This driver generates maintenance workload - The manufacturer is not interested and does not care as Emails or inquiries, to support or involved persons of gct, got unanswered. - Did not find a possibility to buy the chips. - Did not find minimal documentation on the web. - Did not find a device where it is build in and the user is able to install any Linux. Therefore it is not possible to do any testing of the driver from the community. - No blog entries about anyone using the gdmtty and gdmulte. - No response about usage of this drivers to the Email from April 2024 Link: https://lore.kernel.org/linux-staging/2024100910-smoky-condiment-2298= @gregkh/T/#u Link: https://lore.kernel.org/all/78b521eb-4e89-4c01-8dfc-1fb990e6887d@gmai= l.com/ Signed-off-by: Philipp Hortmann --- Checked for artifacts of gdm724x in MAINTAINERS. Removed artifacts in Makefile and Kconfig. --- drivers/staging/Kconfig | 2 - drivers/staging/Makefile | 1 - drivers/staging/gdm724x/Kconfig | 16 - drivers/staging/gdm724x/Makefile | 8 - drivers/staging/gdm724x/TODO | 15 - drivers/staging/gdm724x/gdm_endian.c | 37 - drivers/staging/gdm724x/gdm_endian.h | 30 - drivers/staging/gdm724x/gdm_lte.c | 937 ------------------------ drivers/staging/gdm724x/gdm_lte.h | 71 -- drivers/staging/gdm724x/gdm_mux.c | 668 ----------------- drivers/staging/gdm724x/gdm_mux.h | 85 --- drivers/staging/gdm724x/gdm_tty.c | 316 -------- drivers/staging/gdm724x/gdm_tty.h | 60 -- drivers/staging/gdm724x/gdm_usb.c | 1014 -------------------------- drivers/staging/gdm724x/gdm_usb.h | 99 --- drivers/staging/gdm724x/hci.h | 45 -- drivers/staging/gdm724x/hci_packet.h | 82 --- drivers/staging/gdm724x/netlink_k.c | 128 ---- drivers/staging/gdm724x/netlink_k.h | 16 - 19 files changed, 3630 deletions(-) delete mode 100644 drivers/staging/gdm724x/Kconfig delete mode 100644 drivers/staging/gdm724x/Makefile delete mode 100644 drivers/staging/gdm724x/TODO delete mode 100644 drivers/staging/gdm724x/gdm_endian.c delete mode 100644 drivers/staging/gdm724x/gdm_endian.h delete mode 100644 drivers/staging/gdm724x/gdm_lte.c delete mode 100644 drivers/staging/gdm724x/gdm_lte.h delete mode 100644 drivers/staging/gdm724x/gdm_mux.c delete mode 100644 drivers/staging/gdm724x/gdm_mux.h delete mode 100644 drivers/staging/gdm724x/gdm_tty.c delete mode 100644 drivers/staging/gdm724x/gdm_tty.h delete mode 100644 drivers/staging/gdm724x/gdm_usb.c delete mode 100644 drivers/staging/gdm724x/gdm_usb.h delete mode 100644 drivers/staging/gdm724x/hci.h delete mode 100644 drivers/staging/gdm724x/hci_packet.h delete mode 100644 drivers/staging/gdm724x/netlink_k.c delete mode 100644 drivers/staging/gdm724x/netlink_k.h diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 5fbb0bc53308..2493e150fbbd 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -42,8 +42,6 @@ source "drivers/staging/nvec/Kconfig" =20 source "drivers/staging/media/Kconfig" =20 -source "drivers/staging/gdm724x/Kconfig" - source "drivers/staging/fbtft/Kconfig" =20 source "drivers/staging/most/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 797dcd192a33..add5e887e451 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -11,7 +11,6 @@ obj-$(CONFIG_VME_BUS) +=3D vme_user/ obj-$(CONFIG_IIO) +=3D iio/ obj-$(CONFIG_FB_SM750) +=3D sm750fb/ obj-$(CONFIG_MFD_NVEC) +=3D nvec/ -obj-$(CONFIG_LTE_GDM724X) +=3D gdm724x/ obj-$(CONFIG_FB_TFT) +=3D fbtft/ obj-$(CONFIG_MOST) +=3D most/ obj-$(CONFIG_GREYBUS) +=3D greybus/ diff --git a/drivers/staging/gdm724x/Kconfig b/drivers/staging/gdm724x/Kcon= fig deleted file mode 100644 index 1f403ecd9608..000000000000 --- a/drivers/staging/gdm724x/Kconfig +++ /dev/null @@ -1,16 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -# -# GCT GDM724x LTE driver configuration -# - -config LTE_GDM724X - tristate "GCT GDM724x LTE support" - depends on NET && USB && TTY && m - help - This driver supports GCT GDM724x LTE chip based USB modem devices. - It exposes 4 network devices to be used per PDN and 2 tty devices to be - used for AT commands and DM monitoring applications. - The modules will be called gdmulte.ko and gdmtty.ko - - GCT-ATCx can be used for AT Commands - GCT-DMx can be used for LTE protocol monitoring diff --git a/drivers/staging/gdm724x/Makefile b/drivers/staging/gdm724x/Mak= efile deleted file mode 100644 index e61b95788c9f..000000000000 --- a/drivers/staging/gdm724x/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_LTE_GDM724X) :=3D gdmulte.o -gdmulte-y +=3D gdm_lte.o netlink_k.o -gdmulte-y +=3D gdm_usb.o gdm_endian.o - -obj-$(CONFIG_LTE_GDM724X) +=3D gdmtty.o -gdmtty-y :=3D gdm_tty.o gdm_mux.o - diff --git a/drivers/staging/gdm724x/TODO b/drivers/staging/gdm724x/TODO deleted file mode 100644 index 56a415b9dcbe..000000000000 --- a/drivers/staging/gdm724x/TODO +++ /dev/null @@ -1,15 +0,0 @@ -TODO: -- Clean up coding style to meet kernel standard. (80 line limit, netdev_er= r) -- Remove test for host endian -- Remove confusing macros (endian, hci_send, sdu_send, rcv_with_cb) -- Check for skb->len in gdm_lte_emulate_arp() -- Use ALIGN() macro for dummy_cnt in up_to_host() -- Error handling in init_usb() -- Explain reason for multiples of 512 bytes in alloc_tx_struct() -- Review use of atomic allocation for tx structs -- No error checking for alloc_tx_struct in do_tx() -- fix up static tty port allocation to be dynamic - -Patches to: - Jonathan Kim - Dean ahn diff --git a/drivers/staging/gdm724x/gdm_endian.c b/drivers/staging/gdm724x= /gdm_endian.c deleted file mode 100644 index ae39e59daf70..000000000000 --- a/drivers/staging/gdm724x/gdm_endian.c +++ /dev/null @@ -1,37 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved. */ - -#include -#include "gdm_endian.h" - -__dev16 gdm_cpu_to_dev16(u8 dev_ed, u16 x) -{ - if (dev_ed =3D=3D ENDIANNESS_LITTLE) - return (__force __dev16)cpu_to_le16(x); - else - return (__force __dev16)cpu_to_be16(x); -} - -u16 gdm_dev16_to_cpu(u8 dev_ed, __dev16 x) -{ - if (dev_ed =3D=3D ENDIANNESS_LITTLE) - return le16_to_cpu((__force __le16)x); - else - return be16_to_cpu((__force __be16)x); -} - -__dev32 gdm_cpu_to_dev32(u8 dev_ed, u32 x) -{ - if (dev_ed =3D=3D ENDIANNESS_LITTLE) - return (__force __dev32)cpu_to_le32(x); - else - return (__force __dev32)cpu_to_be32(x); -} - -u32 gdm_dev32_to_cpu(u8 dev_ed, __dev32 x) -{ - if (dev_ed =3D=3D ENDIANNESS_LITTLE) - return le32_to_cpu((__force __le32)x); - else - return be32_to_cpu((__force __be32)x); -} diff --git a/drivers/staging/gdm724x/gdm_endian.h b/drivers/staging/gdm724x= /gdm_endian.h deleted file mode 100644 index f373dc3a19bf..000000000000 --- a/drivers/staging/gdm724x/gdm_endian.h +++ /dev/null @@ -1,30 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved. */ - -#ifndef __GDM_ENDIAN_H__ -#define __GDM_ENDIAN_H__ - -#include - -/* - * For data in "device-endian" byte order (device endianness is model - * dependent). Analogous to __leXX or __beXX. - */ -typedef __u32 __bitwise __dev32; -typedef __u16 __bitwise __dev16; - -enum { - ENDIANNESS_MIN =3D 0, - ENDIANNESS_UNKNOWN, - ENDIANNESS_LITTLE, - ENDIANNESS_BIG, - ENDIANNESS_MIDDLE, - ENDIANNESS_MAX -}; - -__dev16 gdm_cpu_to_dev16(u8 dev_ed, u16 x); -u16 gdm_dev16_to_cpu(u8 dev_ed, __dev16 x); -__dev32 gdm_cpu_to_dev32(u8 dev_ed, u32 x); -u32 gdm_dev32_to_cpu(u8 dev_ed, __dev32 x); - -#endif /*__GDM_ENDIAN_H__*/ diff --git a/drivers/staging/gdm724x/gdm_lte.c b/drivers/staging/gdm724x/gd= m_lte.c deleted file mode 100644 index eb754b231429..000000000000 --- a/drivers/staging/gdm724x/gdm_lte.c +++ /dev/null @@ -1,937 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved. */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "gdm_lte.h" -#include "netlink_k.h" -#include "hci.h" -#include "hci_packet.h" -#include "gdm_endian.h" - -/* - * Netlink protocol number - */ -#define NETLINK_LTE 30 - -/* - * Default MTU Size - */ -#define DEFAULT_MTU_SIZE 1500 - -#define IP_VERSION_4 4 -#define IP_VERSION_6 6 - -static struct { - int ref_cnt; - struct sock *sock; -} lte_event; - -static const struct device_type wwan_type =3D { - .name =3D "wwan", -}; - -static int gdm_lte_open(struct net_device *dev) -{ - netif_start_queue(dev); - return 0; -} - -static int gdm_lte_close(struct net_device *dev) -{ - netif_stop_queue(dev); - return 0; -} - -static int gdm_lte_set_config(struct net_device *dev, struct ifmap *map) -{ - if (dev->flags & IFF_UP) - return -EBUSY; - return 0; -} - -static void tx_complete(void *arg) -{ - struct nic *nic =3D arg; - - if (netif_queue_stopped(nic->netdev)) - netif_wake_queue(nic->netdev); -} - -static int gdm_lte_rx(struct sk_buff *skb, struct nic *nic, int nic_type) -{ - int ret, len; - - len =3D skb->len + ETH_HLEN; - ret =3D netif_rx(skb); - if (ret =3D=3D NET_RX_DROP) { - nic->stats.rx_dropped++; - } else { - nic->stats.rx_packets++; - nic->stats.rx_bytes +=3D len; - } - - return 0; -} - -static int gdm_lte_emulate_arp(struct sk_buff *skb_in, u32 nic_type) -{ - struct nic *nic =3D netdev_priv(skb_in->dev); - struct sk_buff *skb_out; - struct ethhdr eth; - struct vlan_ethhdr vlan_eth; - struct arphdr *arp_in; - struct arphdr *arp_out; - struct arpdata { - u8 ar_sha[ETH_ALEN]; - u8 ar_sip[4]; - u8 ar_tha[ETH_ALEN]; - u8 ar_tip[4]; - }; - struct arpdata *arp_data_in; - struct arpdata *arp_data_out; - u8 arp_temp[60]; - void *mac_header_data; - u32 mac_header_len; - - /* Check for skb->len, discard if empty */ - if (skb_in->len =3D=3D 0) - return -ENODATA; - - /* Format the mac header so that it can be put to skb */ - if (ntohs(((struct ethhdr *)skb_in->data)->h_proto) =3D=3D ETH_P_8021Q) { - memcpy(&vlan_eth, skb_in->data, sizeof(struct vlan_ethhdr)); - mac_header_data =3D &vlan_eth; - mac_header_len =3D VLAN_ETH_HLEN; - } else { - memcpy(ð, skb_in->data, sizeof(struct ethhdr)); - mac_header_data =3D ð - mac_header_len =3D ETH_HLEN; - } - - /* Get the pointer of the original request */ - arp_in =3D (struct arphdr *)(skb_in->data + mac_header_len); - arp_data_in =3D (struct arpdata *)(skb_in->data + mac_header_len + - sizeof(struct arphdr)); - - /* Get the pointer of the outgoing response */ - arp_out =3D (struct arphdr *)arp_temp; - arp_data_out =3D (struct arpdata *)(arp_temp + sizeof(struct arphdr)); - - /* Copy the arp header */ - memcpy(arp_out, arp_in, sizeof(struct arphdr)); - arp_out->ar_op =3D htons(ARPOP_REPLY); - - /* Copy the arp payload: based on 2 bytes of mac and fill the IP */ - arp_data_out->ar_sha[0] =3D arp_data_in->ar_sha[0]; - arp_data_out->ar_sha[1] =3D arp_data_in->ar_sha[1]; - memcpy(&arp_data_out->ar_sha[2], &arp_data_in->ar_tip[0], 4); - memcpy(&arp_data_out->ar_sip[0], &arp_data_in->ar_tip[0], 4); - memcpy(&arp_data_out->ar_tha[0], &arp_data_in->ar_sha[0], 6); - memcpy(&arp_data_out->ar_tip[0], &arp_data_in->ar_sip[0], 4); - - /* Fill the destination mac with source mac of the received packet */ - memcpy(mac_header_data, mac_header_data + ETH_ALEN, ETH_ALEN); - /* Fill the source mac with nic's source mac */ - memcpy(mac_header_data + ETH_ALEN, nic->src_mac_addr, ETH_ALEN); - - /* Alloc skb and reserve align */ - skb_out =3D dev_alloc_skb(skb_in->len); - if (!skb_out) - return -ENOMEM; - skb_reserve(skb_out, NET_IP_ALIGN); - - skb_put_data(skb_out, mac_header_data, mac_header_len); - skb_put_data(skb_out, arp_out, sizeof(struct arphdr)); - skb_put_data(skb_out, arp_data_out, sizeof(struct arpdata)); - - skb_out->protocol =3D ((struct ethhdr *)mac_header_data)->h_proto; - skb_out->dev =3D skb_in->dev; - skb_reset_mac_header(skb_out); - skb_pull(skb_out, ETH_HLEN); - - gdm_lte_rx(skb_out, nic, nic_type); - - return 0; -} - -static __sum16 icmp6_checksum(struct ipv6hdr *ipv6, u16 *ptr, int len) -{ - unsigned short *w; - __wsum sum =3D 0; - int i; - u16 pa; - - union { - struct { - u8 ph_src[16]; - u8 ph_dst[16]; - u32 ph_len; - u8 ph_zero[3]; - u8 ph_nxt; - } ph __packed; - u16 pa[20]; - } pseudo_header; - - memset(&pseudo_header, 0, sizeof(pseudo_header)); - memcpy(&pseudo_header.ph.ph_src, &ipv6->saddr.in6_u.u6_addr8, 16); - memcpy(&pseudo_header.ph.ph_dst, &ipv6->daddr.in6_u.u6_addr8, 16); - pseudo_header.ph.ph_len =3D be16_to_cpu(ipv6->payload_len); - pseudo_header.ph.ph_nxt =3D ipv6->nexthdr; - - for (i =3D 0; i < ARRAY_SIZE(pseudo_header.pa); i++) { - pa =3D pseudo_header.pa[i]; - sum =3D csum_add(sum, csum_unfold((__force __sum16)pa)); - } - - w =3D ptr; - while (len > 1) { - sum =3D csum_add(sum, csum_unfold((__force __sum16)*w++)); - len -=3D 2; - } - - return csum_fold(sum); -} - -static int gdm_lte_emulate_ndp(struct sk_buff *skb_in, u32 nic_type) -{ - struct nic *nic =3D netdev_priv(skb_in->dev); - struct sk_buff *skb_out; - struct ethhdr eth; - struct vlan_ethhdr vlan_eth; - struct neighbour_advertisement { - u8 target_address[16]; - u8 type; - u8 length; - u8 link_layer_address[6]; - }; - struct neighbour_advertisement na; - struct neighbour_solicitation { - u8 target_address[16]; - }; - struct neighbour_solicitation *ns; - struct ipv6hdr *ipv6_in; - struct ipv6hdr ipv6_out; - struct icmp6hdr *icmp6_in; - struct icmp6hdr icmp6_out; - - void *mac_header_data; - u32 mac_header_len; - - /* Format the mac header so that it can be put to skb */ - if (ntohs(((struct ethhdr *)skb_in->data)->h_proto) =3D=3D ETH_P_8021Q) { - memcpy(&vlan_eth, skb_in->data, sizeof(struct vlan_ethhdr)); - if (ntohs(vlan_eth.h_vlan_encapsulated_proto) !=3D ETH_P_IPV6) - return -EPROTONOSUPPORT; - mac_header_data =3D &vlan_eth; - mac_header_len =3D VLAN_ETH_HLEN; - } else { - memcpy(ð, skb_in->data, sizeof(struct ethhdr)); - if (ntohs(eth.h_proto) !=3D ETH_P_IPV6) - return -EPROTONOSUPPORT; - mac_header_data =3D ð - mac_header_len =3D ETH_HLEN; - } - - /* Check if this is IPv6 ICMP packet */ - ipv6_in =3D (struct ipv6hdr *)(skb_in->data + mac_header_len); - if (ipv6_in->version !=3D 6 || ipv6_in->nexthdr !=3D IPPROTO_ICMPV6) - return -EPROTONOSUPPORT; - - /* Check if this is NDP packet */ - icmp6_in =3D (struct icmp6hdr *)(skb_in->data + mac_header_len + - sizeof(struct ipv6hdr)); - if (icmp6_in->icmp6_type =3D=3D NDISC_ROUTER_SOLICITATION) { /* Check RS = */ - return -EPROTONOSUPPORT; - } else if (icmp6_in->icmp6_type =3D=3D NDISC_NEIGHBOUR_SOLICITATION) { - /* Check NS */ - u8 icmp_na[sizeof(struct icmp6hdr) + - sizeof(struct neighbour_advertisement)]; - u8 zero_addr8[16] =3D {0,}; - - if (memcmp(ipv6_in->saddr.in6_u.u6_addr8, zero_addr8, 16) =3D=3D 0) - /* Duplicate Address Detection: Source IP is all zero */ - return 0; - - icmp6_out.icmp6_type =3D NDISC_NEIGHBOUR_ADVERTISEMENT; - icmp6_out.icmp6_code =3D 0; - icmp6_out.icmp6_cksum =3D 0; - /* R=3D0, S=3D1, O=3D1 */ - icmp6_out.icmp6_dataun.un_data32[0] =3D htonl(0x60000000); - - ns =3D (struct neighbour_solicitation *) - (skb_in->data + mac_header_len + - sizeof(struct ipv6hdr) + sizeof(struct icmp6hdr)); - memcpy(&na.target_address, ns->target_address, 16); - na.type =3D 0x02; - na.length =3D 1; - na.link_layer_address[0] =3D 0x00; - na.link_layer_address[1] =3D 0x0a; - na.link_layer_address[2] =3D 0x3b; - na.link_layer_address[3] =3D 0xaf; - na.link_layer_address[4] =3D 0x63; - na.link_layer_address[5] =3D 0xc7; - - memcpy(&ipv6_out, ipv6_in, sizeof(struct ipv6hdr)); - memcpy(ipv6_out.saddr.in6_u.u6_addr8, &na.target_address, 16); - memcpy(ipv6_out.daddr.in6_u.u6_addr8, - ipv6_in->saddr.in6_u.u6_addr8, 16); - ipv6_out.payload_len =3D htons(sizeof(struct icmp6hdr) + - sizeof(struct neighbour_advertisement)); - - memcpy(icmp_na, &icmp6_out, sizeof(struct icmp6hdr)); - memcpy(icmp_na + sizeof(struct icmp6hdr), &na, - sizeof(struct neighbour_advertisement)); - - icmp6_out.icmp6_cksum =3D icmp6_checksum(&ipv6_out, - (u16 *)icmp_na, - sizeof(icmp_na)); - } else { - return -EINVAL; - } - - /* Fill the destination mac with source mac of the received packet */ - memcpy(mac_header_data, mac_header_data + ETH_ALEN, ETH_ALEN); - /* Fill the source mac with nic's source mac */ - memcpy(mac_header_data + ETH_ALEN, nic->src_mac_addr, ETH_ALEN); - - /* Alloc skb and reserve align */ - skb_out =3D dev_alloc_skb(skb_in->len); - if (!skb_out) - return -ENOMEM; - skb_reserve(skb_out, NET_IP_ALIGN); - - skb_put_data(skb_out, mac_header_data, mac_header_len); - skb_put_data(skb_out, &ipv6_out, sizeof(struct ipv6hdr)); - skb_put_data(skb_out, &icmp6_out, sizeof(struct icmp6hdr)); - skb_put_data(skb_out, &na, sizeof(struct neighbour_advertisement)); - - skb_out->protocol =3D ((struct ethhdr *)mac_header_data)->h_proto; - skb_out->dev =3D skb_in->dev; - skb_reset_mac_header(skb_out); - skb_pull(skb_out, ETH_HLEN); - - gdm_lte_rx(skb_out, nic, nic_type); - - return 0; -} - -static s32 gdm_lte_tx_nic_type(struct net_device *dev, struct sk_buff *skb) -{ - struct nic *nic =3D netdev_priv(dev); - struct ethhdr *eth; - struct vlan_ethhdr *vlan_eth; - struct iphdr *ip; - struct ipv6hdr *ipv6; - int mac_proto; - void *network_data; - u32 nic_type; - - /* NIC TYPE is based on the nic_id of this net_device */ - nic_type =3D 0x00000010 | nic->nic_id; - - /* Get ethernet protocol */ - eth =3D (struct ethhdr *)skb->data; - if (ntohs(eth->h_proto) =3D=3D ETH_P_8021Q) { - vlan_eth =3D skb_vlan_eth_hdr(skb); - mac_proto =3D ntohs(vlan_eth->h_vlan_encapsulated_proto); - network_data =3D skb->data + VLAN_ETH_HLEN; - nic_type |=3D NIC_TYPE_F_VLAN; - } else { - mac_proto =3D ntohs(eth->h_proto); - network_data =3D skb->data + ETH_HLEN; - } - - /* Process packet for nic type */ - switch (mac_proto) { - case ETH_P_ARP: - nic_type |=3D NIC_TYPE_ARP; - break; - case ETH_P_IP: - nic_type |=3D NIC_TYPE_F_IPV4; - ip =3D network_data; - - /* Check DHCPv4 */ - if (ip->protocol =3D=3D IPPROTO_UDP) { - struct udphdr *udp =3D - network_data + sizeof(struct iphdr); - if (ntohs(udp->dest) =3D=3D 67 || ntohs(udp->dest) =3D=3D 68) - nic_type |=3D NIC_TYPE_F_DHCP; - } - break; - case ETH_P_IPV6: - nic_type |=3D NIC_TYPE_F_IPV6; - ipv6 =3D network_data; - - if (ipv6->nexthdr =3D=3D IPPROTO_ICMPV6) /* Check NDP request */ { - struct icmp6hdr *icmp6 =3D - network_data + sizeof(struct ipv6hdr); - if (icmp6->icmp6_type =3D=3D NDISC_NEIGHBOUR_SOLICITATION) - nic_type |=3D NIC_TYPE_ICMPV6; - } else if (ipv6->nexthdr =3D=3D IPPROTO_UDP) /* Check DHCPv6 */ { - struct udphdr *udp =3D - network_data + sizeof(struct ipv6hdr); - if (ntohs(udp->dest) =3D=3D 546 || ntohs(udp->dest) =3D=3D 547) - nic_type |=3D NIC_TYPE_F_DHCP; - } - break; - default: - break; - } - - return nic_type; -} - -static netdev_tx_t gdm_lte_tx(struct sk_buff *skb, struct net_device *dev) -{ - struct nic *nic =3D netdev_priv(dev); - u32 nic_type; - void *data_buf; - int data_len; - int idx; - int ret =3D 0; - - nic_type =3D gdm_lte_tx_nic_type(dev, skb); - if (nic_type =3D=3D 0) { - netdev_err(dev, "tx - invalid nic_type\n"); - return -EMEDIUMTYPE; - } - - if (nic_type & NIC_TYPE_ARP) { - if (gdm_lte_emulate_arp(skb, nic_type) =3D=3D 0) { - dev_kfree_skb(skb); - return 0; - } - } - - if (nic_type & NIC_TYPE_ICMPV6) { - if (gdm_lte_emulate_ndp(skb, nic_type) =3D=3D 0) { - dev_kfree_skb(skb); - return 0; - } - } - - /* - * Need byte shift (that is, remove VLAN tag) if there is one - * For the case of ARP, this breaks the offset as vlan_ethhdr+4 - * is treated as ethhdr However, it shouldn't be a problem as - * the response starts from arp_hdr and ethhdr is created by this - * driver based on the NIC mac - */ - if (nic_type & NIC_TYPE_F_VLAN) { - struct vlan_ethhdr *vlan_eth =3D skb_vlan_eth_hdr(skb); - - nic->vlan_id =3D ntohs(vlan_eth->h_vlan_TCI) & VLAN_VID_MASK; - data_buf =3D skb->data + (VLAN_ETH_HLEN - ETH_HLEN); - data_len =3D skb->len - (VLAN_ETH_HLEN - ETH_HLEN); - } else { - nic->vlan_id =3D 0; - data_buf =3D skb->data; - data_len =3D skb->len; - } - - /* If it is a ICMPV6 packet, clear all the other bits : - * for backward compatibility with the firmware - */ - if (nic_type & NIC_TYPE_ICMPV6) - nic_type =3D NIC_TYPE_ICMPV6; - - /* If it is not a dhcp packet, clear all the flag bits : - * original NIC, otherwise the special flag (IPVX | DHCP) - */ - if (!(nic_type & NIC_TYPE_F_DHCP)) - nic_type &=3D NIC_TYPE_MASK; - - ret =3D sscanf(dev->name, "lte%d", &idx); - if (ret !=3D 1) { - dev_kfree_skb(skb); - return -EINVAL; - } - - ret =3D nic->phy_dev->send_sdu_func(nic->phy_dev->priv_dev, - data_buf, data_len, - nic->pdn_table.dft_eps_id, 0, - tx_complete, nic, idx, - nic_type); - - if (ret =3D=3D TX_NO_BUFFER || ret =3D=3D TX_NO_SPC) { - netif_stop_queue(dev); - if (ret =3D=3D TX_NO_BUFFER) - ret =3D 0; - else - ret =3D -ENOSPC; - } else if (ret =3D=3D TX_NO_DEV) { - ret =3D -ENODEV; - } - - /* Updates tx stats */ - if (ret) { - nic->stats.tx_dropped++; - } else { - nic->stats.tx_packets++; - nic->stats.tx_bytes +=3D data_len; - } - dev_kfree_skb(skb); - - return 0; -} - -static struct net_device_stats *gdm_lte_stats(struct net_device *dev) -{ - struct nic *nic =3D netdev_priv(dev); - - return &nic->stats; -} - -static int gdm_lte_event_send(struct net_device *dev, char *buf, int len) -{ - struct phy_dev *phy_dev =3D ((struct nic *)netdev_priv(dev))->phy_dev; - struct hci_packet *hci =3D (struct hci_packet *)buf; - int length; - int idx; - int ret; - - ret =3D sscanf(dev->name, "lte%d", &idx); - if (ret !=3D 1) - return -EINVAL; - - length =3D gdm_dev16_to_cpu(phy_dev->get_endian(phy_dev->priv_dev), - hci->len) + HCI_HEADER_SIZE; - return netlink_send(lte_event.sock, idx, 0, buf, length, dev); -} - -static void gdm_lte_event_rcv(struct net_device *dev, u16 type, - void *msg, int len) -{ - struct nic *nic =3D netdev_priv(dev); - - nic->phy_dev->send_hci_func(nic->phy_dev->priv_dev, msg, len, NULL, - NULL); -} - -int gdm_lte_event_init(void) -{ - if (lte_event.ref_cnt =3D=3D 0) - lte_event.sock =3D netlink_init(NETLINK_LTE, gdm_lte_event_rcv); - - if (lte_event.sock) { - lte_event.ref_cnt++; - return 0; - } - - pr_err("event init failed\n"); - return -ENODATA; -} - -void gdm_lte_event_exit(void) -{ - if (lte_event.sock && --lte_event.ref_cnt =3D=3D 0) { - sock_release(lte_event.sock->sk_socket); - lte_event.sock =3D NULL; - } -} - -static int find_dev_index(u32 nic_type) -{ - u8 index; - - index =3D (u8)(nic_type & 0x0000000f); - if (index >=3D MAX_NIC_TYPE) - return -EINVAL; - - return index; -} - -static void gdm_lte_netif_rx(struct net_device *dev, char *buf, - int len, int flagged_nic_type) -{ - u32 nic_type; - struct nic *nic; - struct sk_buff *skb; - struct ethhdr eth; - struct vlan_ethhdr vlan_eth; - void *mac_header_data; - u32 mac_header_len; - char ip_version =3D 0; - - nic_type =3D flagged_nic_type & NIC_TYPE_MASK; - nic =3D netdev_priv(dev); - - if (flagged_nic_type & NIC_TYPE_F_DHCP) { - /* Change the destination mac address - * with the one requested the IP - */ - if (flagged_nic_type & NIC_TYPE_F_IPV4) { - struct dhcp_packet { - u8 op; /* BOOTREQUEST or BOOTREPLY */ - u8 htype; /* hardware address type. - * 1 =3D 10mb ethernet - */ - u8 hlen; /* hardware address length */ - u8 hops; /* used by relay agents only */ - u32 xid; /* unique id */ - u16 secs; /* elapsed since client began - * acquisition/renewal - */ - u16 flags; /* only one flag so far: */ - #define BROADCAST_FLAG 0x8000 - /* "I need broadcast replies" */ - u32 ciaddr; /* client IP (if client is in - * BOUND, RENEW or REBINDING state) - */ - u32 yiaddr; /* 'your' (client) IP address */ - /* IP address of next server to use in - * bootstrap, returned in DHCPOFFER, - * DHCPACK by server - */ - u32 siaddr_nip; - u32 gateway_nip; /* relay agent IP address */ - u8 chaddr[16]; /* link-layer client hardware - * address (MAC) - */ - u8 sname[64]; /* server host name (ASCIZ) */ - u8 file[128]; /* boot file name (ASCIZ) */ - u32 cookie; /* fixed first four option - * bytes (99,130,83,99 dec) - */ - } __packed; - int offset =3D sizeof(struct iphdr) + - sizeof(struct udphdr) + - offsetof(struct dhcp_packet, chaddr); - if (offset + ETH_ALEN > len) - return; - ether_addr_copy(nic->dest_mac_addr, buf + offset); - } - } - - if (nic->vlan_id > 0) { - mac_header_data =3D (void *)&vlan_eth; - mac_header_len =3D VLAN_ETH_HLEN; - } else { - mac_header_data =3D (void *)ð - mac_header_len =3D ETH_HLEN; - } - - /* Format the data so that it can be put to skb */ - ether_addr_copy(mac_header_data, nic->dest_mac_addr); - memcpy(mac_header_data + ETH_ALEN, nic->src_mac_addr, ETH_ALEN); - - vlan_eth.h_vlan_TCI =3D htons(nic->vlan_id); - vlan_eth.h_vlan_proto =3D htons(ETH_P_8021Q); - - if (nic_type =3D=3D NIC_TYPE_ARP) { - /* Should be response: Only happens because - * there was a request from the host - */ - eth.h_proto =3D htons(ETH_P_ARP); - vlan_eth.h_vlan_encapsulated_proto =3D htons(ETH_P_ARP); - } else { - ip_version =3D buf[0] >> 4; - if (ip_version =3D=3D IP_VERSION_4) { - eth.h_proto =3D htons(ETH_P_IP); - vlan_eth.h_vlan_encapsulated_proto =3D htons(ETH_P_IP); - } else if (ip_version =3D=3D IP_VERSION_6) { - eth.h_proto =3D htons(ETH_P_IPV6); - vlan_eth.h_vlan_encapsulated_proto =3D htons(ETH_P_IPV6); - } else { - netdev_err(dev, "Unknown IP version %d\n", ip_version); - return; - } - } - - /* Alloc skb and reserve align */ - skb =3D dev_alloc_skb(len + mac_header_len + NET_IP_ALIGN); - if (!skb) - return; - skb_reserve(skb, NET_IP_ALIGN); - - skb_put_data(skb, mac_header_data, mac_header_len); - skb_put_data(skb, buf, len); - - skb->protocol =3D ((struct ethhdr *)mac_header_data)->h_proto; - skb->dev =3D dev; - skb_reset_mac_header(skb); - skb_pull(skb, ETH_HLEN); - - gdm_lte_rx(skb, nic, nic_type); -} - -static void gdm_lte_multi_sdu_pkt(struct phy_dev *phy_dev, char *buf, int = len) -{ - struct net_device *dev; - struct multi_sdu *multi_sdu =3D (struct multi_sdu *)buf; - struct sdu *sdu =3D NULL; - u8 endian =3D phy_dev->get_endian(phy_dev->priv_dev); - u8 *data =3D (u8 *)multi_sdu->data; - int copied; - u16 i =3D 0; - u16 num_packet; - u16 hci_len; - u16 cmd_evt; - u32 nic_type; - int index; - - num_packet =3D gdm_dev16_to_cpu(endian, multi_sdu->num_packet); - - for (i =3D 0; i < num_packet; i++) { - copied =3D data - multi_sdu->data; - if (len < copied + sizeof(*sdu)) { - pr_err("rx prevent buffer overflow"); - return; - } - - sdu =3D (struct sdu *)data; - - cmd_evt =3D gdm_dev16_to_cpu(endian, sdu->cmd_evt); - hci_len =3D gdm_dev16_to_cpu(endian, sdu->len); - nic_type =3D gdm_dev32_to_cpu(endian, sdu->nic_type); - - if (cmd_evt !=3D LTE_RX_SDU) { - pr_err("rx sdu wrong hci %04x\n", cmd_evt); - return; - } - if (hci_len < 12 || - len < copied + sizeof(*sdu) + (hci_len - 12)) { - pr_err("rx sdu invalid len %d\n", hci_len); - return; - } - - index =3D find_dev_index(nic_type); - if (index < 0) { - pr_err("rx sdu invalid nic_type :%x\n", nic_type); - return; - } - dev =3D phy_dev->dev[index]; - gdm_lte_netif_rx(dev, (char *)sdu->data, - (int)(hci_len - 12), nic_type); - - data +=3D ((hci_len + 3) & 0xfffc) + HCI_HEADER_SIZE; - } -} - -static void gdm_lte_pdn_table(struct net_device *dev, char *buf, int len) -{ - struct nic *nic =3D netdev_priv(dev); - struct hci_pdn_table_ind *pdn_table =3D (struct hci_pdn_table_ind *)buf; - u8 ed =3D nic->phy_dev->get_endian(nic->phy_dev->priv_dev); - - if (!pdn_table->activate) { - memset(&nic->pdn_table, 0x00, sizeof(struct pdn_table)); - netdev_info(dev, "pdn deactivated\n"); - - return; - } - - nic->pdn_table.activate =3D pdn_table->activate; - nic->pdn_table.dft_eps_id =3D gdm_dev32_to_cpu(ed, pdn_table->dft_eps_id); - nic->pdn_table.nic_type =3D gdm_dev32_to_cpu(ed, pdn_table->nic_type); - - netdev_info(dev, "pdn activated, nic_type=3D0x%x\n", - nic->pdn_table.nic_type); -} - -static int gdm_lte_receive_pkt(struct phy_dev *phy_dev, char *buf, int len) -{ - struct hci_packet *hci =3D (struct hci_packet *)buf; - struct hci_pdn_table_ind *pdn_table =3D (struct hci_pdn_table_ind *)buf; - struct sdu *sdu; - struct net_device *dev; - u8 endian =3D phy_dev->get_endian(phy_dev->priv_dev); - int ret =3D 0; - u16 cmd_evt; - u32 nic_type; - int index; - - if (!len) - return ret; - - cmd_evt =3D gdm_dev16_to_cpu(endian, hci->cmd_evt); - - dev =3D phy_dev->dev[0]; - if (!dev) - return 0; - - switch (cmd_evt) { - case LTE_RX_SDU: - sdu =3D (struct sdu *)hci->data; - nic_type =3D gdm_dev32_to_cpu(endian, sdu->nic_type); - index =3D find_dev_index(nic_type); - if (index < 0) - return index; - dev =3D phy_dev->dev[index]; - gdm_lte_netif_rx(dev, hci->data, len, nic_type); - break; - case LTE_RX_MULTI_SDU: - gdm_lte_multi_sdu_pkt(phy_dev, buf, len); - break; - case LTE_LINK_ON_OFF_INDICATION: - netdev_info(dev, "link %s\n", - ((struct hci_connect_ind *)buf)->connect - ? "on" : "off"); - break; - case LTE_PDN_TABLE_IND: - pdn_table =3D (struct hci_pdn_table_ind *)buf; - nic_type =3D gdm_dev32_to_cpu(endian, pdn_table->nic_type); - index =3D find_dev_index(nic_type); - if (index < 0) - return index; - dev =3D phy_dev->dev[index]; - gdm_lte_pdn_table(dev, buf, len); - fallthrough; - default: - ret =3D gdm_lte_event_send(dev, buf, len); - break; - } - - return ret; -} - -static int rx_complete(void *arg, void *data, int len, int context) -{ - struct phy_dev *phy_dev =3D arg; - - return gdm_lte_receive_pkt(phy_dev, data, len); -} - -void start_rx_proc(struct phy_dev *phy_dev) -{ - int i; - - for (i =3D 0; i < MAX_RX_SUBMIT_COUNT; i++) - phy_dev->rcv_func(phy_dev->priv_dev, - rx_complete, phy_dev, USB_COMPLETE); -} - -static const struct net_device_ops gdm_netdev_ops =3D { - .ndo_open =3D gdm_lte_open, - .ndo_stop =3D gdm_lte_close, - .ndo_set_config =3D gdm_lte_set_config, - .ndo_start_xmit =3D gdm_lte_tx, - .ndo_get_stats =3D gdm_lte_stats, -}; - -static u8 gdm_lte_macaddr[ETH_ALEN] =3D {0x00, 0x0a, 0x3b, 0x00, 0x00, 0x0= 0}; - -static void form_mac_address(u8 *dev_addr, u8 *nic_src, u8 *nic_dest, - u8 *mac_address, u8 index) -{ - /* Form the dev_addr */ - if (!mac_address) - ether_addr_copy(dev_addr, gdm_lte_macaddr); - else - ether_addr_copy(dev_addr, mac_address); - - /* The last byte of the mac address - * should be less than or equal to 0xFC - */ - dev_addr[ETH_ALEN - 1] +=3D index; - - /* Create random nic src and copy the first - * 3 bytes to be the same as dev_addr - */ - eth_random_addr(nic_src); - memcpy(nic_src, dev_addr, 3); - - /* Copy the nic_dest from dev_addr*/ - ether_addr_copy(nic_dest, dev_addr); -} - -static void validate_mac_address(u8 *mac_address) -{ - /* if zero address or multicast bit set, restore the default value */ - if (is_zero_ether_addr(mac_address) || (mac_address[0] & 0x01)) { - pr_err("MAC invalid, restoring default\n"); - memcpy(mac_address, gdm_lte_macaddr, 6); - } -} - -int register_lte_device(struct phy_dev *phy_dev, - struct device *dev, u8 *mac_address) -{ - struct nic *nic; - struct net_device *net; - char pdn_dev_name[16]; - u8 addr[ETH_ALEN]; - int ret =3D 0; - u8 index; - - validate_mac_address(mac_address); - - for (index =3D 0; index < MAX_NIC_TYPE; index++) { - /* Create device name lteXpdnX */ - sprintf(pdn_dev_name, "lte%%dpdn%d", index); - - /* Allocate netdev */ - net =3D alloc_netdev(sizeof(struct nic), pdn_dev_name, - NET_NAME_UNKNOWN, ether_setup); - if (!net) { - ret =3D -ENOMEM; - goto err; - } - net->netdev_ops =3D &gdm_netdev_ops; - net->flags &=3D ~IFF_MULTICAST; - net->mtu =3D DEFAULT_MTU_SIZE; - - nic =3D netdev_priv(net); - memset(nic, 0, sizeof(struct nic)); - nic->netdev =3D net; - nic->phy_dev =3D phy_dev; - nic->nic_id =3D index; - - form_mac_address(addr, - nic->src_mac_addr, - nic->dest_mac_addr, - mac_address, - index); - eth_hw_addr_set(net, addr); - - SET_NETDEV_DEV(net, dev); - SET_NETDEV_DEVTYPE(net, &wwan_type); - - ret =3D register_netdev(net); - if (ret) - goto err; - - netif_carrier_on(net); - - phy_dev->dev[index] =3D net; - } - - return 0; - -err: - unregister_lte_device(phy_dev); - - return ret; -} - -void unregister_lte_device(struct phy_dev *phy_dev) -{ - struct net_device *net; - int index; - - for (index =3D 0; index < MAX_NIC_TYPE; index++) { - net =3D phy_dev->dev[index]; - if (!net) - continue; - - unregister_netdev(net); - free_netdev(net); - } -} diff --git a/drivers/staging/gdm724x/gdm_lte.h b/drivers/staging/gdm724x/gd= m_lte.h deleted file mode 100644 index f2143a6e0e99..000000000000 --- a/drivers/staging/gdm724x/gdm_lte.h +++ /dev/null @@ -1,71 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved. */ - -#ifndef _GDM_LTE_H_ -#define _GDM_LTE_H_ - -#include -#include - -#include "gdm_endian.h" - -#define MAX_NIC_TYPE 4 -#define MAX_RX_SUBMIT_COUNT 3 -#define DRIVER_VERSION "3.7.17.0" - -enum TX_ERROR_CODE { - TX_NO_ERROR =3D 0, - TX_NO_DEV, - TX_NO_SPC, - TX_NO_BUFFER, -}; - -enum CALLBACK_CONTEXT { - KERNEL_THREAD =3D 0, - USB_COMPLETE, -}; - -struct pdn_table { - u8 activate; - u32 dft_eps_id; - u32 nic_type; -} __packed; - -struct nic; - -struct phy_dev { - void *priv_dev; - struct net_device *dev[MAX_NIC_TYPE]; - int (*send_hci_func)(void *priv_dev, void *data, int len, - void (*cb)(void *cb_data), void *cb_data); - int (*send_sdu_func)(void *priv_dev, void *data, int len, - unsigned int dft_eps_id, unsigned int eps_id, - void (*cb)(void *cb_data), void *cb_data, - int dev_idx, int nic_type); - int (*rcv_func)(void *priv_dev, - int (*cb)(void *cb_data, void *data, int len, - int context), - void *cb_data, int context); - u8 (*get_endian)(void *priv_dev); -}; - -struct nic { - struct net_device *netdev; - struct phy_dev *phy_dev; - struct net_device_stats stats; - struct pdn_table pdn_table; - u8 dest_mac_addr[ETH_ALEN]; - u8 src_mac_addr[ETH_ALEN]; - u32 nic_id; - u16 vlan_id; -}; - -int gdm_lte_event_init(void); -void gdm_lte_event_exit(void); - -void start_rx_proc(struct phy_dev *phy_dev); -int register_lte_device(struct phy_dev *phy_dev, struct device *dev, - u8 *mac_address); -void unregister_lte_device(struct phy_dev *phy_dev); - -#endif /* _GDM_LTE_H_ */ diff --git a/drivers/staging/gdm724x/gdm_mux.c b/drivers/staging/gdm724x/gd= m_mux.c deleted file mode 100644 index 82302c6266eb..000000000000 --- a/drivers/staging/gdm724x/gdm_mux.c +++ /dev/null @@ -1,668 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved. */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "gdm_mux.h" - -static u16 packet_type_for_tty_index[TTY_MAX_COUNT] =3D {0xF011, 0xF010}; - -#define USB_DEVICE_CDC_DATA(vid, pid) \ - .match_flags =3D \ - USB_DEVICE_ID_MATCH_DEVICE |\ - USB_DEVICE_ID_MATCH_INT_CLASS |\ - USB_DEVICE_ID_MATCH_INT_SUBCLASS,\ - .idVendor =3D vid,\ - .idProduct =3D pid,\ - .bInterfaceClass =3D USB_CLASS_COMM,\ - .bInterfaceSubClass =3D USB_CDC_SUBCLASS_ACM - -static const struct usb_device_id id_table[] =3D { - { USB_DEVICE_CDC_DATA(0x1076, 0x8000) }, /* GCT GDM7240 */ - { USB_DEVICE_CDC_DATA(0x1076, 0x8f00) }, /* GCT GDM7243 */ - { USB_DEVICE_CDC_DATA(0x1076, 0x9000) }, /* GCT GDM7243 */ - { USB_DEVICE_CDC_DATA(0x1d74, 0x2300) }, /* LGIT Phoenix */ - {} -}; - -MODULE_DEVICE_TABLE(usb, id_table); - -static int packet_type_to_tty_index(u16 packet_type) -{ - int i; - - for (i =3D 0; i < TTY_MAX_COUNT; i++) { - if (packet_type_for_tty_index[i] =3D=3D packet_type) - return i; - } - - return -ENOENT; -} - -static struct mux_tx *alloc_mux_tx(int len) -{ - struct mux_tx *t; - - t =3D kzalloc(sizeof(*t), GFP_ATOMIC); - if (!t) - return NULL; - - t->urb =3D usb_alloc_urb(0, GFP_ATOMIC); - t->buf =3D kmalloc(MUX_TX_MAX_SIZE, GFP_ATOMIC); - if (!t->urb || !t->buf) { - usb_free_urb(t->urb); - kfree(t->buf); - kfree(t); - return NULL; - } - - return t; -} - -static void free_mux_tx(struct mux_tx *t) -{ - if (t) { - usb_free_urb(t->urb); - kfree(t->buf); - kfree(t); - } -} - -static struct mux_rx *alloc_mux_rx(void) -{ - struct mux_rx *r; - - r =3D kzalloc(sizeof(*r), GFP_KERNEL); - if (!r) - return NULL; - - r->urb =3D usb_alloc_urb(0, GFP_KERNEL); - r->buf =3D kmalloc(MUX_RX_MAX_SIZE, GFP_KERNEL); - if (!r->urb || !r->buf) { - usb_free_urb(r->urb); - kfree(r->buf); - kfree(r); - return NULL; - } - - return r; -} - -static void free_mux_rx(struct mux_rx *r) -{ - if (r) { - usb_free_urb(r->urb); - kfree(r->buf); - kfree(r); - } -} - -static struct mux_rx *get_rx_struct(struct rx_cxt *rx) -{ - struct mux_rx *r; - unsigned long flags; - - spin_lock_irqsave(&rx->free_list_lock, flags); - - if (list_empty(&rx->rx_free_list)) { - spin_unlock_irqrestore(&rx->free_list_lock, flags); - return NULL; - } - - r =3D list_entry(rx->rx_free_list.prev, struct mux_rx, free_list); - list_del(&r->free_list); - - spin_unlock_irqrestore(&rx->free_list_lock, flags); - - return r; -} - -static void put_rx_struct(struct rx_cxt *rx, struct mux_rx *r) -{ - unsigned long flags; - - spin_lock_irqsave(&rx->free_list_lock, flags); - list_add_tail(&r->free_list, &rx->rx_free_list); - spin_unlock_irqrestore(&rx->free_list_lock, flags); -} - -static int up_to_host(struct mux_rx *r) -{ - struct mux_dev *mux_dev =3D r->mux_dev; - struct mux_pkt_header *mux_header; - unsigned int start_flag; - unsigned int payload_size; - unsigned short packet_type; - int total_len; - u32 packet_size_sum =3D r->offset; - int index; - int ret =3D TO_HOST_INVALID_PACKET; - int len =3D r->len; - - while (1) { - mux_header =3D (struct mux_pkt_header *)(r->buf + - packet_size_sum); - start_flag =3D __le32_to_cpu(mux_header->start_flag); - payload_size =3D __le32_to_cpu(mux_header->payload_size); - packet_type =3D __le16_to_cpu(mux_header->packet_type); - - if (start_flag !=3D START_FLAG) { - pr_err("invalid START_FLAG %x\n", start_flag); - break; - } - - total_len =3D ALIGN(MUX_HEADER_SIZE + payload_size, 4); - - if (len - packet_size_sum < total_len) { - pr_err("invalid payload : %d %d %04x\n", - payload_size, len, packet_type); - break; - } - - index =3D packet_type_to_tty_index(packet_type); - if (index < 0) { - pr_err("invalid index %d\n", index); - break; - } - - ret =3D r->callback(mux_header->data, - payload_size, - index, - mux_dev->tty_dev, - RECV_PACKET_PROCESS_CONTINUE - ); - if (ret =3D=3D TO_HOST_BUFFER_REQUEST_FAIL) { - r->offset +=3D packet_size_sum; - break; - } - - packet_size_sum +=3D total_len; - if (len - packet_size_sum <=3D MUX_HEADER_SIZE + 2) { - ret =3D r->callback(NULL, - 0, - index, - mux_dev->tty_dev, - RECV_PACKET_PROCESS_COMPLETE - ); - break; - } - } - - return ret; -} - -static void do_rx(struct work_struct *work) -{ - struct mux_dev *mux_dev =3D - container_of(work, struct mux_dev, work_rx.work); - struct mux_rx *r; - struct rx_cxt *rx =3D &mux_dev->rx; - unsigned long flags; - int ret =3D 0; - - while (1) { - spin_lock_irqsave(&rx->to_host_lock, flags); - if (list_empty(&rx->to_host_list)) { - spin_unlock_irqrestore(&rx->to_host_lock, flags); - break; - } - r =3D list_entry(rx->to_host_list.next, struct mux_rx, - to_host_list); - list_del(&r->to_host_list); - spin_unlock_irqrestore(&rx->to_host_lock, flags); - - ret =3D up_to_host(r); - if (ret =3D=3D TO_HOST_BUFFER_REQUEST_FAIL) - pr_err("failed to send mux data to host\n"); - else - put_rx_struct(rx, r); - } -} - -static void remove_rx_submit_list(struct mux_rx *r, struct rx_cxt *rx) -{ - unsigned long flags; - struct mux_rx *r_remove, *r_remove_next; - - spin_lock_irqsave(&rx->submit_list_lock, flags); - list_for_each_entry_safe(r_remove, r_remove_next, &rx->rx_submit_list, - rx_submit_list) { - if (r =3D=3D r_remove) - list_del(&r->rx_submit_list); - } - spin_unlock_irqrestore(&rx->submit_list_lock, flags); -} - -static void gdm_mux_rcv_complete(struct urb *urb) -{ - struct mux_rx *r =3D urb->context; - struct mux_dev *mux_dev =3D r->mux_dev; - struct rx_cxt *rx =3D &mux_dev->rx; - unsigned long flags; - - remove_rx_submit_list(r, rx); - - if (urb->status) { - if (mux_dev->usb_state =3D=3D PM_NORMAL) - dev_err(&urb->dev->dev, "%s: urb status error %d\n", - __func__, urb->status); - put_rx_struct(rx, r); - } else { - r->len =3D r->urb->actual_length; - spin_lock_irqsave(&rx->to_host_lock, flags); - list_add_tail(&r->to_host_list, &rx->to_host_list); - schedule_work(&mux_dev->work_rx.work); - spin_unlock_irqrestore(&rx->to_host_lock, flags); - } -} - -static int gdm_mux_recv(void *priv_dev, - int (*cb)(void *data, int len, int tty_index, - struct tty_dev *tty_dev, int complete)) -{ - struct mux_dev *mux_dev =3D priv_dev; - struct usb_device *usbdev =3D mux_dev->usbdev; - struct mux_rx *r; - struct rx_cxt *rx =3D &mux_dev->rx; - unsigned long flags; - int ret; - - if (!usbdev) { - pr_err("device is disconnected\n"); - return -ENODEV; - } - - r =3D get_rx_struct(rx); - if (!r) { - pr_err("get_rx_struct fail\n"); - return -ENOMEM; - } - - r->offset =3D 0; - r->mux_dev =3D (void *)mux_dev; - r->callback =3D cb; - mux_dev->rx_cb =3D cb; - - usb_fill_bulk_urb(r->urb, - usbdev, - usb_rcvbulkpipe(usbdev, 0x86), - r->buf, - MUX_RX_MAX_SIZE, - gdm_mux_rcv_complete, - r); - - spin_lock_irqsave(&rx->submit_list_lock, flags); - list_add_tail(&r->rx_submit_list, &rx->rx_submit_list); - spin_unlock_irqrestore(&rx->submit_list_lock, flags); - - ret =3D usb_submit_urb(r->urb, GFP_KERNEL); - - if (ret) { - spin_lock_irqsave(&rx->submit_list_lock, flags); - list_del(&r->rx_submit_list); - spin_unlock_irqrestore(&rx->submit_list_lock, flags); - - put_rx_struct(rx, r); - - pr_err("usb_submit_urb ret=3D%d\n", ret); - } - - usb_mark_last_busy(usbdev); - - return ret; -} - -static void gdm_mux_send_complete(struct urb *urb) -{ - struct mux_tx *t =3D urb->context; - - if (urb->status =3D=3D -ECONNRESET) { - dev_info(&urb->dev->dev, "CONNRESET\n"); - free_mux_tx(t); - return; - } - - if (t->callback) - t->callback(t->cb_data); - - free_mux_tx(t); -} - -static int gdm_mux_send(void *priv_dev, void *data, int len, int tty_index, - void (*cb)(void *data), void *cb_data) -{ - struct mux_dev *mux_dev =3D priv_dev; - struct usb_device *usbdev =3D mux_dev->usbdev; - struct mux_pkt_header *mux_header; - struct mux_tx *t =3D NULL; - static u32 seq_num =3D 1; - int total_len; - int ret; - unsigned long flags; - - if (mux_dev->usb_state =3D=3D PM_SUSPEND) { - ret =3D usb_autopm_get_interface(mux_dev->intf); - if (!ret) - usb_autopm_put_interface(mux_dev->intf); - } - - spin_lock_irqsave(&mux_dev->write_lock, flags); - - total_len =3D ALIGN(MUX_HEADER_SIZE + len, 4); - - t =3D alloc_mux_tx(total_len); - if (!t) { - pr_err("alloc_mux_tx fail\n"); - spin_unlock_irqrestore(&mux_dev->write_lock, flags); - return -ENOMEM; - } - - mux_header =3D (struct mux_pkt_header *)t->buf; - mux_header->start_flag =3D __cpu_to_le32(START_FLAG); - mux_header->seq_num =3D __cpu_to_le32(seq_num++); - mux_header->payload_size =3D __cpu_to_le32((u32)len); - mux_header->packet_type =3D __cpu_to_le16(packet_type_for_tty_index[tty_i= ndex]); - - memcpy(t->buf + MUX_HEADER_SIZE, data, len); - memset(t->buf + MUX_HEADER_SIZE + len, 0, - total_len - MUX_HEADER_SIZE - len); - - t->len =3D total_len; - t->callback =3D cb; - t->cb_data =3D cb_data; - - usb_fill_bulk_urb(t->urb, - usbdev, - usb_sndbulkpipe(usbdev, 5), - t->buf, - total_len, - gdm_mux_send_complete, - t); - - ret =3D usb_submit_urb(t->urb, GFP_ATOMIC); - - spin_unlock_irqrestore(&mux_dev->write_lock, flags); - - if (ret) - pr_err("usb_submit_urb Error: %d\n", ret); - - usb_mark_last_busy(usbdev); - - return ret; -} - -static int gdm_mux_send_control(void *priv_dev, int request, int value, - void *buf, int len) -{ - struct mux_dev *mux_dev =3D priv_dev; - struct usb_device *usbdev =3D mux_dev->usbdev; - int ret; - - ret =3D usb_control_msg(usbdev, - usb_sndctrlpipe(usbdev, 0), - request, - USB_RT_ACM, - value, - 2, - buf, - len, - 5000 - ); - - if (ret < 0) - pr_err("usb_control_msg error: %d\n", ret); - - return min(ret, 0); -} - -static void release_usb(struct mux_dev *mux_dev) -{ - struct rx_cxt *rx =3D &mux_dev->rx; - struct mux_rx *r, *r_next; - unsigned long flags; - - cancel_delayed_work(&mux_dev->work_rx); - - spin_lock_irqsave(&rx->submit_list_lock, flags); - list_for_each_entry_safe(r, r_next, &rx->rx_submit_list, - rx_submit_list) { - spin_unlock_irqrestore(&rx->submit_list_lock, flags); - usb_kill_urb(r->urb); - spin_lock_irqsave(&rx->submit_list_lock, flags); - } - spin_unlock_irqrestore(&rx->submit_list_lock, flags); - - spin_lock_irqsave(&rx->free_list_lock, flags); - list_for_each_entry_safe(r, r_next, &rx->rx_free_list, free_list) { - list_del(&r->free_list); - free_mux_rx(r); - } - spin_unlock_irqrestore(&rx->free_list_lock, flags); - - spin_lock_irqsave(&rx->to_host_lock, flags); - list_for_each_entry_safe(r, r_next, &rx->to_host_list, to_host_list) { - if (r->mux_dev =3D=3D (void *)mux_dev) { - list_del(&r->to_host_list); - free_mux_rx(r); - } - } - spin_unlock_irqrestore(&rx->to_host_lock, flags); -} - -static int init_usb(struct mux_dev *mux_dev) -{ - struct mux_rx *r; - struct rx_cxt *rx =3D &mux_dev->rx; - int ret =3D 0; - int i; - - spin_lock_init(&mux_dev->write_lock); - INIT_LIST_HEAD(&rx->to_host_list); - INIT_LIST_HEAD(&rx->rx_submit_list); - INIT_LIST_HEAD(&rx->rx_free_list); - spin_lock_init(&rx->to_host_lock); - spin_lock_init(&rx->submit_list_lock); - spin_lock_init(&rx->free_list_lock); - - for (i =3D 0; i < MAX_ISSUE_NUM * 2; i++) { - r =3D alloc_mux_rx(); - if (!r) { - ret =3D -ENOMEM; - break; - } - - list_add(&r->free_list, &rx->rx_free_list); - } - - INIT_DELAYED_WORK(&mux_dev->work_rx, do_rx); - - return ret; -} - -static int gdm_mux_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - struct mux_dev *mux_dev; - struct tty_dev *tty_dev; - u16 idVendor, idProduct; - int bInterfaceNumber; - int ret; - int i; - struct usb_device *usbdev =3D interface_to_usbdev(intf); - - bInterfaceNumber =3D intf->cur_altsetting->desc.bInterfaceNumber; - - idVendor =3D __le16_to_cpu(usbdev->descriptor.idVendor); - idProduct =3D __le16_to_cpu(usbdev->descriptor.idProduct); - - pr_info("mux vid =3D 0x%04x pid =3D 0x%04x\n", idVendor, idProduct); - - if (bInterfaceNumber !=3D 2) - return -ENODEV; - - mux_dev =3D kzalloc(sizeof(*mux_dev), GFP_KERNEL); - if (!mux_dev) - return -ENOMEM; - - tty_dev =3D kzalloc(sizeof(*tty_dev), GFP_KERNEL); - if (!tty_dev) { - ret =3D -ENOMEM; - goto err_free_mux; - } - - mux_dev->usbdev =3D usbdev; - mux_dev->control_intf =3D intf; - - ret =3D init_usb(mux_dev); - if (ret) - goto err_free_usb; - - tty_dev->priv_dev =3D (void *)mux_dev; - tty_dev->send_func =3D gdm_mux_send; - tty_dev->recv_func =3D gdm_mux_recv; - tty_dev->send_control =3D gdm_mux_send_control; - - ret =3D register_lte_tty_device(tty_dev, &intf->dev); - if (ret) - goto err_unregister_tty; - - for (i =3D 0; i < TTY_MAX_COUNT; i++) - mux_dev->tty_dev =3D tty_dev; - - mux_dev->intf =3D intf; - mux_dev->usb_state =3D PM_NORMAL; - - usb_get_dev(usbdev); - usb_set_intfdata(intf, tty_dev); - - return 0; - -err_unregister_tty: - unregister_lte_tty_device(tty_dev); -err_free_usb: - release_usb(mux_dev); - kfree(tty_dev); -err_free_mux: - kfree(mux_dev); - - return ret; -} - -static void gdm_mux_disconnect(struct usb_interface *intf) -{ - struct tty_dev *tty_dev; - struct mux_dev *mux_dev; - struct usb_device *usbdev =3D interface_to_usbdev(intf); - - tty_dev =3D usb_get_intfdata(intf); - - mux_dev =3D tty_dev->priv_dev; - - release_usb(mux_dev); - unregister_lte_tty_device(tty_dev); - - kfree(mux_dev); - kfree(tty_dev); - - usb_put_dev(usbdev); -} - -static int gdm_mux_suspend(struct usb_interface *intf, pm_message_t pm_msg) -{ - struct tty_dev *tty_dev; - struct mux_dev *mux_dev; - struct rx_cxt *rx; - struct mux_rx *r, *r_next; - unsigned long flags; - - tty_dev =3D usb_get_intfdata(intf); - mux_dev =3D tty_dev->priv_dev; - rx =3D &mux_dev->rx; - - cancel_work_sync(&mux_dev->work_rx.work); - - if (mux_dev->usb_state !=3D PM_NORMAL) { - dev_err(intf->usb_dev, "usb suspend - invalid state\n"); - return -EINVAL; - } - - mux_dev->usb_state =3D PM_SUSPEND; - - spin_lock_irqsave(&rx->submit_list_lock, flags); - list_for_each_entry_safe(r, r_next, &rx->rx_submit_list, - rx_submit_list) { - spin_unlock_irqrestore(&rx->submit_list_lock, flags); - usb_kill_urb(r->urb); - spin_lock_irqsave(&rx->submit_list_lock, flags); - } - spin_unlock_irqrestore(&rx->submit_list_lock, flags); - - return 0; -} - -static int gdm_mux_resume(struct usb_interface *intf) -{ - struct tty_dev *tty_dev; - struct mux_dev *mux_dev; - u8 i; - - tty_dev =3D usb_get_intfdata(intf); - mux_dev =3D tty_dev->priv_dev; - - if (mux_dev->usb_state !=3D PM_SUSPEND) { - dev_err(intf->usb_dev, "usb resume - invalid state\n"); - return -EINVAL; - } - - mux_dev->usb_state =3D PM_NORMAL; - - for (i =3D 0; i < MAX_ISSUE_NUM; i++) - gdm_mux_recv(mux_dev, mux_dev->rx_cb); - - return 0; -} - -static struct usb_driver gdm_mux_driver =3D { - .name =3D "gdm_mux", - .probe =3D gdm_mux_probe, - .disconnect =3D gdm_mux_disconnect, - .id_table =3D id_table, - .supports_autosuspend =3D 1, - .suspend =3D gdm_mux_suspend, - .resume =3D gdm_mux_resume, - .reset_resume =3D gdm_mux_resume, -}; - -static int __init gdm_usb_mux_init(void) -{ - int ret; - - ret =3D register_lte_tty_driver(); - if (ret) - return ret; - - return usb_register(&gdm_mux_driver); -} - -static void __exit gdm_usb_mux_exit(void) -{ - usb_deregister(&gdm_mux_driver); - unregister_lte_tty_driver(); -} - -module_init(gdm_usb_mux_init); -module_exit(gdm_usb_mux_exit); - -MODULE_DESCRIPTION("GCT LTE TTY Device Driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/gdm724x/gdm_mux.h b/drivers/staging/gdm724x/gd= m_mux.h deleted file mode 100644 index 87b8d921fdc8..000000000000 --- a/drivers/staging/gdm724x/gdm_mux.h +++ /dev/null @@ -1,85 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved. */ - -#ifndef _GDM_MUX_H_ -#define _GDM_MUX_H_ - -#include -#include -#include - -#include "gdm_tty.h" - -#define PM_NORMAL 0 -#define PM_SUSPEND 1 - -#define USB_RT_ACM (USB_TYPE_CLASS | USB_RECIP_INTERFACE) - -#define START_FLAG 0xA512485A -#define MUX_HEADER_SIZE 14 -#define MUX_TX_MAX_SIZE (1024 * 10) -#define MUX_RX_MAX_SIZE (1024 * 30) -#define AT_PKT_TYPE 0xF011 -#define DM_PKT_TYPE 0xF010 - -#define RETRY_TIMER 30 /* msec */ - -struct mux_pkt_header { - __le32 start_flag; - __le32 seq_num; - __le32 payload_size; - __le16 packet_type; - unsigned char data[]; -}; - -struct mux_tx { - struct urb *urb; - u8 *buf; - int len; - void (*callback)(void *cb_data); - void *cb_data; -}; - -struct mux_rx { - struct list_head free_list; - struct list_head rx_submit_list; - struct list_head to_host_list; - struct urb *urb; - u8 *buf; - void *mux_dev; - u32 offset; - u32 len; - int (*callback)(void *data, - int len, - int tty_index, - struct tty_dev *tty_dev, - int complete); -}; - -struct rx_cxt { - struct list_head to_host_list; - struct list_head rx_submit_list; - struct list_head rx_free_list; - spinlock_t to_host_lock; - spinlock_t submit_list_lock; - spinlock_t free_list_lock; -}; - -struct mux_dev { - struct usb_device *usbdev; - struct usb_interface *control_intf; - struct usb_interface *data_intf; - struct rx_cxt rx; - struct delayed_work work_rx; - struct usb_interface *intf; - int usb_state; - int (*rx_cb)(void *data, - int len, - int tty_index, - struct tty_dev *tty_dev, - int complete); - spinlock_t write_lock; - struct tty_dev *tty_dev; -}; - -#endif /* _GDM_MUX_H_ */ diff --git a/drivers/staging/gdm724x/gdm_tty.c b/drivers/staging/gdm724x/gd= m_tty.c deleted file mode 100644 index 15c246d3b1a3..000000000000 --- a/drivers/staging/gdm724x/gdm_tty.c +++ /dev/null @@ -1,316 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved. */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "gdm_tty.h" - -#define GDM_TTY_MAJOR 0 -#define GDM_TTY_MINOR 32 - -#define WRITE_SIZE 2048 - -#define MUX_TX_MAX_SIZE 2048 - -static inline bool gdm_tty_ready(struct gdm *gdm) -{ - return gdm && gdm->tty_dev && gdm->port.count; -} - -static struct tty_driver *gdm_driver[TTY_MAX_COUNT]; -static struct gdm *gdm_table[TTY_MAX_COUNT][GDM_TTY_MINOR]; -static DEFINE_MUTEX(gdm_table_lock); - -static const char *DRIVER_STRING[TTY_MAX_COUNT] =3D {"GCTATC", "GCTDM"}; -static char *DEVICE_STRING[TTY_MAX_COUNT] =3D {"GCT-ATC", "GCT-DM"}; - -static void gdm_port_destruct(struct tty_port *port) -{ - struct gdm *gdm =3D container_of(port, struct gdm, port); - - mutex_lock(&gdm_table_lock); - gdm_table[gdm->index][gdm->minor] =3D NULL; - mutex_unlock(&gdm_table_lock); - - kfree(gdm); -} - -static const struct tty_port_operations gdm_port_ops =3D { - .destruct =3D gdm_port_destruct, -}; - -static int gdm_tty_install(struct tty_driver *driver, struct tty_struct *t= ty) -{ - struct gdm *gdm =3D NULL; - int ret; - - ret =3D match_string(DRIVER_STRING, TTY_MAX_COUNT, - tty->driver->driver_name); - if (ret < 0) - return -ENODEV; - - mutex_lock(&gdm_table_lock); - gdm =3D gdm_table[ret][tty->index]; - if (!gdm) { - mutex_unlock(&gdm_table_lock); - return -ENODEV; - } - - tty_port_get(&gdm->port); - - ret =3D tty_standard_install(driver, tty); - if (ret) { - tty_port_put(&gdm->port); - mutex_unlock(&gdm_table_lock); - return ret; - } - - tty->driver_data =3D gdm; - mutex_unlock(&gdm_table_lock); - - return 0; -} - -static int gdm_tty_open(struct tty_struct *tty, struct file *filp) -{ - struct gdm *gdm =3D tty->driver_data; - - return tty_port_open(&gdm->port, tty, filp); -} - -static void gdm_tty_cleanup(struct tty_struct *tty) -{ - struct gdm *gdm =3D tty->driver_data; - - tty_port_put(&gdm->port); -} - -static void gdm_tty_hangup(struct tty_struct *tty) -{ - struct gdm *gdm =3D tty->driver_data; - - tty_port_hangup(&gdm->port); -} - -static void gdm_tty_close(struct tty_struct *tty, struct file *filp) -{ - struct gdm *gdm =3D tty->driver_data; - - tty_port_close(&gdm->port, tty, filp); -} - -static int gdm_tty_recv_complete(void *data, - int len, - int index, - struct tty_dev *tty_dev, - int complete) -{ - struct gdm *gdm =3D tty_dev->gdm[index]; - - if (!gdm_tty_ready(gdm)) { - if (complete =3D=3D RECV_PACKET_PROCESS_COMPLETE) - gdm->tty_dev->recv_func(gdm->tty_dev->priv_dev, - gdm_tty_recv_complete); - return TO_HOST_PORT_CLOSE; - } - - if (data && len) { - if (tty_buffer_request_room(&gdm->port, len) =3D=3D len) { - tty_insert_flip_string(&gdm->port, data, len); - tty_flip_buffer_push(&gdm->port); - } else { - return TO_HOST_BUFFER_REQUEST_FAIL; - } - } - - if (complete =3D=3D RECV_PACKET_PROCESS_COMPLETE) - gdm->tty_dev->recv_func(gdm->tty_dev->priv_dev, - gdm_tty_recv_complete); - - return 0; -} - -static void gdm_tty_send_complete(void *arg) -{ - struct gdm *gdm =3D arg; - - if (!gdm_tty_ready(gdm)) - return; - - tty_port_tty_wakeup(&gdm->port); -} - -static ssize_t gdm_tty_write(struct tty_struct *tty, const u8 *buf, size_t= len) -{ - struct gdm *gdm =3D tty->driver_data; - size_t remain =3D len; - size_t sent_len =3D 0; - - if (!gdm_tty_ready(gdm)) - return -ENODEV; - - while (remain) { - size_t sending_len =3D min_t(size_t, MUX_TX_MAX_SIZE, remain); - - gdm->tty_dev->send_func(gdm->tty_dev->priv_dev, - (void *)(buf + sent_len), - sending_len, - gdm->index, - gdm_tty_send_complete, - gdm); - sent_len +=3D sending_len; - remain -=3D sending_len; - } - - return len; -} - -static unsigned int gdm_tty_write_room(struct tty_struct *tty) -{ - struct gdm *gdm =3D tty->driver_data; - - if (!gdm_tty_ready(gdm)) - return 0; - - return WRITE_SIZE; -} - -int register_lte_tty_device(struct tty_dev *tty_dev, struct device *device) -{ - struct gdm *gdm; - int i; - int j; - - for (i =3D 0; i < TTY_MAX_COUNT; i++) { - gdm =3D kmalloc(sizeof(*gdm), GFP_KERNEL); - if (!gdm) - return -ENOMEM; - - mutex_lock(&gdm_table_lock); - for (j =3D 0; j < GDM_TTY_MINOR; j++) { - if (!gdm_table[i][j]) - break; - } - - if (j =3D=3D GDM_TTY_MINOR) { - kfree(gdm); - mutex_unlock(&gdm_table_lock); - return -EINVAL; - } - - gdm_table[i][j] =3D gdm; - mutex_unlock(&gdm_table_lock); - - tty_dev->gdm[i] =3D gdm; - tty_port_init(&gdm->port); - - gdm->port.ops =3D &gdm_port_ops; - gdm->index =3D i; - gdm->minor =3D j; - gdm->tty_dev =3D tty_dev; - - tty_port_register_device(&gdm->port, gdm_driver[i], - gdm->minor, device); - } - - for (i =3D 0; i < MAX_ISSUE_NUM; i++) - gdm->tty_dev->recv_func(gdm->tty_dev->priv_dev, - gdm_tty_recv_complete); - - return 0; -} - -void unregister_lte_tty_device(struct tty_dev *tty_dev) -{ - struct gdm *gdm; - struct tty_struct *tty; - int i; - - for (i =3D 0; i < TTY_MAX_COUNT; i++) { - gdm =3D tty_dev->gdm[i]; - if (!gdm) - continue; - - mutex_lock(&gdm_table_lock); - gdm_table[gdm->index][gdm->minor] =3D NULL; - mutex_unlock(&gdm_table_lock); - - tty =3D tty_port_tty_get(&gdm->port); - if (tty) { - tty_vhangup(tty); - tty_kref_put(tty); - } - - tty_unregister_device(gdm_driver[i], gdm->minor); - tty_port_put(&gdm->port); - } -} - -static const struct tty_operations gdm_tty_ops =3D { - .install =3D gdm_tty_install, - .open =3D gdm_tty_open, - .close =3D gdm_tty_close, - .cleanup =3D gdm_tty_cleanup, - .hangup =3D gdm_tty_hangup, - .write =3D gdm_tty_write, - .write_room =3D gdm_tty_write_room, -}; - -int register_lte_tty_driver(void) -{ - struct tty_driver *tty_driver; - int i; - int ret; - - for (i =3D 0; i < TTY_MAX_COUNT; i++) { - tty_driver =3D tty_alloc_driver(GDM_TTY_MINOR, - TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV); - if (IS_ERR(tty_driver)) - return PTR_ERR(tty_driver); - - tty_driver->owner =3D THIS_MODULE; - tty_driver->driver_name =3D DRIVER_STRING[i]; - tty_driver->name =3D DEVICE_STRING[i]; - tty_driver->major =3D GDM_TTY_MAJOR; - tty_driver->type =3D TTY_DRIVER_TYPE_SERIAL; - tty_driver->subtype =3D SERIAL_TYPE_NORMAL; - tty_driver->init_termios =3D tty_std_termios; - tty_driver->init_termios.c_cflag =3D B9600 | CS8 | HUPCL | CLOCAL; - tty_driver->init_termios.c_lflag =3D ISIG | ICANON | IEXTEN; - tty_set_operations(tty_driver, &gdm_tty_ops); - - ret =3D tty_register_driver(tty_driver); - if (ret) { - tty_driver_kref_put(tty_driver); - return ret; - } - - gdm_driver[i] =3D tty_driver; - } - - return ret; -} - -void unregister_lte_tty_driver(void) -{ - struct tty_driver *tty_driver; - int i; - - for (i =3D 0; i < TTY_MAX_COUNT; i++) { - tty_driver =3D gdm_driver[i]; - if (tty_driver) { - tty_unregister_driver(tty_driver); - tty_driver_kref_put(tty_driver); - } - } -} - diff --git a/drivers/staging/gdm724x/gdm_tty.h b/drivers/staging/gdm724x/gd= m_tty.h deleted file mode 100644 index afec97ced476..000000000000 --- a/drivers/staging/gdm724x/gdm_tty.h +++ /dev/null @@ -1,60 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved. */ - -#ifndef _GDM_TTY_H_ -#define _GDM_TTY_H_ - -#include -#include - -#define TTY_MAX_COUNT 2 - -#define MAX_ISSUE_NUM 3 - -enum TO_HOST_RESULT { - TO_HOST_BUFFER_REQUEST_FAIL =3D 1, - TO_HOST_PORT_CLOSE =3D 2, - TO_HOST_INVALID_PACKET =3D 3, -}; - -enum RECV_PACKET_PROCESS { - RECV_PACKET_PROCESS_COMPLETE =3D 0, - RECV_PACKET_PROCESS_CONTINUE =3D 1, -}; - -struct gdm { - struct tty_dev *tty_dev; - struct tty_port port; - unsigned int index; - unsigned int minor; -}; - -struct tty_dev { - void *priv_dev; - int (*send_func)(void *priv_dev, - void *data, - int len, - int tty_index, - void (*cb)(void *cb_data), - void *cb_data); - int (*recv_func)(void *priv_dev, - int (*cb)(void *data, - int len, - int tty_index, - struct tty_dev *tty_dev, - int complete)); - int (*send_control)(void *priv_dev, - int request, - int value, - void *data, - int len); - struct gdm *gdm[2]; -}; - -int register_lte_tty_driver(void); -void unregister_lte_tty_driver(void); -int register_lte_tty_device(struct tty_dev *tty_dev, struct device *dev); -void unregister_lte_tty_device(struct tty_dev *tty_dev); - -#endif /* _GDM_USB_H_ */ - diff --git a/drivers/staging/gdm724x/gdm_usb.c b/drivers/staging/gdm724x/gd= m_usb.c deleted file mode 100644 index f666fbeeb44c..000000000000 --- a/drivers/staging/gdm724x/gdm_usb.c +++ /dev/null @@ -1,1014 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved. */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "gdm_usb.h" -#include "gdm_lte.h" -#include "hci.h" -#include "hci_packet.h" -#include "gdm_endian.h" - -#define USB_DEVICE_CDC_DATA(vid, pid) \ - .match_flags =3D USB_DEVICE_ID_MATCH_DEVICE | \ - USB_DEVICE_ID_MATCH_INT_CLASS | \ - USB_DEVICE_ID_MATCH_INT_SUBCLASS,\ - .idVendor =3D vid,\ - .idProduct =3D pid,\ - .bInterfaceClass =3D USB_CLASS_COMM,\ - .bInterfaceSubClass =3D USB_CDC_SUBCLASS_ETHERNET - -#define USB_DEVICE_MASS_DATA(vid, pid) \ - .match_flags =3D USB_DEVICE_ID_MATCH_DEVICE | \ - USB_DEVICE_ID_MATCH_INT_INFO,\ - .idVendor =3D vid,\ - .idProduct =3D pid,\ - .bInterfaceSubClass =3D USB_SC_SCSI, \ - .bInterfaceClass =3D USB_CLASS_MASS_STORAGE,\ - .bInterfaceProtocol =3D USB_PR_BULK - -static const struct usb_device_id id_table[] =3D { - { USB_DEVICE_CDC_DATA(VID_GCT, PID_GDM7240) }, /* GCT GDM7240 */ - { USB_DEVICE_CDC_DATA(VID_GCT, PID_GDM7243) }, /* GCT GDM7243 */ - { } -}; - -MODULE_DEVICE_TABLE(usb, id_table); - -static void do_tx(struct work_struct *work); -static void do_rx(struct work_struct *work); - -static int gdm_usb_recv(void *priv_dev, - int (*cb)(void *cb_data, - void *data, int len, int context), - void *cb_data, - int context); - -static int request_mac_address(struct lte_udev *udev) -{ - struct hci_packet *hci; - struct usb_device *usbdev =3D udev->usbdev; - int actual; - int ret =3D -1; - - hci =3D kmalloc(struct_size(hci, data, 1), GFP_KERNEL); - if (!hci) - return -ENOMEM; - - hci->cmd_evt =3D gdm_cpu_to_dev16(udev->gdm_ed, LTE_GET_INFORMATION); - hci->len =3D gdm_cpu_to_dev16(udev->gdm_ed, 1); - hci->data[0] =3D MAC_ADDRESS; - - ret =3D usb_bulk_msg(usbdev, usb_sndbulkpipe(usbdev, 2), hci, 5, - &actual, 1000); - - udev->request_mac_addr =3D 1; - kfree(hci); - - return ret; -} - -static struct usb_tx *alloc_tx_struct(int len) -{ - struct usb_tx *t =3D NULL; - int ret =3D 0; - - t =3D kzalloc(sizeof(*t), GFP_ATOMIC); - if (!t) { - ret =3D -ENOMEM; - goto out; - } - - t->urb =3D usb_alloc_urb(0, GFP_ATOMIC); - if (!(len % 512)) - len++; - - t->buf =3D kmalloc(len, GFP_ATOMIC); - if (!t->urb || !t->buf) { - ret =3D -ENOMEM; - goto out; - } - -out: - if (ret < 0) { - if (t) { - usb_free_urb(t->urb); - kfree(t->buf); - kfree(t); - } - return NULL; - } - - return t; -} - -static struct usb_tx_sdu *alloc_tx_sdu_struct(void) -{ - struct usb_tx_sdu *t_sdu; - - t_sdu =3D kzalloc(sizeof(*t_sdu), GFP_KERNEL); - if (!t_sdu) - return NULL; - - t_sdu->buf =3D kmalloc(SDU_BUF_SIZE, GFP_KERNEL); - if (!t_sdu->buf) { - kfree(t_sdu); - return NULL; - } - - return t_sdu; -} - -static void free_tx_struct(struct usb_tx *t) -{ - if (t) { - usb_free_urb(t->urb); - kfree(t->buf); - kfree(t); - } -} - -static void free_tx_sdu_struct(struct usb_tx_sdu *t_sdu) -{ - if (t_sdu) { - kfree(t_sdu->buf); - kfree(t_sdu); - } -} - -static struct usb_tx_sdu *get_tx_sdu_struct(struct tx_cxt *tx, int *no_spc) -{ - struct usb_tx_sdu *t_sdu; - - if (list_empty(&tx->free_list)) - return NULL; - - t_sdu =3D list_entry(tx->free_list.next, struct usb_tx_sdu, list); - list_del(&t_sdu->list); - - tx->avail_count--; - - *no_spc =3D list_empty(&tx->free_list) ? 1 : 0; - - return t_sdu; -} - -static void put_tx_struct(struct tx_cxt *tx, struct usb_tx_sdu *t_sdu) -{ - list_add_tail(&t_sdu->list, &tx->free_list); - tx->avail_count++; -} - -static struct usb_rx *alloc_rx_struct(void) -{ - struct usb_rx *r =3D NULL; - int ret =3D 0; - - r =3D kmalloc(sizeof(*r), GFP_KERNEL); - if (!r) { - ret =3D -ENOMEM; - goto out; - } - - r->urb =3D usb_alloc_urb(0, GFP_KERNEL); - r->buf =3D kmalloc(RX_BUF_SIZE, GFP_KERNEL); - if (!r->urb || !r->buf) { - ret =3D -ENOMEM; - goto out; - } -out: - - if (ret < 0) { - if (r) { - usb_free_urb(r->urb); - kfree(r->buf); - kfree(r); - } - return NULL; - } - - return r; -} - -static void free_rx_struct(struct usb_rx *r) -{ - if (r) { - usb_free_urb(r->urb); - kfree(r->buf); - kfree(r); - } -} - -static struct usb_rx *get_rx_struct(struct rx_cxt *rx, int *no_spc) -{ - struct usb_rx *r; - unsigned long flags; - - spin_lock_irqsave(&rx->rx_lock, flags); - - if (list_empty(&rx->free_list)) { - spin_unlock_irqrestore(&rx->rx_lock, flags); - return NULL; - } - - r =3D list_entry(rx->free_list.next, struct usb_rx, free_list); - list_del(&r->free_list); - - rx->avail_count--; - - *no_spc =3D list_empty(&rx->free_list) ? 1 : 0; - - spin_unlock_irqrestore(&rx->rx_lock, flags); - - return r; -} - -static void put_rx_struct(struct rx_cxt *rx, struct usb_rx *r) -{ - unsigned long flags; - - spin_lock_irqsave(&rx->rx_lock, flags); - - list_add_tail(&r->free_list, &rx->free_list); - rx->avail_count++; - - spin_unlock_irqrestore(&rx->rx_lock, flags); -} - -static void release_usb(struct lte_udev *udev) -{ - struct rx_cxt *rx =3D &udev->rx; - struct tx_cxt *tx =3D &udev->tx; - struct usb_tx *t, *t_next; - struct usb_rx *r, *r_next; - struct usb_tx_sdu *t_sdu, *t_sdu_next; - unsigned long flags; - - spin_lock_irqsave(&tx->lock, flags); - list_for_each_entry_safe(t_sdu, t_sdu_next, &tx->sdu_list, list) { - list_del(&t_sdu->list); - free_tx_sdu_struct(t_sdu); - } - - list_for_each_entry_safe(t, t_next, &tx->hci_list, list) { - list_del(&t->list); - free_tx_struct(t); - } - - list_for_each_entry_safe(t_sdu, t_sdu_next, &tx->free_list, list) { - list_del(&t_sdu->list); - free_tx_sdu_struct(t_sdu); - } - spin_unlock_irqrestore(&tx->lock, flags); - - spin_lock_irqsave(&rx->submit_lock, flags); - list_for_each_entry_safe(r, r_next, &rx->rx_submit_list, - rx_submit_list) { - spin_unlock_irqrestore(&rx->submit_lock, flags); - usb_kill_urb(r->urb); - spin_lock_irqsave(&rx->submit_lock, flags); - } - spin_unlock_irqrestore(&rx->submit_lock, flags); - - spin_lock_irqsave(&rx->rx_lock, flags); - list_for_each_entry_safe(r, r_next, &rx->free_list, free_list) { - list_del(&r->free_list); - free_rx_struct(r); - } - spin_unlock_irqrestore(&rx->rx_lock, flags); - - spin_lock_irqsave(&rx->to_host_lock, flags); - list_for_each_entry_safe(r, r_next, &rx->to_host_list, to_host_list) { - if (r->index =3D=3D (void *)udev) { - list_del(&r->to_host_list); - free_rx_struct(r); - } - } - spin_unlock_irqrestore(&rx->to_host_lock, flags); -} - -static int init_usb(struct lte_udev *udev) -{ - int ret =3D 0; - int i; - struct tx_cxt *tx =3D &udev->tx; - struct rx_cxt *rx =3D &udev->rx; - struct usb_tx_sdu *t_sdu =3D NULL; - struct usb_rx *r =3D NULL; - - udev->send_complete =3D 1; - udev->tx_stop =3D 0; - udev->request_mac_addr =3D 0; - udev->usb_state =3D PM_NORMAL; - - INIT_LIST_HEAD(&tx->sdu_list); - INIT_LIST_HEAD(&tx->hci_list); - INIT_LIST_HEAD(&tx->free_list); - INIT_LIST_HEAD(&rx->rx_submit_list); - INIT_LIST_HEAD(&rx->free_list); - INIT_LIST_HEAD(&rx->to_host_list); - spin_lock_init(&tx->lock); - spin_lock_init(&rx->rx_lock); - spin_lock_init(&rx->submit_lock); - spin_lock_init(&rx->to_host_lock); - - tx->avail_count =3D 0; - rx->avail_count =3D 0; - - udev->rx_cb =3D NULL; - - for (i =3D 0; i < MAX_NUM_SDU_BUF; i++) { - t_sdu =3D alloc_tx_sdu_struct(); - if (!t_sdu) { - ret =3D -ENOMEM; - goto fail; - } - - list_add(&t_sdu->list, &tx->free_list); - tx->avail_count++; - } - - for (i =3D 0; i < MAX_RX_SUBMIT_COUNT * 2; i++) { - r =3D alloc_rx_struct(); - if (!r) { - ret =3D -ENOMEM; - goto fail; - } - - list_add(&r->free_list, &rx->free_list); - rx->avail_count++; - } - INIT_DELAYED_WORK(&udev->work_tx, do_tx); - INIT_DELAYED_WORK(&udev->work_rx, do_rx); - return 0; -fail: - release_usb(udev); - return ret; -} - -static int set_mac_address(u8 *data, void *arg) -{ - struct phy_dev *phy_dev =3D arg; - struct lte_udev *udev =3D phy_dev->priv_dev; - struct tlv *tlv =3D (struct tlv *)data; - u8 mac_address[ETH_ALEN] =3D {0, }; - - if (tlv->type =3D=3D MAC_ADDRESS && udev->request_mac_addr) { - memcpy(mac_address, tlv->data, tlv->len); - - if (register_lte_device(phy_dev, - &udev->intf->dev, mac_address) < 0) - pr_err("register lte device failed\n"); - - udev->request_mac_addr =3D 0; - - return 1; - } - - return 0; -} - -static void do_rx(struct work_struct *work) -{ - struct lte_udev *udev =3D - container_of(work, struct lte_udev, work_rx.work); - struct rx_cxt *rx =3D &udev->rx; - struct usb_rx *r; - struct hci_packet *hci; - struct phy_dev *phy_dev; - u16 cmd_evt; - int ret; - unsigned long flags; - - while (1) { - spin_lock_irqsave(&rx->to_host_lock, flags); - if (list_empty(&rx->to_host_list)) { - spin_unlock_irqrestore(&rx->to_host_lock, flags); - break; - } - r =3D list_entry(rx->to_host_list.next, - struct usb_rx, to_host_list); - list_del(&r->to_host_list); - spin_unlock_irqrestore(&rx->to_host_lock, flags); - - phy_dev =3D r->cb_data; - udev =3D phy_dev->priv_dev; - hci =3D (struct hci_packet *)r->buf; - cmd_evt =3D gdm_dev16_to_cpu(udev->gdm_ed, hci->cmd_evt); - - switch (cmd_evt) { - case LTE_GET_INFORMATION_RESULT: - if (set_mac_address(hci->data, r->cb_data) =3D=3D 0) { - r->callback(r->cb_data, - r->buf, - r->urb->actual_length, - KERNEL_THREAD); - } - break; - - default: - if (r->callback) { - ret =3D r->callback(r->cb_data, - r->buf, - r->urb->actual_length, - KERNEL_THREAD); - - if (ret =3D=3D -EAGAIN) - pr_err("failed to send received data\n"); - } - break; - } - - put_rx_struct(rx, r); - - gdm_usb_recv(udev, - r->callback, - r->cb_data, - USB_COMPLETE); - } -} - -static void remove_rx_submit_list(struct usb_rx *r, struct rx_cxt *rx) -{ - unsigned long flags; - struct usb_rx *r_remove, *r_remove_next; - - spin_lock_irqsave(&rx->submit_lock, flags); - list_for_each_entry_safe(r_remove, r_remove_next, - &rx->rx_submit_list, rx_submit_list) { - if (r =3D=3D r_remove) { - list_del(&r->rx_submit_list); - break; - } - } - spin_unlock_irqrestore(&rx->submit_lock, flags); -} - -static void gdm_usb_rcv_complete(struct urb *urb) -{ - struct usb_rx *r =3D urb->context; - struct rx_cxt *rx =3D r->rx; - unsigned long flags; - struct lte_udev *udev =3D container_of(r->rx, struct lte_udev, rx); - struct usb_device *usbdev =3D udev->usbdev; - - remove_rx_submit_list(r, rx); - - if (!urb->status && r->callback) { - spin_lock_irqsave(&rx->to_host_lock, flags); - list_add_tail(&r->to_host_list, &rx->to_host_list); - schedule_work(&udev->work_rx.work); - spin_unlock_irqrestore(&rx->to_host_lock, flags); - } else { - if (urb->status && udev->usb_state =3D=3D PM_NORMAL) - dev_err(&urb->dev->dev, "%s: urb status error %d\n", - __func__, urb->status); - - put_rx_struct(rx, r); - } - - usb_mark_last_busy(usbdev); -} - -static int gdm_usb_recv(void *priv_dev, - int (*cb)(void *cb_data, - void *data, int len, int context), - void *cb_data, - int context) -{ - struct lte_udev *udev =3D priv_dev; - struct usb_device *usbdev =3D udev->usbdev; - struct rx_cxt *rx =3D &udev->rx; - struct usb_rx *r; - int no_spc; - int ret; - unsigned long flags; - - if (!udev->usbdev) { - pr_err("invalid device\n"); - return -ENODEV; - } - - r =3D get_rx_struct(rx, &no_spc); - if (!r) { - pr_err("Out of Memory\n"); - return -ENOMEM; - } - - udev->rx_cb =3D cb; - r->callback =3D cb; - r->cb_data =3D cb_data; - r->index =3D (void *)udev; - r->rx =3D rx; - - usb_fill_bulk_urb(r->urb, - usbdev, - usb_rcvbulkpipe(usbdev, 0x83), - r->buf, - RX_BUF_SIZE, - gdm_usb_rcv_complete, - r); - - spin_lock_irqsave(&rx->submit_lock, flags); - list_add_tail(&r->rx_submit_list, &rx->rx_submit_list); - spin_unlock_irqrestore(&rx->submit_lock, flags); - - if (context =3D=3D KERNEL_THREAD) - ret =3D usb_submit_urb(r->urb, GFP_KERNEL); - else - ret =3D usb_submit_urb(r->urb, GFP_ATOMIC); - - if (ret) { - spin_lock_irqsave(&rx->submit_lock, flags); - list_del(&r->rx_submit_list); - spin_unlock_irqrestore(&rx->submit_lock, flags); - - pr_err("usb_submit_urb failed (%p)\n", r); - put_rx_struct(rx, r); - } - - return ret; -} - -static void gdm_usb_send_complete(struct urb *urb) -{ - struct usb_tx *t =3D urb->context; - struct tx_cxt *tx =3D t->tx; - struct lte_udev *udev =3D container_of(tx, struct lte_udev, tx); - unsigned long flags; - - if (urb->status =3D=3D -ECONNRESET) { - dev_info(&urb->dev->dev, "CONNRESET\n"); - return; - } - - if (t->callback) - t->callback(t->cb_data); - - free_tx_struct(t); - - spin_lock_irqsave(&tx->lock, flags); - udev->send_complete =3D 1; - schedule_work(&udev->work_tx.work); - spin_unlock_irqrestore(&tx->lock, flags); -} - -static int send_tx_packet(struct usb_device *usbdev, struct usb_tx *t, u32= len) -{ - int ret =3D 0; - - if (!(len % 512)) - len++; - - usb_fill_bulk_urb(t->urb, - usbdev, - usb_sndbulkpipe(usbdev, 2), - t->buf, - len, - gdm_usb_send_complete, - t); - - ret =3D usb_submit_urb(t->urb, GFP_ATOMIC); - - if (ret) - dev_err(&usbdev->dev, "usb_submit_urb failed: %d\n", - ret); - - usb_mark_last_busy(usbdev); - - return ret; -} - -static u32 packet_aggregation(struct lte_udev *udev, u8 *send_buf) -{ - struct tx_cxt *tx =3D &udev->tx; - struct usb_tx_sdu *t_sdu =3D NULL; - struct multi_sdu *multi_sdu =3D (struct multi_sdu *)send_buf; - u16 send_len =3D 0; - u16 num_packet =3D 0; - unsigned long flags; - - multi_sdu->cmd_evt =3D gdm_cpu_to_dev16(udev->gdm_ed, LTE_TX_MULTI_SDU); - - while (num_packet < MAX_PACKET_IN_MULTI_SDU) { - spin_lock_irqsave(&tx->lock, flags); - if (list_empty(&tx->sdu_list)) { - spin_unlock_irqrestore(&tx->lock, flags); - break; - } - - t_sdu =3D list_entry(tx->sdu_list.next, struct usb_tx_sdu, list); - if (send_len + t_sdu->len > MAX_SDU_SIZE) { - spin_unlock_irqrestore(&tx->lock, flags); - break; - } - - list_del(&t_sdu->list); - spin_unlock_irqrestore(&tx->lock, flags); - - memcpy(multi_sdu->data + send_len, t_sdu->buf, t_sdu->len); - - send_len +=3D (t_sdu->len + 3) & 0xfffc; - num_packet++; - - if (tx->avail_count > 10) - t_sdu->callback(t_sdu->cb_data); - - spin_lock_irqsave(&tx->lock, flags); - put_tx_struct(tx, t_sdu); - spin_unlock_irqrestore(&tx->lock, flags); - } - - multi_sdu->len =3D gdm_cpu_to_dev16(udev->gdm_ed, send_len); - multi_sdu->num_packet =3D gdm_cpu_to_dev16(udev->gdm_ed, num_packet); - - return send_len + offsetof(struct multi_sdu, data); -} - -static void do_tx(struct work_struct *work) -{ - struct lte_udev *udev =3D - container_of(work, struct lte_udev, work_tx.work); - struct usb_device *usbdev =3D udev->usbdev; - struct tx_cxt *tx =3D &udev->tx; - struct usb_tx *t =3D NULL; - int is_send =3D 0; - u32 len =3D 0; - unsigned long flags; - - if (!usb_autopm_get_interface(udev->intf)) - usb_autopm_put_interface(udev->intf); - - if (udev->usb_state =3D=3D PM_SUSPEND) - return; - - spin_lock_irqsave(&tx->lock, flags); - if (!udev->send_complete) { - spin_unlock_irqrestore(&tx->lock, flags); - return; - } - udev->send_complete =3D 0; - - if (!list_empty(&tx->hci_list)) { - t =3D list_entry(tx->hci_list.next, struct usb_tx, list); - list_del(&t->list); - len =3D t->len; - t->is_sdu =3D 0; - is_send =3D 1; - } else if (!list_empty(&tx->sdu_list)) { - if (udev->tx_stop) { - udev->send_complete =3D 1; - spin_unlock_irqrestore(&tx->lock, flags); - return; - } - - t =3D alloc_tx_struct(TX_BUF_SIZE); - if (!t) { - spin_unlock_irqrestore(&tx->lock, flags); - return; - } - t->callback =3D NULL; - t->tx =3D tx; - t->is_sdu =3D 1; - is_send =3D 1; - } - - if (!is_send) { - udev->send_complete =3D 1; - spin_unlock_irqrestore(&tx->lock, flags); - return; - } - spin_unlock_irqrestore(&tx->lock, flags); - - if (t->is_sdu) - len =3D packet_aggregation(udev, t->buf); - - if (send_tx_packet(usbdev, t, len)) { - pr_err("send_tx_packet failed\n"); - t->callback =3D NULL; - gdm_usb_send_complete(t->urb); - } -} - -#define SDU_PARAM_LEN 12 -static int gdm_usb_sdu_send(void *priv_dev, void *data, int len, - unsigned int dft_eps_ID, unsigned int eps_ID, - void (*cb)(void *data), void *cb_data, - int dev_idx, int nic_type) -{ - struct lte_udev *udev =3D priv_dev; - struct tx_cxt *tx =3D &udev->tx; - struct usb_tx_sdu *t_sdu; - struct sdu *sdu =3D NULL; - unsigned long flags; - int no_spc =3D 0; - u16 send_len; - - if (!udev->usbdev) { - pr_err("sdu send - invalid device\n"); - return TX_NO_DEV; - } - - spin_lock_irqsave(&tx->lock, flags); - t_sdu =3D get_tx_sdu_struct(tx, &no_spc); - spin_unlock_irqrestore(&tx->lock, flags); - - if (!t_sdu) { - pr_err("sdu send - free list empty\n"); - return TX_NO_SPC; - } - - sdu =3D (struct sdu *)t_sdu->buf; - sdu->cmd_evt =3D gdm_cpu_to_dev16(udev->gdm_ed, LTE_TX_SDU); - if (nic_type =3D=3D NIC_TYPE_ARP) { - send_len =3D len + SDU_PARAM_LEN; - memcpy(sdu->data, data, len); - } else { - send_len =3D len - ETH_HLEN; - send_len +=3D SDU_PARAM_LEN; - memcpy(sdu->data, data + ETH_HLEN, len - ETH_HLEN); - } - - sdu->len =3D gdm_cpu_to_dev16(udev->gdm_ed, send_len); - sdu->dft_eps_ID =3D gdm_cpu_to_dev32(udev->gdm_ed, dft_eps_ID); - sdu->bearer_ID =3D gdm_cpu_to_dev32(udev->gdm_ed, eps_ID); - sdu->nic_type =3D gdm_cpu_to_dev32(udev->gdm_ed, nic_type); - - t_sdu->len =3D send_len + HCI_HEADER_SIZE; - t_sdu->callback =3D cb; - t_sdu->cb_data =3D cb_data; - - spin_lock_irqsave(&tx->lock, flags); - list_add_tail(&t_sdu->list, &tx->sdu_list); - schedule_work(&udev->work_tx.work); - spin_unlock_irqrestore(&tx->lock, flags); - - if (no_spc) - return TX_NO_BUFFER; - - return 0; -} - -static int gdm_usb_hci_send(void *priv_dev, void *data, int len, - void (*cb)(void *data), void *cb_data) -{ - struct lte_udev *udev =3D priv_dev; - struct tx_cxt *tx =3D &udev->tx; - struct usb_tx *t; - unsigned long flags; - - if (!udev->usbdev) { - pr_err("hci send - invalid device\n"); - return -ENODEV; - } - - t =3D alloc_tx_struct(len); - if (!t) { - pr_err("hci_send - out of memory\n"); - return -ENOMEM; - } - - memcpy(t->buf, data, len); - t->callback =3D cb; - t->cb_data =3D cb_data; - t->len =3D len; - t->tx =3D tx; - t->is_sdu =3D 0; - - spin_lock_irqsave(&tx->lock, flags); - list_add_tail(&t->list, &tx->hci_list); - schedule_work(&udev->work_tx.work); - spin_unlock_irqrestore(&tx->lock, flags); - - return 0; -} - -static u8 gdm_usb_get_endian(void *priv_dev) -{ - struct lte_udev *udev =3D priv_dev; - - return udev->gdm_ed; -} - -static int gdm_usb_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - int ret =3D 0; - struct phy_dev *phy_dev =3D NULL; - struct lte_udev *udev =3D NULL; - u16 idVendor, idProduct; - int bInterfaceNumber; - struct usb_device *usbdev =3D interface_to_usbdev(intf); - - bInterfaceNumber =3D intf->cur_altsetting->desc.bInterfaceNumber; - idVendor =3D __le16_to_cpu(usbdev->descriptor.idVendor); - idProduct =3D __le16_to_cpu(usbdev->descriptor.idProduct); - - pr_info("net vid =3D 0x%04x pid =3D 0x%04x\n", idVendor, idProduct); - - if (bInterfaceNumber > NETWORK_INTERFACE) { - pr_info("not a network device\n"); - return -ENODEV; - } - - phy_dev =3D kzalloc(sizeof(*phy_dev), GFP_KERNEL); - if (!phy_dev) - return -ENOMEM; - - udev =3D kzalloc(sizeof(*udev), GFP_KERNEL); - if (!udev) { - ret =3D -ENOMEM; - goto err_udev; - } - - phy_dev->priv_dev =3D (void *)udev; - phy_dev->send_hci_func =3D gdm_usb_hci_send; - phy_dev->send_sdu_func =3D gdm_usb_sdu_send; - phy_dev->rcv_func =3D gdm_usb_recv; - phy_dev->get_endian =3D gdm_usb_get_endian; - - udev->usbdev =3D usbdev; - ret =3D init_usb(udev); - if (ret < 0) { - dev_err(intf->usb_dev, "init_usb func failed\n"); - goto err_init_usb; - } - udev->intf =3D intf; - - intf->needs_remote_wakeup =3D 1; - usb_enable_autosuspend(usbdev); - pm_runtime_set_autosuspend_delay(&usbdev->dev, AUTO_SUSPEND_TIMER); - - /* List up hosts with big endians, otherwise, - * defaults to little endian - */ - if (idProduct =3D=3D PID_GDM7243) - udev->gdm_ed =3D ENDIANNESS_BIG; - else - udev->gdm_ed =3D ENDIANNESS_LITTLE; - - ret =3D request_mac_address(udev); - if (ret < 0) { - dev_err(intf->usb_dev, "request Mac address failed\n"); - goto err_mac_address; - } - - start_rx_proc(phy_dev); - usb_get_dev(usbdev); - usb_set_intfdata(intf, phy_dev); - - return 0; - -err_mac_address: - release_usb(udev); -err_init_usb: - kfree(udev); -err_udev: - kfree(phy_dev); - - return ret; -} - -static void gdm_usb_disconnect(struct usb_interface *intf) -{ - struct phy_dev *phy_dev; - struct lte_udev *udev; - struct usb_device *usbdev; - - usbdev =3D interface_to_usbdev(intf); - phy_dev =3D usb_get_intfdata(intf); - - udev =3D phy_dev->priv_dev; - unregister_lte_device(phy_dev); - - release_usb(udev); - - kfree(udev); - udev =3D NULL; - - kfree(phy_dev); - phy_dev =3D NULL; - - usb_put_dev(usbdev); -} - -static int gdm_usb_suspend(struct usb_interface *intf, pm_message_t pm_msg) -{ - struct phy_dev *phy_dev; - struct lte_udev *udev; - struct rx_cxt *rx; - struct usb_rx *r; - struct usb_rx *r_next; - unsigned long flags; - - phy_dev =3D usb_get_intfdata(intf); - udev =3D phy_dev->priv_dev; - rx =3D &udev->rx; - if (udev->usb_state !=3D PM_NORMAL) { - dev_err(intf->usb_dev, "usb suspend - invalid state\n"); - return -EINVAL; - } - - udev->usb_state =3D PM_SUSPEND; - - spin_lock_irqsave(&rx->submit_lock, flags); - list_for_each_entry_safe(r, r_next, &rx->rx_submit_list, - rx_submit_list) { - spin_unlock_irqrestore(&rx->submit_lock, flags); - usb_kill_urb(r->urb); - spin_lock_irqsave(&rx->submit_lock, flags); - } - spin_unlock_irqrestore(&rx->submit_lock, flags); - - cancel_work_sync(&udev->work_tx.work); - cancel_work_sync(&udev->work_rx.work); - - return 0; -} - -static int gdm_usb_resume(struct usb_interface *intf) -{ - struct phy_dev *phy_dev; - struct lte_udev *udev; - struct tx_cxt *tx; - struct rx_cxt *rx; - unsigned long flags; - int issue_count; - int i; - - phy_dev =3D usb_get_intfdata(intf); - udev =3D phy_dev->priv_dev; - rx =3D &udev->rx; - - if (udev->usb_state !=3D PM_SUSPEND) { - dev_err(intf->usb_dev, "usb resume - invalid state\n"); - return -EINVAL; - } - udev->usb_state =3D PM_NORMAL; - - spin_lock_irqsave(&rx->rx_lock, flags); - issue_count =3D rx->avail_count - MAX_RX_SUBMIT_COUNT; - spin_unlock_irqrestore(&rx->rx_lock, flags); - - if (issue_count >=3D 0) { - for (i =3D 0; i < issue_count; i++) - gdm_usb_recv(phy_dev->priv_dev, - udev->rx_cb, - phy_dev, - USB_COMPLETE); - } - - tx =3D &udev->tx; - spin_lock_irqsave(&tx->lock, flags); - schedule_work(&udev->work_tx.work); - spin_unlock_irqrestore(&tx->lock, flags); - - return 0; -} - -static struct usb_driver gdm_usb_lte_driver =3D { - .name =3D "gdm_lte", - .probe =3D gdm_usb_probe, - .disconnect =3D gdm_usb_disconnect, - .id_table =3D id_table, - .supports_autosuspend =3D 1, - .suspend =3D gdm_usb_suspend, - .resume =3D gdm_usb_resume, - .reset_resume =3D gdm_usb_resume, -}; - -static int __init gdm_usb_lte_init(void) -{ - int ret =3D gdm_lte_event_init(); - - if (ret < 0) { - pr_err("error creating event\n"); - return ret; - } - - return usb_register(&gdm_usb_lte_driver); -} - -static void __exit gdm_usb_lte_exit(void) -{ - gdm_lte_event_exit(); - - usb_deregister(&gdm_usb_lte_driver); -} - -module_init(gdm_usb_lte_init); -module_exit(gdm_usb_lte_exit); - -MODULE_VERSION(DRIVER_VERSION); -MODULE_DESCRIPTION("GCT LTE USB Device Driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/gdm724x/gdm_usb.h b/drivers/staging/gdm724x/gd= m_usb.h deleted file mode 100644 index db689b091c4f..000000000000 --- a/drivers/staging/gdm724x/gdm_usb.h +++ /dev/null @@ -1,99 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved. */ - -#ifndef _GDM_USB_H_ -#define _GDM_USB_H_ - -#include -#include -#include -#include - -#include "gdm_endian.h" -#include "hci_packet.h" - -#define PM_NORMAL 0 -#define PM_SUSPEND 1 -#define AUTO_SUSPEND_TIMER 5000 /* ms */ - -#define RX_BUF_SIZE (1024 * 32) -#define TX_BUF_SIZE (1024 * 32) -#define SDU_BUF_SIZE 2048 -#define MAX_SDU_SIZE (1024 * 30) -#define MAX_PACKET_IN_MULTI_SDU 256 - -#define VID_GCT 0x1076 -#define PID_GDM7240 0x8000 -#define PID_GDM7243 0x9000 - -#define NETWORK_INTERFACE 1 -#define USB_SC_SCSI 0x06 -#define USB_PR_BULK 0x50 - -#define MAX_NUM_SDU_BUF 64 - -struct usb_tx { - struct list_head list; - struct urb *urb; - u8 *buf; - u32 len; - void (*callback)(void *cb_data); - void *cb_data; - struct tx_cxt *tx; - u8 is_sdu; -}; - -struct usb_tx_sdu { - struct list_head list; - u8 *buf; - u32 len; - void (*callback)(void *cb_data); - void *cb_data; -}; - -struct usb_rx { - struct list_head to_host_list; - struct list_head free_list; - struct list_head rx_submit_list; - struct rx_cxt *rx; - struct urb *urb; - u8 *buf; - int (*callback)(void *cb_data, void *data, int len, int context); - void *cb_data; - void *index; -}; - -struct tx_cxt { - struct list_head sdu_list; - struct list_head hci_list; - struct list_head free_list; - u32 avail_count; - spinlock_t lock; -}; - -struct rx_cxt { - struct list_head to_host_list; - struct list_head rx_submit_list; - struct list_head free_list; - u32 avail_count; - spinlock_t to_host_lock; - spinlock_t rx_lock; - spinlock_t submit_lock; -}; - -struct lte_udev { - struct usb_device *usbdev; - struct tx_cxt tx; - struct rx_cxt rx; - struct delayed_work work_tx; - struct delayed_work work_rx; - u8 gdm_ed; - u8 send_complete; - u8 tx_stop; - struct usb_interface *intf; - int (*rx_cb)(void *cb_data, void *data, int len, int context); - int usb_state; - u8 request_mac_addr; -}; - -#endif /* _GDM_USB_H_ */ diff --git a/drivers/staging/gdm724x/hci.h b/drivers/staging/gdm724x/hci.h deleted file mode 100644 index b30945daf3a5..000000000000 --- a/drivers/staging/gdm724x/hci.h +++ /dev/null @@ -1,45 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved. */ - -#ifndef _HCI_H_ -#define _HCI_H_ - -#define LTE_GET_INFORMATION 0x3002 -#define LTE_GET_INFORMATION_RESULT 0xB003 - #define MAC_ADDRESS 0xA2 - -#define LTE_LINK_ON_OFF_INDICATION 0xB133 -#define LTE_PDN_TABLE_IND 0xB143 - -#define LTE_TX_SDU 0x3200 -#define LTE_RX_SDU 0xB201 -#define LTE_TX_MULTI_SDU 0x3202 -#define LTE_RX_MULTI_SDU 0xB203 - -#define LTE_DL_SDU_FLOW_CONTROL 0x3305 -#define LTE_UL_SDU_FLOW_CONTROL 0xB306 - -#define LTE_AT_CMD_TO_DEVICE 0x3307 -#define LTE_AT_CMD_FROM_DEVICE 0xB308 - -#define LTE_SDIO_DM_SEND_PKT 0x3312 -#define LTE_SDIO_DM_RECV_PKT 0xB313 - -#define LTE_NV_RESTORE_REQUEST 0xB30C -#define LTE_NV_RESTORE_RESPONSE 0x330D -#define LTE_NV_SAVE_REQUEST 0xB30E - #define NV_TYPE_LTE_INFO 0x00 - #define NV_TYPE_BOARD_CONFIG 0x01 - #define NV_TYPE_RF_CAL 0x02 - #define NV_TYPE_TEMP 0x03 - #define NV_TYPE_NET_INFO 0x04 - #define NV_TYPE_SAFETY_INFO 0x05 - #define NV_TYPE_CDMA_CAL 0x06 - #define NV_TYPE_VENDOR 0x07 - #define NV_TYPE_ALL 0xff -#define LTE_NV_SAVE_RESPONSE 0x330F - -#define LTE_AT_CMD_TO_DEVICE_EXT 0x3323 -#define LTE_AT_CMD_FROM_DEVICE_EXT 0xB324 - -#endif /* _HCI_H_ */ diff --git a/drivers/staging/gdm724x/hci_packet.h b/drivers/staging/gdm724x= /hci_packet.h deleted file mode 100644 index 3bb01e94f3b5..000000000000 --- a/drivers/staging/gdm724x/hci_packet.h +++ /dev/null @@ -1,82 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved. */ - -#ifndef _HCI_PACKET_H_ -#define _HCI_PACKET_H_ - -#define HCI_HEADER_SIZE 4 - -/* - * The NIC type definition: - * For backward compatibility, lower 16 bits used as they were. - * Lower 16 bit: NIC_TYPE values - * Uppoer 16 bit: NIC_TYPE Flags - */ -#define NIC_TYPE_NIC0 0x00000010 -#define NIC_TYPE_NIC1 0x00000011 -#define NIC_TYPE_NIC2 0x00000012 -#define NIC_TYPE_NIC3 0x00000013 -#define NIC_TYPE_ARP 0x00000100 -#define NIC_TYPE_ICMPV6 0x00000200 -#define NIC_TYPE_MASK 0x0000FFFF -#define NIC_TYPE_F_IPV4 0x00010000 -#define NIC_TYPE_F_IPV6 0x00020000 -#define NIC_TYPE_F_DHCP 0x00040000 -#define NIC_TYPE_F_NDP 0x00080000 -#define NIC_TYPE_F_VLAN 0x00100000 - -struct hci_packet { - __dev16 cmd_evt; - __dev16 len; - u8 data[]; -} __packed; - -struct tlv { - u8 type; - u8 len; - u8 *data[]; -} __packed; - -struct sdu_header { - __dev16 cmd_evt; - __dev16 len; - __dev32 dft_eps_id; - __dev32 bearer_ID; - __dev32 nic_type; -} __packed; - -struct sdu { - __dev16 cmd_evt; - __dev16 len; - __dev32 dft_eps_ID; - __dev32 bearer_ID; - __dev32 nic_type; - u8 data[]; -} __packed; - -struct multi_sdu { - __dev16 cmd_evt; - __dev16 len; - __dev16 num_packet; - __dev16 reserved; - u8 data[]; -} __packed; - -struct hci_pdn_table_ind { - __dev16 cmd_evt; - __dev16 len; - u8 activate; - __dev32 dft_eps_id; - __dev32 nic_type; - u8 pdn_type; - u8 ipv4_addr[4]; - u8 ipv6_intf_id[8]; -} __packed; - -struct hci_connect_ind { - __dev16 cmd_evt; - __dev16 len; - __dev32 connect; -} __packed; - -#endif /* _HCI_PACKET_H_ */ diff --git a/drivers/staging/gdm724x/netlink_k.c b/drivers/staging/gdm724x/= netlink_k.c deleted file mode 100644 index 8f39cc5617aa..000000000000 --- a/drivers/staging/gdm724x/netlink_k.c +++ /dev/null @@ -1,128 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved. */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include -#include - -#include "netlink_k.h" - -static DEFINE_MUTEX(netlink_mutex); - -#define ND_MAX_GROUP 30 -#define ND_IFINDEX_LEN sizeof(int) -#define ND_NLMSG_SPACE(len) (NLMSG_SPACE(len) + ND_IFINDEX_LEN) -#define ND_NLMSG_DATA(nlh) ((void *)((char *)NLMSG_DATA(nlh) + \ - ND_IFINDEX_LEN)) -#define ND_NLMSG_S_LEN(len) ((len) + ND_IFINDEX_LEN) -#define ND_NLMSG_R_LEN(nlh) ((nlh)->nlmsg_len - ND_IFINDEX_LEN) -#define ND_NLMSG_IFIDX(nlh) NLMSG_DATA(nlh) -#define ND_MAX_MSG_LEN (1024 * 32) - -static void (*rcv_cb)(struct net_device *dev, u16 type, void *msg, int len= ); - -static void netlink_rcv_cb(struct sk_buff *skb) -{ - struct nlmsghdr *nlh; - struct net_device *dev; - u32 mlen; - void *msg; - int ifindex; - - if (!rcv_cb) { - pr_err("nl cb - unregistered\n"); - return; - } - - if (skb->len < NLMSG_HDRLEN) { - pr_err("nl cb - invalid skb length\n"); - return; - } - - nlh =3D (struct nlmsghdr *)skb->data; - - if (skb->len < nlh->nlmsg_len || nlh->nlmsg_len > ND_MAX_MSG_LEN) { - pr_err("nl cb - invalid length (%d,%d)\n", - skb->len, nlh->nlmsg_len); - return; - } - - memcpy(&ifindex, ND_NLMSG_IFIDX(nlh), ND_IFINDEX_LEN); - msg =3D ND_NLMSG_DATA(nlh); - mlen =3D ND_NLMSG_R_LEN(nlh); - - dev =3D dev_get_by_index(&init_net, ifindex); - if (dev) { - rcv_cb(dev, nlh->nlmsg_type, msg, mlen); - dev_put(dev); - } else { - pr_err("nl cb - dev (%d) not found\n", ifindex); - } -} - -static void netlink_rcv(struct sk_buff *skb) -{ - mutex_lock(&netlink_mutex); - netlink_rcv_cb(skb); - mutex_unlock(&netlink_mutex); -} - -struct sock *netlink_init(int unit, - void (*cb)(struct net_device *dev, u16 type, - void *msg, int len)) -{ - struct sock *sock; - struct netlink_kernel_cfg cfg =3D { - .input =3D netlink_rcv, - }; - - sock =3D netlink_kernel_create(&init_net, unit, &cfg); - - if (sock) - rcv_cb =3D cb; - - return sock; -} - -int netlink_send(struct sock *sock, int group, u16 type, void *msg, int le= n, - struct net_device *dev) -{ - static u32 seq; - struct sk_buff *skb =3D NULL; - struct nlmsghdr *nlh; - int ret =3D 0; - - if (group > ND_MAX_GROUP) - return -EINVAL; - - if (!netlink_has_listeners(sock, group + 1)) - return -ESRCH; - - skb =3D alloc_skb(NLMSG_SPACE(len), GFP_ATOMIC); - if (!skb) - return -ENOMEM; - - seq++; - - nlh =3D nlmsg_put(skb, 0, seq, type, len, 0); - memcpy(NLMSG_DATA(nlh), msg, len); - NETLINK_CB(skb).portid =3D 0; - NETLINK_CB(skb).dst_group =3D 0; - - ret =3D netlink_broadcast(sock, skb, 0, group + 1, GFP_ATOMIC); - if (!ret) - return len; - - if (ret !=3D -ESRCH) - netdev_err(dev, "nl broadcast g=3D%d, t=3D%d, l=3D%d, r=3D%d\n", - group, type, len, ret); - else if (netlink_has_listeners(sock, group + 1)) - return -EAGAIN; - - return ret; -} diff --git a/drivers/staging/gdm724x/netlink_k.h b/drivers/staging/gdm724x/= netlink_k.h deleted file mode 100644 index d42eea9bea3e..000000000000 --- a/drivers/staging/gdm724x/netlink_k.h +++ /dev/null @@ -1,16 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved. */ - -#ifndef _NETLINK_K_H -#define _NETLINK_K_H - -#include -#include - -struct sock *netlink_init(int unit, - void (*cb)(struct net_device *dev, - u16 type, void *msg, int len)); -int netlink_send(struct sock *sock, int group, u16 type, void *msg, int le= n, - struct net_device *dev); - -#endif /* _NETLINK_K_H_ */ --=20 2.43.0