summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/eagle/testmode.c
diff options
context:
space:
mode:
authorSrikant Patnaik2015-01-11 12:28:04 +0530
committerSrikant Patnaik2015-01-11 12:28:04 +0530
commit871480933a1c28f8a9fed4c4d34d06c439a7a422 (patch)
tree8718f573808810c2a1e8cb8fb6ac469093ca2784 /drivers/net/wireless/eagle/testmode.c
parent9d40ac5867b9aefe0722bc1f110b965ff294d30d (diff)
downloadFOSSEE-netbook-kernel-source-871480933a1c28f8a9fed4c4d34d06c439a7a422.tar.gz
FOSSEE-netbook-kernel-source-871480933a1c28f8a9fed4c4d34d06c439a7a422.tar.bz2
FOSSEE-netbook-kernel-source-871480933a1c28f8a9fed4c4d34d06c439a7a422.zip
Moved, renamed, and deleted files
The original directory structure was scattered and unorganized. Changes are basically to make it look like kernel structure.
Diffstat (limited to 'drivers/net/wireless/eagle/testmode.c')
-rwxr-xr-xdrivers/net/wireless/eagle/testmode.c619
1 files changed, 619 insertions, 0 deletions
diff --git a/drivers/net/wireless/eagle/testmode.c b/drivers/net/wireless/eagle/testmode.c
new file mode 100755
index 00000000..0c9de755
--- /dev/null
+++ b/drivers/net/wireless/eagle/testmode.c
@@ -0,0 +1,619 @@
+
+/*
+ * Copyright (c) 2011 Espressif System.
+ *
+ * MAC80211 support module
+ */
+#ifdef TEST_MODE
+
+#include <linux/etherdevice.h>
+#include <linux/workqueue.h>
+#include <linux/nl80211.h>
+#include <linux/ieee80211.h>
+#include <linux/slab.h>
+#include <net/cfg80211.h>
+#include <net/mac80211.h>
+#include <net/genetlink.h>
+#include "esp_pub.h"
+#include "esp_sip.h"
+#include "esp_ctrl.h"
+#include "esp_sif.h"
+#include "esp_debug.h"
+#include "esp_wl.h"
+#include "testmode.h"
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31))
+ #include <net/regulatory.h>
+#endif
+
+static u32 connected_nl;
+static struct genl_info info_copy;
+static struct esp_sip *sip_copy = NULL;
+static u8 *sdio_buff = NULL;
+
+#define SIP sip_copy
+#define OUT_DONE() \
+ do { \
+ printk(KERN_DEBUG "esp_sdio: error occured in %s\n", __func__); \
+ } while(0)
+
+/* ESP TEST netlinf family */
+static struct genl_family test_genl_family = {
+ .id = GENL_ID_GENERATE,
+ .hdrsize = 0,
+ .name = "esp_sdio",
+ .version = 1,
+ .maxattr = TEST_ATTR_MAX,
+};
+
+struct loopback_param_s {
+ u32 packet_num;
+ u32 packet_id;
+};
+
+static struct loopback_param_s loopback_param;
+u32 get_loopback_num()
+{
+ return loopback_param.packet_num;
+}
+
+u32 get_loopback_id()
+{
+ return loopback_param.packet_id;
+}
+
+void inc_loopback_id()
+{
+ loopback_param.packet_id++;
+}
+
+#define REGISTER_REPLY(info) \
+ memcpy((char *)&info_copy, (char *)(info), sizeof(struct genl_info))
+
+
+static void sip_send_test_cmd(struct esp_sip *sip, struct sk_buff *skb)
+{
+ skb_queue_tail(&sip->epub->txq, skb);
+
+#if !defined(FPGA_LOOPBACK) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32))
+ ieee80211_queue_work(sip->epub->hw, &sip->epub->tx_work);
+#else
+ queue_work(sip->epub->esp_wkq, &sip->epub->tx_work);
+#endif
+
+}
+
+static int esp_test_cmd_reply(struct genl_info *info, u32 cmd_type, char *reply_info)
+{
+ struct sk_buff *skb;
+ void *hdr;
+
+ /*directly send ask_info to target, and waiting for report*/
+ skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+ if (skb == NULL)
+ goto out;
+
+ hdr = genlmsg_put(skb, info->snd_pid, info->snd_seq, &test_genl_family, 0, cmd_type);
+ if (hdr == NULL)
+ goto nla_put_failure;
+
+ NLA_PUT_STRING(skb, TEST_ATTR_STR, reply_info);
+
+ genlmsg_end(skb, hdr);
+ genlmsg_reply(skb, info);
+ return 0;
+
+nla_put_failure:
+ nlmsg_free(skb);
+out:
+ OUT_DONE();
+ return -EINVAL;
+}
+
+static int esp_test_echo(struct sk_buff *skb_2,
+ struct genl_info *info)
+{
+ char *echo_info;
+ int res;
+
+ if (info == NULL)
+ goto out;
+
+ connected_nl = info->snd_pid;
+ printk(KERN_DEBUG "esp_sdio: received a echo, "
+ "from pid %d\n", info->snd_pid);
+ sip_debug_show(SIP);
+
+ /*get echo info*/
+ echo_info = nla_data(info->attrs[TEST_ATTR_STR]);
+
+ res=esp_test_cmd_reply(info, TEST_CMD_ECHO, echo_info);
+ return res;
+out:
+ OUT_DONE();
+ return -EINVAL;
+}
+
+static int esp_test_sdiospeed(struct sk_buff *skb_2,
+ struct genl_info *info)
+{
+ char *speed_info;
+ int res;
+
+ if (info == NULL)
+ goto out;
+
+ connected_nl = info->snd_pid;
+
+ /*get echo info*/
+ speed_info = nla_data(info->attrs[TEST_ATTR_STR]);
+
+ printk(KERN_DEBUG "esp_sdio: received a sdio speed %s, "
+ "from pid %d\n", speed_info, info->snd_pid);
+
+ if (!strcmp(speed_info, "high")) {
+ sif_platform_target_speed(1);
+ } else if (!strcmp(speed_info, "low")) {
+ sif_platform_target_speed(0);
+ } else {
+ printk(KERN_DEBUG "%s: %s unsupported\n", __func__, speed_info);
+ }
+
+ res=esp_test_cmd_reply(info, TEST_CMD_SDIOSPEED, speed_info);
+ return res;
+out:
+ OUT_DONE();
+ return -EINVAL;
+}
+
+static int esp_test_ask(struct sk_buff *skb_2,
+ struct genl_info *info)
+{
+ char *ask_info;
+ int res;
+
+ if (info == NULL)
+ goto out;
+
+ /*get echo info*/
+ ask_info = nla_data(info->attrs[TEST_ATTR_STR]);
+
+ /*directly send ask_info to target, and waiting for report*/
+ res=esp_test_cmd_reply(info, TEST_CMD_ASK, "ok");
+ return res;
+out:
+ OUT_DONE();
+ return -EINVAL;
+}
+
+static int esp_test_sleep(struct sk_buff *skb_2,
+ struct genl_info *info)
+{
+ struct sip_cmd_sleep *sleepcmd;
+ struct sk_buff *skb = NULL;
+ int res;
+
+ if (info == NULL)
+ goto out;
+
+ skb = sip_alloc_ctrl_skbuf(SIP, sizeof(struct sip_cmd_sleep), SIP_CMD_SLEEP);
+ if (!skb)
+ goto out;
+
+ sleepcmd = (struct sip_cmd_sleep *)(skb->data + sizeof(struct sip_tx_info));
+ sleepcmd->sleep_mode = nla_get_u32(info->attrs[TEST_ATTR_PARA0]);
+ sleepcmd->sleep_tm_ms = nla_get_u32(info->attrs[TEST_ATTR_PARA1]);
+ sleepcmd->wakeup_tm_ms = nla_get_u32(info->attrs[TEST_ATTR_PARA2]);
+ sleepcmd->sleep_times = nla_get_u32(info->attrs[TEST_ATTR_PARA3]);
+
+ sip_send_test_cmd(SIP, skb);
+
+ /*directly send ask_info to target, and waiting for report*/
+ res=esp_test_cmd_reply(info, TEST_CMD_SLEEP, "ok");
+ return res;
+out:
+ OUT_DONE();
+ return -EINVAL;
+}
+
+static int esp_test_wakeup(struct sk_buff *skb_2,
+ struct genl_info *info)
+{
+ struct sip_cmd_wakeup *wakeupcmd;
+ struct sk_buff *skb = NULL;
+ //int res;
+
+ if (info == NULL)
+ goto out;
+
+ skb = sip_alloc_ctrl_skbuf(SIP, sizeof(struct sip_cmd_wakeup), SIP_CMD_WAKEUP);
+ if (!skb)
+ goto out;
+ wakeupcmd = (struct sip_cmd_wakeup *)(skb->data + sizeof(struct sip_tx_info));
+ wakeupcmd->check_data = nla_get_u32(info->attrs[TEST_ATTR_PARA0]);
+
+ /*directly send reply_info to target, and waiting for report*/
+ REGISTER_REPLY(info);
+ //res=esp_test_cmd_reply(info, TEST_CMD_WAKEUP, "ok");
+
+ sip_send_test_cmd(SIP, skb);
+ return 0;
+out:
+ OUT_DONE();
+ return -EINVAL;
+}
+
+static int esp_test_loopback(struct sk_buff *skb_2,
+ struct genl_info *info)
+{
+ u32 txpacket_len;
+ u32 rxpacket_len;
+
+ if (info == NULL)
+ goto out;
+
+ txpacket_len = nla_get_u32(info->attrs[TEST_ATTR_PARA0]);
+ rxpacket_len = nla_get_u32(info->attrs[TEST_ATTR_PARA1]);
+ loopback_param.packet_num = nla_get_u32(info->attrs[TEST_ATTR_PARA2]);
+ loopback_param.packet_id=0;
+ REGISTER_REPLY(info);
+ return sip_send_loopback_mblk(SIP, txpacket_len, rxpacket_len, 0);
+out:
+ OUT_DONE();
+ return -EINVAL;
+}
+
+/*
+u8 probe_req_frm[] = {0x40,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x03,0x8F,0x11,0x22,0x88,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x01,0x08,0x82,0x84,0x8B,0x96,
+ 0x0C,0x12,0x18,0x24,0x32,0x04,0x30,0x48,0x60,0x6C
+ };
+*/
+
+static int sip_send_tx_frame(struct esp_sip *sip, u32 packet_len)
+{
+
+ struct sk_buff *skb = NULL;
+ u8 *ptr = NULL;
+ int i;
+
+ skb = alloc_skb(packet_len, GFP_KERNEL);
+ skb->len = packet_len;
+ ptr = skb->data;
+ /* fill up pkt payload */
+ for (i = 0; i < skb->len; i++) {
+ ptr[i] = i;
+ }
+#ifdef FPGA_LOOPBACK
+ skb_queue_tail(&sip->epub->txq, skb);
+ queue_work(sip->epub->esp_wkq, &sip->epub->tx_work);
+#else
+ sip_tx_data_pkt_enqueue(sip->epub, skb);
+ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32))
+ ieee80211_queue_work(sip->epub->hw, &sip->epub->tx_work);
+ #else
+ queue_work(sip->epub->esp_wkq, &sip->epub->tx_work);
+ #endif
+#endif
+ return 0;
+}
+
+static int esp_test_tx(struct sk_buff *skb_2,
+ struct genl_info *info)
+{
+ u32 txpacket_len;
+ u32 res;
+
+ if (info == NULL)
+ goto out;
+
+ txpacket_len = nla_get_u32(info->attrs[TEST_ATTR_PARA0]);
+ REGISTER_REPLY(info);
+ sip_send_tx_frame(SIP, txpacket_len);
+ res=esp_test_cmd_reply(info, TEST_CMD_TX, "tx out");
+ return res;
+out:
+ OUT_DONE();
+ return -EINVAL;
+}
+
+static int esp_test_genl(struct sk_buff *skb_2,
+ struct genl_info *info)
+{
+ struct sip_cmd_debug *dbgcmd;
+ struct sk_buff *skb = NULL;
+ int i;
+
+ if (info == NULL)
+ goto out;
+
+ skb = sip_alloc_ctrl_skbuf(SIP, sizeof(struct sip_cmd_debug), SIP_CMD_DEBUG);
+ if (!skb)
+ goto out;
+
+ dbgcmd = (struct sip_cmd_debug *)(skb->data + sizeof(struct sip_hdr));
+ dbgcmd->cmd_type = nla_get_u32(info->attrs[TEST_ATTR_CMD_TYPE]);
+ dbgcmd->para_num = nla_get_u32(info->attrs[TEST_ATTR_PARA_NUM]);
+ printk(KERN_DEBUG "%s dbgcmdType %d paraNum %d\n", __func__, dbgcmd->cmd_type, dbgcmd->para_num);
+ for (i=0; i<dbgcmd->para_num; i++)
+ dbgcmd->para[i] = nla_get_u32(info->attrs[TEST_ATTR_PARA(i)]);
+
+ /*directly send reply_info to target, and waiting for report*/
+ REGISTER_REPLY(info);
+
+ sip_send_test_cmd(SIP, skb);
+ return 0;
+out:
+ OUT_DONE();
+ return -EINVAL;
+}
+
+static int esp_test_sdio_wr(struct sk_buff *skb_2,
+ struct genl_info *info)
+{
+ int res;
+ u32 func_no, addr, value;
+
+ if (info == NULL)
+ goto out;
+
+ func_no = nla_get_u32(info->attrs[TEST_ATTR_PARA0]);
+ addr = nla_get_u32(info->attrs[TEST_ATTR_PARA1]);
+ value = nla_get_u32(info->attrs[TEST_ATTR_PARA2]);
+
+ if(!func_no) {
+ res = esp_common_writebyte_with_addr(SIP->epub, addr, (u8)value, ESP_SIF_SYNC);
+ } else {
+ memcpy(sdio_buff, (u8 *)&value, 4);
+ res = esp_common_write_with_addr(SIP->epub, addr, sdio_buff, 4, ESP_SIF_SYNC);
+ }
+
+ /*directly send reply_info to target, and waiting for report*/
+ REGISTER_REPLY(info);
+ if (!res)
+ esp_test_cmd_reply(info, TEST_CMD_SDIO_WR, "write ok!");
+ else
+ esp_test_cmd_reply(info, TEST_CMD_SDIO_WR, "write fail!");
+
+out:
+ OUT_DONE();
+ return -EINVAL;
+}
+
+static int esp_test_sdio_rd(struct sk_buff *skb_2,
+ struct genl_info *info)
+{
+ int res;
+ u32 func_no, addr, value;
+ char value_str[12];
+
+ if (info == NULL)
+ goto out;
+
+ func_no = nla_get_u32(info->attrs[TEST_ATTR_PARA0]);
+ addr = nla_get_u32(info->attrs[TEST_ATTR_PARA1]);
+
+ if(!func_no) {
+ memset(sdio_buff, 0, 4);
+ res = esp_common_readbyte_with_addr(SIP->epub, addr, &sdio_buff[0], ESP_SIF_SYNC);
+ } else {
+ res = esp_common_read_with_addr(SIP->epub, addr, sdio_buff, 4, ESP_SIF_SYNC);
+ }
+ memcpy((u8 *)&value, sdio_buff, 4);
+
+ /*directly send reply_info to target, and waiting for report*/
+ REGISTER_REPLY(info);
+ if (!res) {
+ sprintf((char *)&value_str, "0x%x", value);
+ esp_test_cmd_reply(info, TEST_CMD_SDIO_RD, value_str);
+ } else
+ esp_test_cmd_reply(info, TEST_CMD_SDIO_RD, "read fail!");
+
+out:
+ OUT_DONE();
+ return -EINVAL;
+}
+
+/* TEST_CMD netlink policy */
+
+static struct nla_policy test_genl_policy[TEST_ATTR_MAX + 1] = {
+ [TEST_ATTR_CMD_NAME]= { .type = NLA_NUL_STRING, .len = GENL_NAMSIZ - 1 },
+ [TEST_ATTR_CMD_TYPE] = { .type = NLA_U32 },
+ [TEST_ATTR_PARA_NUM] = { .type = NLA_U32 },
+ [TEST_ATTR_PARA0] = { .type = NLA_U32 },
+ [TEST_ATTR_PARA1] = { .type = NLA_U32 },
+ [TEST_ATTR_PARA2] = { .type = NLA_U32 },
+ [TEST_ATTR_PARA3] = { .type = NLA_U32 },
+ [TEST_ATTR_PARA4] = { .type = NLA_U32 },
+ [TEST_ATTR_PARA5] = { .type = NLA_U32 },
+ [TEST_ATTR_PARA6] = { .type = NLA_U32 },
+ [TEST_ATTR_PARA7] = { .type = NLA_U32 },
+ [TEST_ATTR_STR] = { .type = NLA_NUL_STRING, .len = 256-1 },
+};
+
+/* Generic Netlink operations array */
+static struct genl_ops esp_test_ops[] = {
+ {
+ .cmd = TEST_CMD_ECHO,
+ .policy = test_genl_policy,
+ .doit = esp_test_echo,
+ .flags = GENL_ADMIN_PERM,
+ },
+ {
+ .cmd = TEST_CMD_ASK,
+ .policy = test_genl_policy,
+ .doit = esp_test_ask,
+ .flags = GENL_ADMIN_PERM,
+ },
+ {
+ .cmd = TEST_CMD_SLEEP,
+ .policy = test_genl_policy,
+ .doit = esp_test_sleep,
+ .flags = GENL_ADMIN_PERM,
+ },
+ {
+ .cmd = TEST_CMD_WAKEUP,
+ .policy = test_genl_policy,
+ .doit = esp_test_wakeup,
+ .flags = GENL_ADMIN_PERM,
+ },
+ {
+ .cmd = TEST_CMD_LOOPBACK,
+ .policy = test_genl_policy,
+ .doit = esp_test_loopback,
+ .flags = GENL_ADMIN_PERM,
+ },
+ {
+ .cmd = TEST_CMD_TX,
+ .policy = test_genl_policy,
+ .doit = esp_test_tx,
+ .flags = GENL_ADMIN_PERM,
+ },
+ {
+ .cmd = TEST_CMD_DEBUG,
+ .policy = test_genl_policy,
+ .doit = esp_test_genl,
+ .flags = GENL_ADMIN_PERM,
+ },
+ {
+ .cmd = TEST_CMD_SDIO_WR,
+ .policy = test_genl_policy,
+ .doit = esp_test_sdio_wr,
+ .flags = GENL_ADMIN_PERM,
+ },
+ {
+ .cmd = TEST_CMD_SDIO_RD,
+ .policy = test_genl_policy,
+ .doit = esp_test_sdio_rd,
+ .flags = GENL_ADMIN_PERM,
+ },
+ {
+ .cmd = TEST_CMD_SDIOSPEED,
+ .policy = test_genl_policy,
+ .doit = esp_test_sdiospeed,
+ .flags = GENL_ADMIN_PERM,
+ },
+};
+
+static int esp_test_netlink_notify(struct notifier_block *nb,
+ unsigned long state,
+ void *_notify)
+{
+ struct netlink_notify *notify = _notify;
+
+ if (state != NETLINK_URELEASE)
+ return NOTIFY_DONE;
+
+ if (notify->pid == connected_nl) {
+ printk(KERN_INFO "esp_sdio: user released netlink"
+ " socket \n");
+ connected_nl = 0;
+ }
+ return NOTIFY_DONE;
+
+}
+
+static struct notifier_block test_netlink_notifier = {
+ .notifier_call = esp_test_netlink_notify,
+};
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31))
+/**
+ * copy from net/netlink/genetlink.c(linux kernel 2.6.32)
+ *
+ * genl_register_family_with_ops - register a generic netlink family
+ * @family: generic netlink family
+ * @ops: operations to be registered
+ * @n_ops: number of elements to register
+ *
+ * Registers the specified family and operations from the specified table.
+ * Only one family may be registered with the same family name or identifier.
+ *
+ * The family id may equal GENL_ID_GENERATE causing an unique id to
+ * be automatically generated and assigned.
+ *
+ * Either a doit or dumpit callback must be specified for every registered
+ * operation or the function will fail. Only one operation structure per
+ * command identifier may be registered.
+ *
+ * See include/net/genetlink.h for more documenation on the operations
+ * structure.
+ *
+ * This is equivalent to calling genl_register_family() followed by
+ * genl_register_ops() for every operation entry in the table taking
+ * care to unregister the family on error path.
+ *
+ * Return 0 on success or a negative error code.
+ */
+int genl_register_family_with_ops(struct genl_family *family,
+ struct genl_ops *ops, size_t n_ops)
+{
+ int err, i;
+
+ err = genl_register_family(family);
+ if (err)
+ return err;
+
+ for (i = 0; i < n_ops; ++i, ++ops) {
+ err = genl_register_ops(family, ops);
+ if (err)
+ goto err_out;
+ }
+ return 0;
+err_out:
+ genl_unregister_family(family);
+ return err;
+}
+#endif
+
+int test_init_netlink(struct esp_sip *sip)
+{
+ int rc;
+ printk(KERN_INFO "esp_sdio: initializing netlink\n");
+
+ sip_copy=sip;
+ /* temp buffer for sdio test */
+ sdio_buff = kzalloc(8, GFP_KERNEL);
+
+ rc = genl_register_family_with_ops(&test_genl_family,
+ esp_test_ops, ARRAY_SIZE(esp_test_ops));
+ if (rc)
+ goto failure;
+
+ rc = netlink_register_notifier(&test_netlink_notifier);
+ if (rc)
+ goto failure;
+
+ return 0;
+
+failure:
+ printk(KERN_DEBUG "esp_sdio: error occured in %s\n", __func__);
+ kfree(sdio_buff);
+ return -EINVAL;
+}
+
+void test_exit_netlink(void)
+{
+ int ret;
+
+ if (sdio_buff == NULL)
+ return;
+
+ kfree(sdio_buff);
+ sdio_buff = NULL;
+ sip_copy = NULL;
+
+ printk(KERN_INFO "esp_sdio: closing netlink\n");
+ /* unregister the notifier */
+ netlink_unregister_notifier(&test_netlink_notifier);
+ /* unregister the family */
+ ret = genl_unregister_family(&test_genl_family);
+ if (ret)
+ printk(KERN_DEBUG "esp_sdio: "
+ "unregister family %i\n", ret);
+}
+void esp_test_cmd_event(u32 cmd_type, char *reply_info)
+{
+ esp_test_cmd_reply(&info_copy, cmd_type, reply_info);
+}
+#endif //ifdef TEST_MODE
+