Commit 3765dc92 authored by Shraddha Barke's avatar Shraddha Barke Committed by Greg Kroah-Hartman

Staging: gdm72xx: Remove gdm72xx driver

Remove support for gdm72xx driver from the kernel since Wimax is dead.
[1] http://www.networkworld.com/article/2220370/4g/wimax-is-dead.html
[2] http://www.androidcentral.com/sprint-confirms-wimax-shutdown-november-6-2015

Chrome OS can distribute this driver alongside their library.
Signed-off-by: default avatarShraddha Barke <shraddha.6596@gmail.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent e0a2d503
......@@ -72,8 +72,6 @@ source "drivers/staging/android/Kconfig"
source "drivers/staging/board/Kconfig"
source "drivers/staging/gdm72xx/Kconfig"
source "drivers/staging/gdm724x/Kconfig"
source "drivers/staging/fwserial/Kconfig"
......
......@@ -26,7 +26,6 @@ obj-$(CONFIG_MFD_NVEC) += nvec/
obj-$(CONFIG_STAGING_RDMA) += rdma/
obj-$(CONFIG_ANDROID) += android/
obj-$(CONFIG_STAGING_BOARD) += board/
obj-$(CONFIG_WIMAX_GDM72XX) += gdm72xx/
obj-$(CONFIG_LTE_GDM724X) += gdm724x/
obj-$(CONFIG_FIREWIRE_SERIAL) += fwserial/
obj-$(CONFIG_GOLDFISH) += goldfish/
......
#
# GCT GDM72xx WiMAX driver configuration
#
menuconfig WIMAX_GDM72XX
tristate "GCT GDM72xx WiMAX support"
depends on NET && (USB || MMC)
help
Support a WiMAX module based on the GCT GDM72xx WiMAX chip.
if WIMAX_GDM72XX
config WIMAX_GDM72XX_QOS
bool "Enable QoS support"
default n
help
Enable Quality of Service support based on the data protocol of
transmitting packets.
config WIMAX_GDM72XX_K_MODE
bool "Enable K mode"
default n
help
Enable support for proprietary functions for KT (Korea Telecom).
config WIMAX_GDM72XX_WIMAX2
bool "Enable WiMAX2 support"
default n
help
Enable support for transmitting multiple packets (packet
aggregation) from the WiMAX module to the host processor.
choice
prompt "Select interface"
config WIMAX_GDM72XX_USB
bool "USB interface"
depends on (USB = y || USB = WIMAX_GDM72XX)
help
Select this option if the WiMAX module interfaces with the host
processor via USB.
config WIMAX_GDM72XX_SDIO
bool "SDIO interface"
depends on (MMC = y || MMC = WIMAX_GDM72XX)
help
Select this option if the WiMAX module interfaces with the host
processor via SDIO.
endchoice
if WIMAX_GDM72XX_USB
config WIMAX_GDM72XX_USB_PM
bool "Enable power management support"
depends on PM
help
Enable USB power management in order to reduce power consumption
while the interface is not in use.
endif # WIMAX_GDM72XX_USB
endif # WIMAX_GDM72XX
obj-$(CONFIG_WIMAX_GDM72XX) := gdmwm.o
gdmwm-y += gdm_wimax.o netlink_k.o
gdmwm-$(CONFIG_WIMAX_GDM72XX_QOS) += gdm_qos.o
gdmwm-$(CONFIG_WIMAX_GDM72XX_SDIO) += gdm_sdio.o sdio_boot.o
gdmwm-$(CONFIG_WIMAX_GDM72XX_USB) += gdm_usb.o usb_boot.o
TODO:
- Clean up coding style to meet kernel standard.
This diff is collapsed.
/*
* Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __GDM72XX_GDM_QOS_H__
#define __GDM72XX_GDM_QOS_H__
#include <linux/types.h>
#include <linux/usb.h>
#include <linux/list.h>
#define QOS_MAX 16
#define IPTYPEOFSERVICE 0x8000
#define PROTOCOL 0x4000
#define IPMASKEDSRCADDRESS 0x2000
#define IPMASKEDDSTADDRESS 0x1000
#define PROTOCOLSRCPORTRANGE 0x800
#define PROTOCOLDSTPORTRANGE 0x400
#define DSTMACADDR 0x200
#define SRCMACADDR 0x100
#define ETHERTYPE 0x80
#define IEEE802_1DUSERPRIORITY 0x40
#define IEEE802_1QVLANID 0x10
struct gdm_wimax_csr_s {
bool enabled;
u32 sfid;
u8 qos_buf_count;
u16 classifier_rule_en;
u8 ip2s_lo;
u8 ip2s_hi;
u8 ip2s_mask;
u8 protocol;
u8 ipsrc_addr[16];
u8 ipsrc_addrmask[16];
u8 ipdst_addr[16];
u8 ipdst_addrmask[16];
u16 srcport_lo;
u16 srcport_hi;
u16 dstport_lo;
u16 dstport_hi;
};
struct qos_entry_s {
struct list_head list;
struct sk_buff *skb;
struct net_device *dev;
};
struct qos_cb_s {
struct list_head qos_list[QOS_MAX];
int qos_list_cnt;
int qos_null_idx;
struct gdm_wimax_csr_s csr[QOS_MAX];
spinlock_t qos_lock; /* Protect structure fields */
int qos_limit_size;
};
void gdm_qos_init(void *nic_ptr);
void gdm_qos_release_list(void *nic_ptr);
int gdm_qos_send_hci_pkt(struct sk_buff *skb, struct net_device *dev);
void gdm_recv_qos_hci_packet(void *nic_ptr, u8 *buf, int size);
#endif /* __GDM72XX_GDM_QOS_H__ */
This diff is collapsed.
/*
* Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __GDM72XX_GDM_SDIO_H__
#define __GDM72XX_GDM_SDIO_H__
#include <linux/types.h>
#include <linux/ktime.h>
#define MAX_NR_SDU_BUF 64
struct sdio_tx {
struct list_head list;
struct tx_cxt *tx_cxt;
u8 *buf;
int len;
void (*callback)(void *cb_data);
void *cb_data;
};
struct tx_cxt {
struct list_head free_list;
struct list_head sdu_list;
struct list_head hci_list;
ktime_t sdu_stamp;
u8 *sdu_buf;
spinlock_t lock; /* protect structure fields */
int can_send;
int stop_sdu_tx;
};
struct sdio_rx {
struct list_head list;
struct rx_cxt *rx_cxt;
void (*callback)(void *cb_data, void *data, int len);
void *cb_data;
};
struct rx_cxt {
struct list_head free_list;
struct list_head req_list;
u8 *rx_buf;
spinlock_t lock; /* protect structure fields */
};
struct sdiowm_dev {
struct sdio_func *func;
struct tx_cxt tx;
struct rx_cxt rx;
struct work_struct ws;
};
#endif /* __GDM72XX_GDM_SDIO_H__ */
This diff is collapsed.
/*
* Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __GDM72XX_GDM_USB_H__
#define __GDM72XX_GDM_USB_H__
#include <linux/types.h>
#include <linux/usb.h>
#include <linux/list.h>
#define B_DIFF_DL_DRV BIT(4)
#define B_DOWNLOAD BIT(5)
#define MAX_NR_SDU_BUF 64
struct usb_tx {
struct list_head list;
#if defined(CONFIG_WIMAX_GDM72XX_USB_PM) || defined(CONFIG_WIMAX_GDM72XX_K_MODE)
struct list_head p_list;
#endif
struct tx_cxt *tx_cxt;
struct urb *urb;
u8 *buf;
void (*callback)(void *cb_data);
void *cb_data;
};
struct tx_cxt {
struct list_head free_list;
struct list_head sdu_list;
struct list_head hci_list;
#if defined(CONFIG_WIMAX_GDM72XX_USB_PM) || defined(CONFIG_WIMAX_GDM72XX_K_MODE)
struct list_head pending_list;
#endif
spinlock_t lock; /* Protect structure fields */
};
struct usb_rx {
struct list_head list;
struct rx_cxt *rx_cxt;
struct urb *urb;
u8 *buf;
void (*callback)(void *cb_data, void *data, size_t len);
void *cb_data;
};
struct rx_cxt {
struct list_head free_list;
struct list_head used_list;
spinlock_t lock; /* Protect structure fields */
};
struct usbwm_dev {
struct usb_device *usbdev;
#ifdef CONFIG_WIMAX_GDM72XX_USB_PM
struct work_struct pm_ws;
struct usb_interface *intf;
#endif
#ifdef CONFIG_WIMAX_GDM72XX_K_MODE
int bw_switch;
struct list_head list;
#endif
struct tx_cxt tx;
struct rx_cxt rx;
int padding;
};
#endif /* __GDM72XX_GDM_USB_H__ */
This diff is collapsed.
/*
* Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __GDM72XX_GDM_WIMAX_H__
#define __GDM72XX_GDM_WIMAX_H__
#include <linux/netdevice.h>
#include <linux/types.h>
#include "wm_ioctl.h"
#if defined(CONFIG_WIMAX_GDM72XX_QOS)
#include "gdm_qos.h"
#endif
#define DRIVER_VERSION "3.2.3"
struct phy_dev {
void *priv_dev;
struct net_device *netdev;
int (*send_func)(void *priv_dev, void *data, size_t len,
void (*cb)(void *cb_data), void *cb_data);
int (*rcv_func)(void *priv_dev,
void (*cb)(void *cb_data, void *data, size_t len),
void *cb_data);
};
struct nic {
struct net_device *netdev;
struct phy_dev *phy_dev;
struct data_s sdk_data[SIOC_DATA_MAX];
#if defined(CONFIG_WIMAX_GDM72XX_QOS)
struct qos_cb_s qos;
#endif
};
int register_wimax_device(struct phy_dev *phy_dev, struct device *pdev);
int gdm_wimax_send_tx(struct sk_buff *skb, struct net_device *dev);
void unregister_wimax_device(struct phy_dev *phy_dev);
#endif /* __GDM72XX_GDM_WIMAX_H__ */
/*
* Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __GDM72XX_HCI_H__
#define __GDM72XX_HCI_H__
#define HCI_HEADER_SIZE 4
#define HCI_VALUE_OFFS (HCI_HEADER_SIZE)
#define HCI_MAX_PACKET 2048
#define HCI_MAX_PARAM (HCI_MAX_PACKET - HCI_HEADER_SIZE)
#define HCI_MAX_TLV 32
/* CMD-EVT */
/* Category 0 */
#define WIMAX_RESET 0x0000
#define WIMAX_SET_INFO 0x0001
#define WIMAX_GET_INFO 0x0002
#define WIMAX_GET_INFO_RESULT 0x8003
#define WIMAX_RADIO_OFF 0x0004
#define WIMAX_RADIO_ON 0x0006
#define WIMAX_WIMAX_RESET 0x0007 /* Is this still here */
/* Category 1 */
#define WIMAX_NET_ENTRY 0x0100
#define WIMAX_NET_DISCONN 0x0102
#define WIMAX_ENTER_SLEEP 0x0103
#define WIMAX_EXIT_SLEEP 0x0104
#define WIMAX_ENTER_IDLE 0x0105
#define WIMAX_EXIT_IDLE 0x0106
#define WIMAX_MODE_CHANGE 0x8108
#define WIMAX_HANDOVER 0x8109 /* obsolete */
#define WIMAX_SCAN 0x010d
#define WIMAX_SCAN_COMPLETE 0x810e
#define WIMAX_SCAN_RESULT 0x810f
#define WIMAX_CONNECT 0x0110
#define WIMAX_CONNECT_START 0x8111
#define WIMAX_CONNECT_COMPLETE 0x8112
#define WIMAX_ASSOC_START 0x8113
#define WIMAX_ASSOC_COMPLETE 0x8114
#define WIMAX_DISCONN_IND 0x8115
#define WIMAX_ENTRY_IND 0x8116
#define WIMAX_HO_START 0x8117
#define WIMAX_HO_COMPLETE 0x8118
#define WIMAX_RADIO_STATE_IND 0x8119
#define WIMAX_IP_RENEW_IND 0x811a
#define WIMAX_DISCOVER_NSP 0x011d
#define WIMAX_DISCOVER_NSP_RESULT 0x811e
#define WIMAX_SDU_TX_FLOW 0x8125
/* Category 2 */
#define WIMAX_TX_EAP 0x0200
#define WIMAX_RX_EAP 0x8201
#define WIMAX_TX_SDU 0x0202
#define WIMAX_RX_SDU 0x8203
#define WIMAX_RX_SDU_AGGR 0x8204
#define WIMAX_TX_SDU_AGGR 0x0205
/* Category 3 */
#define WIMAX_DM_CMD 0x030a
#define WIMAX_DM_RSP 0x830b
#define WIMAX_CLI_CMD 0x030c
#define WIMAX_CLI_RSP 0x830d
#define WIMAX_DL_IMAGE 0x0310
#define WIMAX_DL_IMAGE_STATUS 0x8311
#define WIMAX_UL_IMAGE 0x0312
#define WIMAX_UL_IMAGE_RESULT 0x8313
#define WIMAX_UL_IMAGE_STATUS 0x0314
#define WIMAX_EVT_MODEM_REPORT 0x8325
/* Category 0xF */
#define WIMAX_FSM_UPDATE 0x8F01
#define WIMAX_IF_UPDOWN 0x8F02
#define WIMAX_IF_UP 1
#define WIMAX_IF_DOWN 2
/* WIMAX mode */
#define W_NULL 0
#define W_STANDBY 1
#define W_OOZ 2
#define W_AWAKE 3
#define W_IDLE 4
#define W_SLEEP 5
#define W_WAIT 6
#define W_NET_ENTRY_RNG 0x80
#define W_NET_ENTRY_SBC 0x81
#define W_NET_ENTRY_PKM 0x82
#define W_NET_ENTRY_REG 0x83
#define W_NET_ENTRY_DSX 0x84
#define W_NET_ENTRY_RNG_FAIL 0x1100100
#define W_NET_ENTRY_SBC_FAIL 0x1100200
#define W_NET_ENTRY_PKM_FAIL 0x1102000
#define W_NET_ENTRY_REG_FAIL 0x1103000
#define W_NET_ENTRY_DSX_FAIL 0x1104000
/* Scan Type */
#define W_SCAN_ALL_CHANNEL 0
#define W_SCAN_ALL_SUBSCRIPTION 1
#define W_SCAN_SPECIFIED_SUBSCRIPTION 2
/* TLV
*
* [31:31] indicates the type is composite.
* [30:16] is the length of the type. 0 length means length is variable.
* [15:0] is the actual type.
*/
#define TLV_L(x) (((x) >> 16) & 0xff)
#define TLV_T(x) ((x) & 0xff)
#define TLV_COMPOSITE(x) ((x) >> 31)
/* GENERAL */
#define T_MAC_ADDRESS (0x00 | (6 << 16))
#define T_BSID (0x01 | (6 << 16))
#define T_MSK (0x02 | (64 << 16))
#define T_RSSI_THRSHLD (0x03 | (1 << 16))
#define T_FREQUENCY (0x04 | (4 << 16))
#define T_CONN_CS_TYPE (0x05 | (1 << 16))
#define T_HOST_IP_VER (0x06 | (1 << 16))
#define T_STBY_SCAN_INTERVAL (0x07 | (4 << 16))
#define T_OOZ_SCAN_INTERVAL (0x08 | (4 << 16))
#define T_IMEI (0x09 | (8 << 16))
#define T_PID (0x0a | (12 << 16))
#define T_CAPABILITY (0x1a | (4 << 16))
#define T_RELEASE_NUMBER (0x1b | (4 << 16))
#define T_DRIVER_REVISION (0x1c | (4 << 16))
#define T_FW_REVISION (0x1d | (4 << 16))
#define T_MAC_HW_REVISION (0x1e | (4 << 16))
#define T_PHY_HW_REVISION (0x1f | (4 << 16))
/* HANDOVER */
#define T_SCAN_INTERVAL (0x20 | (1 << 16))
#define T_RSC_RETAIN_TIME (0x2f | (2 << 16))
/* SLEEP */
#define T_TYPE1_ISW (0x40 | (1 << 16))
#define T_SLP_START_TO (0x4a | (2 << 16))
/* IDLE */
#define T_IDLE_MODE_TO (0x50 | (2 << 16))
#define T_IDLE_START_TO (0x54 | (2 << 16))
/* MONITOR */
#define T_RSSI (0x60 | (1 << 16))
#define T_CINR (0x61 | (1 << 16))
#define T_TX_POWER (0x6a | (1 << 16))
#define T_CUR_FREQ (0x7f | (4 << 16))
/* WIMAX */
#define T_MAX_SUBSCRIPTION (0xa1 | (1 << 16))
#define T_MAX_SF (0xa2 | (1 << 16))
#define T_PHY_TYPE (0xa3 | (1 << 16))
#define T_PKM (0xa4 | (1 << 16))
#define T_AUTH_POLICY (0xa5 | (1 << 16))
#define T_CS_TYPE (0xa6 | (2 << 16))
#define T_VENDOR_NAME (0xa7 | (0 << 16))
#define T_MOD_NAME (0xa8 | (0 << 16))
#define T_PACKET_FILTER (0xa9 | (1 << 16))
#define T_NSP_CHANGE_COUNT (0xaa | (4 << 16))
#define T_RADIO_STATE (0xab | (1 << 16))
#define T_URI_CONTACT_TYPE (0xac | (1 << 16))
#define T_URI_TEXT (0xad | (0 << 16))
#define T_URI (0xae | (0 << 16))
#define T_ENABLE_AUTH (0xaf | (1 << 16))
#define T_TIMEOUT (0xb0 | (2 << 16))
#define T_RUN_MODE (0xb1 | (1 << 16))
#define T_OMADMT_VER (0xb2 | (4 << 16))
/* This is measured in seconds from 00:00:00 GMT January 1, 1970. */
#define T_RTC_TIME (0xb3 | (4 << 16))
#define T_CERT_STATUS (0xb4 | (4 << 16))
#define T_CERT_MASK (0xb5 | (4 << 16))
#define T_EMSK (0xb6 | (64 << 16))
/* Subscription TLV */
#define T_SUBSCRIPTION_LIST (0xd1 | (0 << 16) | (1 << 31))
#define T_H_NSPID (0xd2 | (3 << 16))
#define T_NSP_NAME (0xd3 | (0 << 16))
#define T_SUBSCRIPTION_NAME (0xd4 | (0 << 16))
#define T_SUBSCRIPTION_FLAG (0xd5 | (2 << 16))
#define T_V_NSPID (0xd6 | (3 << 16))
#define T_NAP_ID (0xd7 | (3 << 16))
#define T_PREAMBLES (0xd8 | (15 << 16))
#define T_BW (0xd9 | (4 << 16))
#define T_FFTSIZE (0xda | (4 << 16))
#define T_DUPLEX_MODE (0xdb | (4 << 16))
/* T_CAPABILITY */
#define T_CAPABILITY_MULTI_CS BIT(0)
#define T_CAPABILITY_WIMAX BIT(1)
#define T_CAPABILITY_QOS BIT(2)
#define T_CAPABILITY_AGGREGATION BIT(3)
struct hci_s {
__be16 cmd_evt;
__be16 length;
u8 data[0];
} __packed;
#endif /* __GDM72XX_HCI_H__ */
/*
* Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h>
#include <linux/etherdevice.h>
#include <net/netlink.h>
#include <asm/byteorder.h>
#include <net/sock.h>
#include "netlink_k.h"
#if !defined(NLMSG_HDRLEN)
#define NLMSG_HDRLEN ((int)NLMSG_ALIGN(sizeof(struct nlmsghdr)))
#endif
#define ND_MAX_GROUP 30
#define ND_IFINDEX_LEN sizeof(int)
#define ND_NLMSG_SPACE(len) (nlmsg_total_size(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 8096
#if defined(DEFINE_MUTEX)
static DEFINE_MUTEX(netlink_mutex);
#else
static struct semaphore netlink_mutex;
#define mutex_lock(x) down(x)
#define mutex_unlock(x) up(x)
#endif
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 (skb->len >= NLMSG_HDRLEN) {
nlh = (struct nlmsghdr *)skb->data;
if (nlh->nlmsg_len < ND_IFINDEX_LEN ||
nlh->nlmsg_len > skb->len ||
nlh->nlmsg_len > ND_MAX_MSG_LEN) {
netdev_err(skb->dev, "Invalid length (%d,%d)\n",
skb->len, nlh->nlmsg_len);
return;
}
memcpy(&ifindex, ND_NLMSG_IFIDX(nlh), ND_IFINDEX_LEN);
msg = ND_NLMSG_DATA(nlh);
mlen = ND_NLMSG_R_LEN(nlh);
if (rcv_cb) {
dev = dev_get_by_index(&init_net, ifindex);
if (dev) {
rcv_cb(dev, nlh->nlmsg_type, msg, mlen);
dev_put(dev);
} else
netdev_err(skb->dev,
"dev_get_by_index(%d) is not found.\n",
ifindex);
} else {
netdev_err(skb->dev, "Unregistered Callback\n");
}
}
}
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 = {
.input = netlink_rcv,
};
#if !defined(DEFINE_MUTEX)
init_MUTEX(&netlink_mutex);
#endif
sock = netlink_kernel_create(&init_net, unit, &cfg);
if (sock)
rcv_cb = cb;
return sock;
}
void netlink_exit(struct sock *sock)
{
netlink_kernel_release(sock);
}
int netlink_send(struct sock *sock, u16 group, u16 type, void *msg, int len)
{
static u32 seq;
struct sk_buff *skb = NULL;
struct nlmsghdr *nlh;
int ret = 0;
if (group > ND_MAX_GROUP) {
pr_err("Group %d is invalid.\n", group);
pr_err("Valid group is 0 ~ %d.\n", ND_MAX_GROUP);
return -EINVAL;
}
skb = nlmsg_new(len, GFP_ATOMIC);
if (!skb) {
pr_err("netlink_broadcast ret=%d\n", ret);
return -ENOMEM;
}
seq++;
nlh = nlmsg_put(skb, 0, seq, type, len, 0);
if (!nlh) {
kfree_skb(skb);
return -EMSGSIZE;
}
memcpy(nlmsg_data(nlh), msg, len);
NETLINK_CB(skb).portid = 0;
NETLINK_CB(skb).dst_group = 0;
ret = netlink_broadcast(sock, skb, 0, group + 1, GFP_ATOMIC);
if (!ret)
return len;
if (ret != -ESRCH) {
pr_err("netlink_broadcast g=%d, t=%d, l=%d, r=%d\n",
group, type, len, ret);
}
return 0;
}
/*
* Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __GDM72XX_NETLINK_K_H__
#define __GDM72XX_NETLINK_K_H__
#include <linux/netdevice.h>
#include <net/sock.h>
struct sock *netlink_init(int unit, void (*cb)(struct net_device *dev, u16 type,
void *msg, int len));
void netlink_exit(struct sock *sock);
int netlink_send(struct sock *sock, u16 group, u16 type, void *msg, int len);
#endif /* __GDM72XX_NETLINK_K_H__ */
/*
* Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/uaccess.h>
#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/mmc/core.h>
#include <linux/mmc/card.h>
#include <linux/mmc/sdio_func.h>
#include <linux/firmware.h>
#include "gdm_sdio.h"
#include "sdio_boot.h"
#define TYPE_A_HEADER_SIZE 4
#define TYPE_A_LOOKAHEAD_SIZE 16
#define YMEM0_SIZE 0x8000 /* 32kbytes */
#define DOWNLOAD_SIZE (YMEM0_SIZE - TYPE_A_HEADER_SIZE)
#define FW_DIR "gdm72xx/"
#define FW_KRN "gdmskrn.bin"
#define FW_RFS "gdmsrfs.bin"
static u8 *tx_buf;
static int ack_ready(struct sdio_func *func)
{
unsigned long wait = jiffies + HZ;
u8 val;
int ret;
while (time_before(jiffies, wait)) {
val = sdio_readb(func, 0x13, &ret);
if (val & 0x01)
return 1;
schedule();
}
return 0;
}
static int download_image(struct sdio_func *func, const char *img_name)
{
int ret = 0, len, pno;
u8 *buf = tx_buf;
loff_t pos = 0;
int img_len;
const struct firmware *firm;
ret = request_firmware(&firm, img_name, &func->dev);
if (ret < 0) {
dev_err(&func->dev,
"requesting firmware %s failed with error %d\n",
img_name, ret);
return ret;
}
buf = kmalloc(DOWNLOAD_SIZE + TYPE_A_HEADER_SIZE, GFP_KERNEL);
if (!buf)
return -ENOMEM;
img_len = firm->size;
if (img_len <= 0) {
ret = -1;
goto out;
}
pno = 0;
while (img_len > 0) {
if (img_len > DOWNLOAD_SIZE) {
len = DOWNLOAD_SIZE;
buf[3] = 0;
} else {
len = img_len; /* the last packet */
buf[3] = 2;
}
buf[0] = len & 0xff;
buf[1] = (len >> 8) & 0xff;
buf[2] = (len >> 16) & 0xff;
memcpy(buf + TYPE_A_HEADER_SIZE, firm->data + pos, len);
ret = sdio_memcpy_toio(func, 0, buf, len + TYPE_A_HEADER_SIZE);
if (ret < 0) {
dev_err(&func->dev,
"send image error: packet number = %d ret = %d\n",
pno, ret);
goto out;
}
if (buf[3] == 2) /* The last packet */
break;
if (!ack_ready(func)) {
ret = -EIO;
dev_err(&func->dev, "Ack is not ready.\n");
goto out;
}
ret = sdio_memcpy_fromio(func, buf, 0, TYPE_A_LOOKAHEAD_SIZE);
if (ret < 0) {
dev_err(&func->dev,
"receive ack error: packet number = %d ret = %d\n",
pno, ret);
goto out;
}
sdio_writeb(func, 0x01, 0x13, &ret);
sdio_writeb(func, 0x00, 0x10, &ret); /* PCRRT */
img_len -= DOWNLOAD_SIZE;
pos += DOWNLOAD_SIZE;
pno++;
}
out:
kfree(buf);
return ret;
}
int sdio_boot(struct sdio_func *func)
{
int ret;
const char *krn_name = FW_DIR FW_KRN;
const char *rfs_name = FW_DIR FW_RFS;
tx_buf = kmalloc(YMEM0_SIZE, GFP_KERNEL);
if (!tx_buf)
return -ENOMEM;
ret = download_image(func, krn_name);
if (ret)
goto restore_fs;
dev_info(&func->dev, "GCT: Kernel download success.\n");
ret = download_image(func, rfs_name);
if (ret)
goto restore_fs;
dev_info(&func->dev, "GCT: Filesystem download success.\n");
restore_fs:
kfree(tx_buf);
return ret;
}
/*
* Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __GDM72XX_SDIO_BOOT_H__
#define __GDM72XX_SDIO_BOOT_H__
struct sdio_func;
int sdio_boot(struct sdio_func *func);
#endif /* __GDM72XX_SDIO_BOOT_H__ */
/*
* Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/uaccess.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/usb.h>
#include <linux/unistd.h>
#include <linux/slab.h>
#include <linux/firmware.h>
#include <asm/byteorder.h>
#include "gdm_usb.h"
#include "usb_boot.h"
#define DN_KERNEL_MAGIC_NUMBER 0x10760001
#define DN_ROOTFS_MAGIC_NUMBER 0x10760002
#define DOWNLOAD_SIZE 1024
#define MAX_IMG_CNT 16
#define FW_DIR "gdm72xx/"
#define FW_UIMG "gdmuimg.bin"
#define FW_KERN "zImage"
#define FW_FS "ramdisk.jffs2"
struct dn_header {
__be32 magic_num;
__be32 file_size;
};
struct img_header {
u32 magic_code;
u32 count;
u32 len;
u32 offset[MAX_IMG_CNT];
char hostname[32];
char date[32];
};
struct fw_info {
u32 id;
u32 len;
u32 kernel_len;
u32 rootfs_len;
u32 kernel_offset;
u32 rootfs_offset;
u32 fw_ver;
u32 mac_ver;
char hostname[32];
char userid[16];
char date[32];
char user_desc[128];
};
static void array_le32_to_cpu(u32 *arr, int num)
{
int i;
for (i = 0; i < num; i++, arr++)
le32_to_cpus(arr);
}
static u8 *tx_buf;
static int gdm_wibro_send(struct usb_device *usbdev, void *data, int len)
{
int ret;
int actual;
ret = usb_bulk_msg(usbdev, usb_sndbulkpipe(usbdev, 1), data, len,
&actual, 1000);
if (ret < 0) {
dev_err(&usbdev->dev, "Error : usb_bulk_msg ( result = %d )\n",
ret);
return ret;
}
return 0;
}
static int gdm_wibro_recv(struct usb_device *usbdev, void *data, int len)
{
int ret;
int actual;
ret = usb_bulk_msg(usbdev, usb_rcvbulkpipe(usbdev, 2), data, len,
&actual, 5000);
if (ret < 0) {
dev_err(&usbdev->dev,
"Error : usb_bulk_msg(recv) ( result = %d )\n", ret);
return ret;
}
return 0;
}
static int download_image(struct usb_device *usbdev,
const struct firmware *firm,
loff_t pos, u32 img_len, u32 magic_num)
{
struct dn_header h;
int ret = 0;
u32 size;
size = ALIGN(img_len, DOWNLOAD_SIZE);
h.magic_num = cpu_to_be32(magic_num);
h.file_size = cpu_to_be32(size);
ret = gdm_wibro_send(usbdev, &h, sizeof(h));
if (ret < 0)
return ret;
while (img_len > 0) {
if (img_len > DOWNLOAD_SIZE)
size = DOWNLOAD_SIZE;
else
size = img_len; /* the last chunk of data */
memcpy(tx_buf, firm->data + pos, size);
ret = gdm_wibro_send(usbdev, tx_buf, size);
if (ret < 0)
return ret;
img_len -= size;
pos += size;
}
return ret;
}
int usb_boot(struct usb_device *usbdev, u16 pid)
{
int i, ret = 0;
struct img_header hdr;
struct fw_info fw_info;
loff_t pos = 0;
char *img_name = FW_DIR FW_UIMG;
const struct firmware *firm;
ret = request_firmware(&firm, img_name, &usbdev->dev);
if (ret < 0) {
dev_err(&usbdev->dev,
"requesting firmware %s failed with error %d\n",
img_name, ret);
return ret;
}
tx_buf = kmalloc(DOWNLOAD_SIZE, GFP_KERNEL);
if (!tx_buf) {
release_firmware(firm);
return -ENOMEM;
}
if (firm->size < sizeof(hdr)) {
dev_err(&usbdev->dev, "Cannot read the image info.\n");
ret = -EIO;
goto out;
}
memcpy(&hdr, firm->data, sizeof(hdr));
array_le32_to_cpu((u32 *)&hdr, 19);
if (hdr.count > MAX_IMG_CNT) {
dev_err(&usbdev->dev, "Too many images. %d\n", hdr.count);
ret = -EINVAL;
goto out;
}
for (i = 0; i < hdr.count; i++) {
if (hdr.offset[i] > hdr.len) {
dev_err(&usbdev->dev,
"Invalid offset. Entry = %d Offset = 0x%08x Image length = 0x%08x\n",
i, hdr.offset[i], hdr.len);
ret = -EINVAL;
goto out;
}
pos = hdr.offset[i];
if (firm->size < sizeof(fw_info) + pos) {
dev_err(&usbdev->dev, "Cannot read the FW info.\n");
ret = -EIO;
goto out;
}
memcpy(&fw_info, firm->data + pos, sizeof(fw_info));
array_le32_to_cpu((u32 *)&fw_info, 8);
if ((fw_info.id & 0xffff) != pid)
continue;
pos = hdr.offset[i] + fw_info.kernel_offset;
if (firm->size < fw_info.kernel_len + pos) {
dev_err(&usbdev->dev, "Kernel FW is too small.\n");
goto out;
}
ret = download_image(usbdev, firm, pos, fw_info.kernel_len,
DN_KERNEL_MAGIC_NUMBER);
if (ret < 0)
goto out;
dev_info(&usbdev->dev, "GCT: Kernel download success.\n");
pos = hdr.offset[i] + fw_info.rootfs_offset;
if (firm->size < fw_info.rootfs_len + pos) {
dev_err(&usbdev->dev, "Filesystem FW is too small.\n");
goto out;
}
ret = download_image(usbdev, firm, pos, fw_info.rootfs_len,
DN_ROOTFS_MAGIC_NUMBER);
if (ret < 0)
goto out;
dev_info(&usbdev->dev, "GCT: Filesystem download success.\n");
break;
}
if (i == hdr.count) {
dev_err(&usbdev->dev, "Firmware for gsk%x is not installed.\n",
pid);
ret = -EINVAL;
}
out:
release_firmware(firm);
kfree(tx_buf);
return ret;
}
/*#define GDM7205_PADDING 256 */
#define DOWNLOAD_CHUCK 2048
#define KERNEL_TYPE_STRING "linux"
#define FS_TYPE_STRING "rootfs"
static int em_wait_ack(struct usb_device *usbdev, int send_zlp)
{
int ack;
int ret = -1;
if (send_zlp) {
/*Send ZLP*/
ret = gdm_wibro_send(usbdev, NULL, 0);
if (ret < 0)
goto out;
}
/*Wait for ACK*/
ret = gdm_wibro_recv(usbdev, &ack, sizeof(ack));
if (ret < 0)
goto out;
out:
return ret;
}
static int em_download_image(struct usb_device *usbdev, const char *img_name,
char *type_string)
{
char *buf = NULL;
loff_t pos = 0;
int ret = 0;
int len;
int img_len;
const struct firmware *firm;
#if defined(GDM7205_PADDING)
const int pad_size = GDM7205_PADDING;
#else
const int pad_size = 0;
#endif
ret = request_firmware(&firm, img_name, &usbdev->dev);
if (ret < 0) {
dev_err(&usbdev->dev,
"requesting firmware %s failed with error %d\n",
img_name, ret);
return ret;
}
buf = kzalloc(DOWNLOAD_CHUCK + pad_size, GFP_KERNEL);
if (!buf) {
release_firmware(firm);
return -ENOMEM;
}
strcpy(buf + pad_size, type_string);
ret = gdm_wibro_send(usbdev, buf, strlen(type_string) + pad_size);
if (ret < 0)
goto out;
img_len = firm->size;
if (img_len <= 0) {
ret = -1;
goto out;
}
while (img_len > 0) {
if (img_len > DOWNLOAD_CHUCK)
len = DOWNLOAD_CHUCK;
else
len = img_len; /* the last chunk of data */
memcpy(buf + pad_size, firm->data + pos, len);
ret = gdm_wibro_send(usbdev, buf, len + pad_size);
if (ret < 0)
goto out;
img_len -= DOWNLOAD_CHUCK;
pos += DOWNLOAD_CHUCK;
ret = em_wait_ack(usbdev, ((len + pad_size) % 512 == 0));
if (ret < 0)
goto out;
}
ret = em_wait_ack(usbdev, 1);
if (ret < 0)
goto out;
out:
release_firmware(firm);
kfree(buf);
return ret;
}
static int em_fw_reset(struct usb_device *usbdev)
{
/*Send ZLP*/
return gdm_wibro_send(usbdev, NULL, 0);
}
int usb_emergency(struct usb_device *usbdev)
{
int ret;
const char *kern_name = FW_DIR FW_KERN;
const char *fs_name = FW_DIR FW_FS;
ret = em_download_image(usbdev, kern_name, KERNEL_TYPE_STRING);
if (ret < 0)
return ret;
dev_err(&usbdev->dev, "GCT Emergency: Kernel download success.\n");
ret = em_download_image(usbdev, fs_name, FS_TYPE_STRING);
if (ret < 0)
return ret;
dev_info(&usbdev->dev, "GCT Emergency: Filesystem download success.\n");
return em_fw_reset(usbdev);
}
/*
* Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __GDM72XX_USB_BOOT_H__
#define __GDM72XX_USB_BOOT_H__
struct usb_device;
int usb_boot(struct usb_device *usbdev, u16 pid);
int usb_emergency(struct usb_device *usbdev);
#endif /* __GDM72XX_USB_BOOT_H__ */
/*
* Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __GDM72XX_USB_IDS_H__
#define __GDM72XX_USB_IDS_H__
/*You can replace vendor-ID as yours.*/
#define GCT_VID 0x1076
/*You can replace product-ID as yours.*/
#define GCT_PID1 0x7e00
#define GCT_PID2 0x7f00
#define USB_DEVICE_ID_MATCH_DEVICE_INTERFACE \
(USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_CLASS)
#define USB_DEVICE_INTF(vend, prod, intf) \
.match_flags = USB_DEVICE_ID_MATCH_DEVICE_INTERFACE, \
.idVendor = (vend), .idProduct = (prod), .bInterfaceClass = (intf)
#define EMERGENCY_PID 0x720f
#define BL_PID_MASK 0xffc0
#define USB_DEVICE_BOOTLOADER(vid, pid) \
{USB_DEVICE((vid), ((pid) & BL_PID_MASK) | B_DOWNLOAD)}
#define USB_DEVICE_BOOTLOADER_DRV(vid, pid) \
{USB_DEVICE((vid), ((pid) & BL_PID_MASK) | B_DOWNLOAD | B_DIFF_DL_DRV)}
#define USB_DEVICE_CDC_DATA(vid, pid) \
{USB_DEVICE_INTF((vid), (pid), USB_CLASS_CDC_DATA)}
static const struct usb_device_id id_table[] = {
USB_DEVICE_BOOTLOADER(GCT_VID, GCT_PID1),
USB_DEVICE_BOOTLOADER_DRV(GCT_VID, GCT_PID1),
USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID1),
USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID1 + 0x1),
USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID1 + 0x2),
USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID1 + 0x3),
USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID1 + 0x4),
USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID1 + 0x5),
USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID1 + 0x6),
USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID1 + 0x7),
USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID1 + 0x8),
USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID1 + 0x9),
USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID1 + 0xa),
USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID1 + 0xb),
USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID1 + 0xc),
USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID1 + 0xd),
USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID1 + 0xe),
USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID1 + 0xf),
USB_DEVICE_BOOTLOADER(GCT_VID, GCT_PID2),
USB_DEVICE_BOOTLOADER_DRV(GCT_VID, GCT_PID2),
USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID2),
USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID2 + 0x1),
USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID2 + 0x2),
USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID2 + 0x3),
USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID2 + 0x4),
USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID2 + 0x5),
USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID2 + 0x6),
USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID2 + 0x7),
USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID2 + 0x8),
USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID2 + 0x9),
USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID2 + 0xa),
USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID2 + 0xb),
USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID2 + 0xc),
USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID2 + 0xd),
USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID2 + 0xe),
USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID2 + 0xf),
{USB_DEVICE(GCT_VID, EMERGENCY_PID)},
{ }
};
#endif /* __GDM72XX_USB_IDS_H__ */
/*
* Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __GDM72XX_WM_IOCTL_H__
#define __GDM72XX_WM_IOCTL_H__
#if !defined(__KERNEL__)
#include <net/if.h>
#endif
#define NETLINK_WIMAX 31
#define SIOCWMIOCTL SIOCDEVPRIVATE
#define SIOCG_DATA 0x8D10
#define SIOCS_DATA 0x8D11
enum {
SIOC_DATA_FSM,
SIOC_DATA_NETLIST,
SIOC_DATA_CONNNSP,
SIOC_DATA_CONNCOMP,
SIOC_DATA_PROFILEID,
SIOC_DATA_END
};
#define SIOC_DATA_MAX 16
/* FSM */
enum {
M_INIT = 0,
M_OPEN_OFF,
M_OPEN_ON,
M_SCAN,
M_CONNECTING,
M_CONNECTED,
M_FSM_END,
C_INIT = 0,
C_CONNSTART,
C_ASSOCSTART,
C_RNG,
C_SBC,
C_AUTH,
C_REG,
C_DSX,
C_ASSOCCOMPLETE,
C_CONNCOMPLETE,
C_FSM_END,
D_INIT = 0,
D_READY,
D_LISTEN,
D_IPACQUISITION,
END_FSM
};
struct fsm_s {
int m_status; /*main status*/
int c_status; /*connection status*/
int d_status; /*oma-dm status*/
};
struct data_s {
unsigned int size;
void *buf;
};
struct udata_s {
unsigned int size;
void __user *buf;
};
struct wm_req_s {
union {
char ifrn_name[IFNAMSIZ];
} ifr_ifrn;
unsigned short cmd;
unsigned short data_id;
struct udata_s data;
/* NOTE: sizeof(struct wm_req_s) must be less than sizeof(struct ifreq). */
};
#ifndef ifr_name
#define ifr_name ifr_ifrn.ifrn_name
#endif
#endif /* __GDM72XX_WM_IOCTL_H__ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment