[RAMEN9610-11181][common][9610] wlbt: Fix kernel panic and Update to 6.60.1
authorYoungsoo <youngss.kim@samsung.com>
Tue, 22 Jan 2019 02:22:29 +0000 (11:22 +0900)
committerhskang <hs1218.kang@samsung.com>
Tue, 22 Jan 2019 13:10:22 +0000 (22:10 +0900)
1) Fix kernel panic in slsi_bt_send_frame
2) Fix memory leak in slsi_bt_send_frame
3) Rx: A-MSDU: handle alloc failure
4) fix broken HIP4 stats
5) Mac randomization through wificond
6) protect dynamic interface deletion with lock
7) delibrately panic kernel on fw panic
8) Prevent issue and Mac Randomization Fixes.
9) Claim wakelock around wlbtd netlink comms
10) Increase FW version Size to 128 bytes

Change-Id: I2bf6b89666ee7d122088fbe31e569260bade02ec
Signed-off-by: Youngsoo <youngss.kim@samsung.com>
26 files changed:
drivers/bluetooth/h4_recv.h [new file with mode: 0755]
drivers/misc/samsung/scsc/mxlogger.c
drivers/misc/samsung/scsc/scsc_wlbtd.c
drivers/misc/samsung/scsc_bt/scsc_bluez.c
drivers/misc/samsung/scsc_bt/scsc_bt_module.c
drivers/misc/samsung/scsc_bt/scsc_shm.c
drivers/net/wireless/scsc/Kconfig
drivers/net/wireless/scsc/acm_api.c
drivers/net/wireless/scsc/cfg80211_ops.c
drivers/net/wireless/scsc/dev.c
drivers/net/wireless/scsc/dev.h
drivers/net/wireless/scsc/hip4.c
drivers/net/wireless/scsc/ioctl.c
drivers/net/wireless/scsc/mgt.c
drivers/net/wireless/scsc/mgt.h
drivers/net/wireless/scsc/mlme.c
drivers/net/wireless/scsc/mlme.h
drivers/net/wireless/scsc/netif.c
drivers/net/wireless/scsc/netif.h [changed mode: 0644->0755]
drivers/net/wireless/scsc/nl80211_vendor.c
drivers/net/wireless/scsc/procfs.c
drivers/net/wireless/scsc/rx.c
drivers/net/wireless/scsc/sap_ma.c
drivers/net/wireless/scsc/tx.c
include/scsc/scsc_log_collector.h
include/scsc/scsc_release.h

diff --git a/drivers/bluetooth/h4_recv.h b/drivers/bluetooth/h4_recv.h
new file mode 100755 (executable)
index 0000000..b432651
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ *
+ *  Generic Bluetooth HCI UART driver
+ *
+ *  Copyright (C) 2015-2018  Intel Corporation
+ *
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  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.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include <asm/unaligned.h>
+
+struct h4_recv_pkt {
+       u8  type;       /* Packet type */
+       u8  hlen;       /* Header length */
+       u8  loff;       /* Data length offset in header */
+       u8  lsize;      /* Data length field size */
+       u16 maxlen;     /* Max overall packet length */
+       int (*recv)(struct hci_dev *hdev, struct sk_buff *skb);
+};
+
+#define H4_RECV_ACL \
+       .type = HCI_ACLDATA_PKT, \
+       .hlen = HCI_ACL_HDR_SIZE, \
+       .loff = 2, \
+       .lsize = 2, \
+       .maxlen = HCI_MAX_FRAME_SIZE \
+
+#define H4_RECV_SCO \
+       .type = HCI_SCODATA_PKT, \
+       .hlen = HCI_SCO_HDR_SIZE, \
+       .loff = 2, \
+       .lsize = 1, \
+       .maxlen = HCI_MAX_SCO_SIZE
+
+#define H4_RECV_EVENT \
+       .type = HCI_EVENT_PKT, \
+       .hlen = HCI_EVENT_HDR_SIZE, \
+       .loff = 1, \
+       .lsize = 1, \
+       .maxlen = HCI_MAX_EVENT_SIZE
+
+static inline struct sk_buff *h4_recv_buf(struct hci_dev *hdev,
+                                         struct sk_buff *skb,
+                                         const unsigned char *buffer,
+                                         int count,
+                                         const struct h4_recv_pkt *pkts,
+                                         int pkts_count)
+{
+       while (count) {
+               int i, len;
+
+               if (!count)
+                       break;
+
+               if (!skb) {
+                       for (i = 0; i < pkts_count; i++) {
+                               if (buffer[0] != (&pkts[i])->type)
+                                       continue;
+
+                               skb = bt_skb_alloc((&pkts[i])->maxlen,
+                                                  GFP_ATOMIC);
+                               if (!skb)
+                                       return ERR_PTR(-ENOMEM);
+
+                               hci_skb_pkt_type(skb) = (&pkts[i])->type;
+                               hci_skb_expect(skb) = (&pkts[i])->hlen;
+                               break;
+                       }
+
+                       /* Check for invalid packet type */
+                       if (!skb)
+                               return ERR_PTR(-EILSEQ);
+
+                       count -= 1;
+                       buffer += 1;
+               }
+
+               len = min_t(uint, hci_skb_expect(skb) - skb->len, count);
+               skb_put_data(skb, buffer, len);
+
+               count -= len;
+               buffer += len;
+
+               /* Check for partial packet */
+               if (skb->len < hci_skb_expect(skb))
+                       continue;
+
+               for (i = 0; i < pkts_count; i++) {
+                       if (hci_skb_pkt_type(skb) == (&pkts[i])->type)
+                               break;
+               }
+
+               if (i >= pkts_count) {
+                       kfree_skb(skb);
+                       return ERR_PTR(-EILSEQ);
+               }
+
+               if (skb->len == (&pkts[i])->hlen) {
+                       u16 dlen;
+
+                       switch ((&pkts[i])->lsize) {
+                       case 0:
+                               /* No variable data length */
+                               dlen = 0;
+                               break;
+                       case 1:
+                               /* Single octet variable length */
+                               dlen = skb->data[(&pkts[i])->loff];
+                               hci_skb_expect(skb) += dlen;
+
+                               if (skb_tailroom(skb) < dlen) {
+                                       kfree_skb(skb);
+                                       return ERR_PTR(-EMSGSIZE);
+                               }
+                               break;
+                       case 2:
+                               /* Double octet variable length */
+                               dlen = get_unaligned_le16(skb->data +
+                                                         (&pkts[i])->loff);
+                               hci_skb_expect(skb) += dlen;
+
+                               if (skb_tailroom(skb) < dlen) {
+                                       kfree_skb(skb);
+                                       return ERR_PTR(-EMSGSIZE);
+                               }
+                               break;
+                       default:
+                               /* Unsupported variable length */
+                               kfree_skb(skb);
+                               return ERR_PTR(-EILSEQ);
+                       }
+
+                       if (!dlen) {
+                               /* No more data, complete frame */
+                               (&pkts[i])->recv(hdev, skb);
+                               skb = NULL;
+                       }
+               } else {
+                       /* Complete frame */
+                       (&pkts[i])->recv(hdev, skb);
+                       skb = NULL;
+               }
+       }
+
+       return skb;
+}
index b49347ee28c5c36464339286ffd400451b744d9b..fa7baec3f3d01e9d764cdbb9363c651a7f250636 100644 (file)
@@ -1,6 +1,6 @@
 /****************************************************************************
  *
- * Copyright (c) 2014 - 2018 Samsung Electronics Co., Ltd. All rights reserved
+ * Copyright (c) 2014 - 2019 Samsung Electronics Co., Ltd. All rights reserved
  *
  ****************************************************************************/
 
@@ -195,6 +195,7 @@ static void mxlogger_message_handler(const void *message, void *data)
 {
        struct mxlogger         __attribute__((unused)) *mxlogger = (struct mxlogger *)data;
        const struct log_msg_packet     *msg = message;
+       u16 reason_code;
 
        switch (msg->msg) {
        case MM_MXLOGGER_INITIALIZED_EVT:
@@ -213,9 +214,16 @@ static void mxlogger_message_handler(const void *message, void *data)
                complete(&mxlogger->rings_serialized_ops);
                break;
        case MM_MXLOGGER_COLLECTION_FW_REQ_EVT:
-               SCSC_TAG_INFO(MXMAN, "MXLOGGER:: FW requested collection - Reason code:%d\n", msg->arg);
+               /* If arg is zero, FW is using the 16bit reason code API */
+               /* therefore, the reason code is in the payload */
+               if (msg->arg == 0x00)
+                       memcpy(&reason_code, &msg->payload[0], sizeof(u16));
+               else
+                       /* old API */
+                       reason_code = msg->arg;
 #ifdef CONFIG_SCSC_LOG_COLLECTION
-               scsc_log_collector_schedule_collection(SCSC_LOG_FW, msg->arg);
+               SCSC_TAG_INFO(MXMAN, "MXLOGGER:: FW requested collection - Reason code:0x%04x\n", reason_code);
+               scsc_log_collector_schedule_collection(SCSC_LOG_FW, reason_code);
 #endif
                break;
        default:
index c8e846edea685221065f5617010e83b8fa3383d8..207dd878ef3125f0420a56f3c1e34103d52e14e9 100755 (executable)
@@ -4,6 +4,8 @@
  *
  ****************************************************************************/
 #include <linux/mutex.h>
+#include <linux/wakelock.h>
+
 #include "scsc_wlbtd.h"
 
 #define MAX_TIMEOUT    30000 /* in milisecounds */
@@ -15,6 +17,8 @@ static DEFINE_MUTEX(build_type_lock);
 static char *build_type;
 static DEFINE_MUTEX(sable_lock);
 
+static struct wake_lock wlbtd_wakelock;
+
 /**
  * This callback runs whenever the socket receives messages.
  */
@@ -158,6 +162,7 @@ int scsc_wlbtd_get_and_print_build_type(void)
        int rc = 0;
 
        SCSC_TAG_DEBUG(WLBTD, "start\n");
+       wake_lock(&wlbtd_wakelock);
 
        /* check if the value wasn't cached yet */
        mutex_lock(&build_type_lock);
@@ -165,7 +170,7 @@ int scsc_wlbtd_get_and_print_build_type(void)
                SCSC_TAG_WARNING(WLBTD, "ro.build.type = %s\n", build_type);
                SCSC_TAG_DEBUG(WLBTD, "sync end\n");
                mutex_unlock(&build_type_lock);
-               return 0;
+               goto done;
        }
        mutex_unlock(&build_type_lock);
        skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
@@ -203,7 +208,10 @@ int scsc_wlbtd_get_and_print_build_type(void)
        }
 
        SCSC_TAG_DEBUG(WLBTD, "async end\n");
+done:
+       wake_unlock(&wlbtd_wakelock);
        return rc;
+
 error:
        if (rc == -ESRCH) {
                /* If no one registered to scsc_mdp_mcgrp (e.g. in case wlbtd
@@ -211,10 +219,12 @@ error:
                 * Ignore and return.
                 */
                SCSC_TAG_WARNING(WLBTD, "WLBTD not running ?\n");
+               wake_unlock(&wlbtd_wakelock);
                return rc;
        }
        /* free skb */
        nlmsg_free(skb);
+       wake_unlock(&wlbtd_wakelock);
        return -1;
 }
 
@@ -227,6 +237,8 @@ int call_wlbtd_sable(const char *trigger, u16 reason_code)
        unsigned long max_timeout_jiffies = msecs_to_jiffies(MAX_TIMEOUT);
 
        mutex_lock(&sable_lock);
+       wake_lock(&wlbtd_wakelock);
+
        SCSC_TAG_INFO(WLBTD, "start:trigger - %s\n", trigger);
 
        skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
@@ -275,10 +287,10 @@ int call_wlbtd_sable(const char *trigger, u16 reason_code)
                         * returns -ESRCH. Ignore and return.
                         */
                        SCSC_TAG_WARNING(WLBTD, "WLBTD not running ?\n");
-                       return rc;
+                       goto done;
                }
                SCSC_TAG_ERR(WLBTD, "Failed to send message. rc = %d\n", rc);
-               return rc;
+               goto done;
        }
 
        SCSC_TAG_INFO(WLBTD, "waiting for completion\n");
@@ -298,13 +310,17 @@ int call_wlbtd_sable(const char *trigger, u16 reason_code)
        reinit_completion(&event_done);
 
        SCSC_TAG_INFO(WLBTD, "  end:trigger - %s\n", trigger);
-       mutex_unlock(&sable_lock);
 
+done:
+       wake_unlock(&wlbtd_wakelock);
+       mutex_unlock(&sable_lock);
        return rc;
 
 error:
        /* free skb */
        nlmsg_free(skb);
+       wake_unlock(&wlbtd_wakelock);
+       mutex_unlock(&sable_lock);
 
        return -1;
 }
@@ -320,6 +336,8 @@ int call_wlbtd(const char *script_path)
 
        SCSC_TAG_DEBUG(WLBTD, "start\n");
 
+       wake_lock(&wlbtd_wakelock);
+
        skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
        if (!skb) {
                SCSC_TAG_ERR(WLBTD, "Failed to construct message\n");
@@ -367,10 +385,10 @@ int call_wlbtd(const char *script_path)
                         * returns -ESRCH. Ignore and return.
                         */
                        SCSC_TAG_WARNING(WLBTD, "WLBTD not running ?\n");
-                       return rc;
+                       goto done;
                }
                SCSC_TAG_ERR(WLBTD, "Failed to send message. rc = %d\n", rc);
-               return rc;
+               goto done;
        }
 
        SCSC_TAG_INFO(WLBTD, "waiting for completion\n");
@@ -392,11 +410,14 @@ int call_wlbtd(const char *script_path)
 
        SCSC_TAG_DEBUG(WLBTD, "end\n");
 
+done:
+       wake_unlock(&wlbtd_wakelock);
        return rc;
 
 error:
        /* free skb */
        nlmsg_free(skb);
+       wake_unlock(&wlbtd_wakelock);
 
        return -1;
 }
@@ -405,6 +426,10 @@ EXPORT_SYMBOL(call_wlbtd);
 int scsc_wlbtd_init(void)
 {
        int r = 0;
+
+       wake_lock_init(&wlbtd_wakelock, WAKE_LOCK_SUSPEND, "wlbtd_wl");
+       init_completion(&event_done);
+
        /* register the family so that wlbtd can bind */
        r = genl_register_family(&scsc_nlfamily);
        if (r) {
@@ -412,8 +437,6 @@ int scsc_wlbtd_init(void)
                return -1;
        }
 
-       init_completion(&event_done);
-
        return r;
 }
 
@@ -430,5 +453,7 @@ int scsc_wlbtd_deinit(void)
        }
        kfree(build_type);
        build_type = NULL;
+       wake_lock_destroy(&wlbtd_wakelock);
+
        return ret;
 }
index f5230ad08911fb080289b57296ee6ad6118fbfc8..cb20ab7569481ff4d941b2700f8ffc67ed508482 100755 (executable)
 
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
+#include "../../../bluetooth/h4_recv.h"
 
 #include <scsc/scsc_logring.h>
 
-static struct sk_buff_head             txq;
 static struct hci_dev                  *hdev;
 static struct device                   *dev_ref;
 static const struct file_operations    *bt_fs;
@@ -74,8 +74,13 @@ static int slsi_bt_close(struct hci_dev *hdev)
        SCSC_TAG_INFO(BT_COMMON, "terminating reader thread\n");
 
        terminate_read = true;
-       atomic_inc(error_count_ref);
-       wake_up(read_wait_ref);
+
+       if (error_count_ref != NULL)
+               atomic_inc(error_count_ref);
+
+       if (read_wait_ref != NULL)
+               wake_up(read_wait_ref);
+
        cancel_work_sync(&read_work);
 
        SCSC_TAG_INFO(BT_COMMON, "releasing service\n");
@@ -89,29 +94,47 @@ static int slsi_bt_close(struct hci_dev *hdev)
 
 static int slsi_bt_flush(struct hci_dev *hdev)
 {
-       skb_queue_purge(&txq);
        return 0;
 }
 
 static int slsi_bt_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
 {
-       struct sk_buff *transfer_skb;
-       int err;
+       int ret;
+
+       SCSC_TAG_INFO(BT_H4, "sending frame(data=%p, len=%u)\n", skb->data, skb->len);
 
        memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
-       skb_queue_tail(&txq, skb);
 
-       transfer_skb = skb_dequeue(&txq);
-       if (transfer_skb) {
-               SCSC_TAG_INFO(BT_H4, "sending frame(data=%p, len=%u)\n", skb->data, skb->len);
+       ret = bt_fs->write(NULL, skb->data, skb->len, NULL);
+       if (ret >= 0) {
+               kfree_skb(skb);
+
+               /* Update HCI stat counters */
+               hdev->stat.byte_tx += skb->len;
+
+               switch (hci_skb_pkt_type(skb)) {
+                       case HCI_COMMAND_PKT:
+                               hdev->stat.cmd_tx++;
+                               break;
 
-               err = bt_fs->write(NULL, skb->data, skb->len, NULL);
-               kfree_skb(transfer_skb);
+                       case HCI_ACLDATA_PKT:
+                               hdev->stat.acl_tx++;
+                               break;
+
+                       case HCI_SCODATA_PKT:
+                               hdev->stat.sco_tx++;
+                               break;
+               }
        }
 
-       return err;
+       return ret;
 }
 
+static const struct h4_recv_pkt scsc_recv_pkts[] = {
+       { H4_RECV_ACL,   .recv = hci_recv_frame },
+       { H4_RECV_EVENT, .recv = hci_recv_frame },
+};
+
 static void slsi_bt_fs_read_func(struct work_struct *work)
 {
        int ret;
@@ -122,20 +145,16 @@ static void slsi_bt_fs_read_func(struct work_struct *work)
                        break;
 
                if (ret > 0) {
-                       skb = bt_skb_alloc(ret, GFP_ATOMIC);
-                       if (!skb)
-                               SCSC_TAG_ERR(BT_COMMON, "bt_skb_alloc failed\n");
-
-                       skb->dev = (void *) hdev;
-                       bt_cb(skb)->pkt_type = receive_buffer[0];
-                       memcpy(skb_put(skb, ret - 1), &receive_buffer[1], ret - 1);
-
-                       ret = hci_recv_frame(hdev, skb);
-                       if (ret < 0) {
-                               SCSC_TAG_ERR(BT_COMMON, "unable to send skb to HCI layer\n");
-                               /* skb freed in HCI layer */
-                               skb = NULL;
+                       skb = h4_recv_buf(hdev, skb, receive_buffer,
+                                       ret, scsc_recv_pkts,
+                                       ARRAY_SIZE(scsc_recv_pkts));
+
+                       if (IS_ERR(skb)) {
+                               SCSC_TAG_ERR(BT_COMMON, "corrupted event packet\n");
+                               hdev->stat.err_rx++;
+                               break;
                        }
+                       hdev->stat.byte_rx += ret;
                }
        }
 
@@ -191,8 +210,6 @@ void slsi_bt_notify_probe(struct device *dev,
        read_wait_ref   = read_wait;
        dev_ref         = dev;
 
-       skb_queue_head_init(&txq);
-
        wq = create_singlethread_workqueue("slsi_bt_bluez_wq");
        INIT_WORK(&read_work, slsi_bt_fs_read_func);
 
index ce5fe1fd332cf2d1d34bebda0ce0994b4c4f8dcf..12d8144b913e94c555dd5c5b5c6c345080e87958 100755 (executable)
@@ -1453,8 +1453,6 @@ static void slsi_bt_service_remove(struct scsc_mx_module_client *module_client,
                goto done;
        }
 
-       slsi_bt_notify_remove();
-
        if (reason == SCSC_MODULE_CLIENT_REASON_RECOVERY && bt_recovery_in_progress) {
                mutex_unlock(&bt_start_mutex);
                wait_for_completion(&bt_service.recovery_release_complete);
@@ -1473,6 +1471,7 @@ static void slsi_bt_service_remove(struct scsc_mx_module_client *module_client,
                bt_service.h4_write_offset = 0;
        }
 
+       slsi_bt_notify_remove();
        put_device(bt_service.dev);
        common_service.maxwell_core = NULL;
 
index cbf81cf5f8be4747154d1da795b13f5cacf2a390..4490936c48c6587a1dae5854277586b6d1dece96 100755 (executable)
@@ -935,9 +935,7 @@ static ssize_t scsc_bt_shm_h4_read_hci_evt(char __user *buf, size_t len)
                        /* Update the index if all the data could be copied to the userspace buffer otherwise stop processing the HCI events */
                        if (BT_READ_OP_NONE == bt_service.read_operation)
                                BSMHCP_INCREASE_INDEX(bt_service.mailbox_hci_evt_read, BSMHCP_TRANSFER_RING_EVT_SIZE);
-#ifndef CONFIG_SCSC_BT_BLUEZ
                        else
-#endif
                                break;
                }
        }
@@ -977,12 +975,7 @@ static bool scsc_bt_shm_h4_acl_start_copy(char __user *buf,
 
        BSMHCP_INCREASE_INDEX(bt_service.mailbox_acl_rx_read, BSMHCP_TRANSFER_RING_ACL_SIZE);
 
-#ifdef CONFIG_SCSC_BT_BLUEZ
-       /* If BlueZ is enabled stop processing even after one complete packet */
-       return true;
-#else
        return false;
-#endif
 }
 
 static ssize_t scsc_bt_shm_h4_read_acl_data(char __user *buf, size_t len)
@@ -1293,46 +1286,28 @@ ssize_t scsc_bt_shm_h4_read(struct file *file, char __user *buf, size_t len, lof
                /* First: process any pending HCI event that needs to be sent to userspace */
                res = scsc_bt_shm_h4_read_hci_evt(&buf[consumed], len - consumed);
                if (0 < res)
-               {
                        consumed += res;
-#ifdef CONFIG_SCSC_BT_BLUEZ
-                       break;
-#endif
-               }
                else
                        ret = res;
 
                /* Second: process any pending ACL data that needs to be sent to userspace */
                res = scsc_bt_shm_h4_read_acl_data(&buf[consumed], len - consumed);
                if (0 < res)
-               {
                        consumed += res;
-#ifdef CONFIG_SCSC_BT_BLUEZ
-                       break;
-#endif
-               }
                else
                        ret = res;
 
                /* Third: process any pending ACL data that needs to be sent to userspace */
                res = scsc_bt_shm_h4_read_acl_credit(&buf[consumed], len - consumed);
                if (0 < res)
-               {
                        consumed += res;
-#ifdef CONFIG_SCSC_BT_BLUEZ
-                       break;
-#endif
-               }
                else
                        ret = res;
 
                res = scsc_bt_shm_h4_read_iq_report_evt(&buf[consumed], len - consumed);
-               if (res > 0) {
+               if (res > 0)
                        consumed += res;
-#ifdef CONFIG_SCSC_BT_BLUEZ
-                       break;
-#endif
-               } else
+               else
                        ret = res;
        }
 
index 4e5c81f40af8cd689262a65ea482c728809d66fa..9f0316e9508f18f3d849e53f182d6d96a5d15d8c 100755 (executable)
@@ -167,6 +167,7 @@ config SCSC_WLAN_SINGLE_ANTENNA
        ---help---
          This option tells if there is support for single
          antenna or dual antenna.
+
 config SCSC_WLAN_ACS_ENABLE
         bool "ACS Support"
         default y
@@ -174,3 +175,8 @@ config SCSC_WLAN_ACS_ENABLE
           This option tells if automatic channel selection is
          supported or not.
 
+config SCSC_AP_INTERFACE_NAME
+        string "AP net device interface name"
+        default "wlan1"
+        ---help---
+          AP net device interface name.
index 8cba1489ea408e9a76055c8d34f2a5b091299871..d64ee26ac61137c7f7905d4a83ca70a3e9e9dcfe 100755 (executable)
@@ -1,6 +1,6 @@
 /*****************************************************************************
  *
- * Copyright (c) 2012 - 2018 Samsung Electronics Co., Ltd. All rights reserved
+ * Copyright (c) 2012 - 2019 Samsung Electronics Co., Ltd. All rights reserved
  *
  ****************************************************************************/
 
@@ -27,9 +27,9 @@ unsigned long long SDA_getTsf(const unsigned char if_id)
        read_lock(&dev_base_lock);
        dev = first_net_device(&init_net);
        while (dev) {
-               if (if_id == 0 && !dev->name && memcmp(dev->name, "wlan0", 5) == 0)
+               if (if_id == 0 && memcmp(dev->name, "wlan0", 5) == 0)
                        break;
-               else if (if_id == 1 && !dev->name && memcmp(dev->name, "p2p0", 4) == 0)
+               else if (if_id == 1 && memcmp(dev->name, "p2p0", 4) == 0)
                        break;
                dev = next_net_device(dev);
        }
index d49849dbefa815cc45bf6bc3dfeb77d4af96ad81..39f404951c1b93846ec12d4388dfcd1086a41211 100755 (executable)
@@ -26,6 +26,18 @@ static uint keep_alive_period = SLSI_P2PGO_KEEP_ALIVE_PERIOD_SEC;
 module_param(keep_alive_period, uint, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(keep_alive_period, "default is 10 seconds");
 
+static bool slsi_is_mhs_active(struct slsi_dev *sdev)
+{
+       struct net_device *mhs_dev = sdev->netdev_ap;
+       struct netdev_vif *ndev_vif = netdev_priv(mhs_dev);
+       bool ret;
+
+       SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
+       ret = ndev_vif->is_available;
+       SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
+       return ret;
+}
+
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0))
 struct wireless_dev *slsi_add_virtual_intf(struct wiphy        *wiphy,
                                           const char          *name,
@@ -59,12 +71,17 @@ struct net_device *slsi_add_ virtual_intf(struct wiphy        *wiphy,
 
        struct net_device *dev = NULL;
        struct netdev_vif *ndev_vif = NULL;
+       struct slsi_dev   *sdev = SDEV_FROM_WIPHY(wiphy);
 
 #if (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 11, 0))
        SLSI_UNUSED_PARAMETER(flags);
 #endif
        SLSI_NET_DBG1(dev, SLSI_CFG80211, "Intf name:%s, type:%d, macaddr:%pM\n", name, type, params->macaddr);
-       dev = slsi_new_interface_create(wiphy, name, type, params);
+       if (slsi_is_mhs_active(sdev)) {
+               SLSI_ERR(sdev, "MHS is active. cannot add new interface\n");
+               return ERR_PTR(-EOPNOTSUPP);
+       }
+       dev = slsi_dynamic_interface_create(wiphy, name, type, params);
        if (!dev)
                goto exit_with_error;
        ndev_vif = netdev_priv(dev);
@@ -97,6 +114,12 @@ int slsi_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev)
 
        slsi_stop_net_dev(sdev, dev);
        slsi_netif_remove_rtlnl_locked(sdev, dev);
+       SLSI_MUTEX_LOCK(sdev->netdev_add_remove_mutex);
+       if (dev == sdev->netdev_ap)
+               rcu_assign_pointer(sdev->netdev_ap, NULL);
+       if (!sdev->netdev[SLSI_NET_INDEX_P2PX_SWLAN])
+               rcu_assign_pointer(sdev->netdev[SLSI_NET_INDEX_P2PX_SWLAN], sdev->netdev_ap);
+       SLSI_MUTEX_UNLOCK(sdev->netdev_add_remove_mutex);
 
        return 0;
 }
@@ -414,7 +437,7 @@ int slsi_scan(struct wiphy *wiphy, struct net_device *dev,
        struct netdev_vif         *ndev_vif = netdev_priv(dev);
        struct slsi_dev           *sdev = SDEV_FROM_WIPHY(wiphy);
        u16                       scan_type = FAPI_SCANTYPE_FULL_SCAN;
-       int                       r;
+       int                       r = 0;
        u16                       p2p_state = sdev->p2p_state;
        u8                        *scan_ie;
        size_t                    scan_ie_len;
@@ -523,12 +546,15 @@ int slsi_scan(struct wiphy *wiphy, struct net_device *dev,
        slsi_purge_scan_results(ndev_vif, SLSI_SCAN_HW_ID);
 
 #ifdef CONFIG_SCSC_WLAN_ENABLE_MAC_RANDOMISATION
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0))
        if (request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
                memcpy(sdev->scan_mac_addr, request->mac_addr, ETH_ALEN);
                r = slsi_set_mac_randomisation_mask(sdev, request->mac_addr_mask);
                if (!r)
                        sdev->scan_addr_set = 1;
-       } else if (sdev->scan_addr_set == 1) {
+       } else
+#endif
+       if (scan_type == FAPI_SCANTYPE_GSCAN && sdev->scan_addr_set == 1) {
                memset(mac_addr_mask, 0xFF, ETH_ALEN);
                for (i = 3; i < ETH_ALEN; i++)
                        mac_addr_mask[i] = 0x00;
@@ -536,7 +562,7 @@ int slsi_scan(struct wiphy *wiphy, struct net_device *dev,
        } else {
                if (sdev->scan_addr_set) {
                        memset(mac_addr_mask, 0xFF, ETH_ALEN);
-                       slsi_set_mac_randomisation_mask(sdev, mac_addr_mask);
+                       r = slsi_set_mac_randomisation_mask(sdev, mac_addr_mask);
                        if (!r)
                                sdev->scan_addr_set = 0;
                }
@@ -787,9 +813,9 @@ int slsi_connect(struct wiphy *wiphy, struct net_device *dev,
 
        center_freq = sme->channel ? sme->channel->center_freq : 0;
 
-       SLSI_NET_INFO(dev, "%.*s CentFreq=%d vifStatus=%d CurrBssid:%pM NewBssid:%pM QOSinfo:%d\n",
+       SLSI_NET_INFO(dev, "%.*s Freq=%d vifStatus=%d CurrBssid:%pM NewBssid:%pM Qinfo:%d ieLen:%d\n",
                      (int)sme->ssid_len, sme->ssid, center_freq, ndev_vif->sta.vif_status,
-                     peer_address, sme->bssid, sdev->device_config.qos_info);
+                     peer_address, sme->bssid, sdev->device_config.qos_info, (int)sme->ie_len);
 
 #ifdef CONFIG_SCSC_WIFILOGGER
        SCSC_WLOG_PKTFATE_NEW_ASSOC();
@@ -871,7 +897,7 @@ int slsi_connect(struct wiphy *wiphy, struct net_device *dev,
        /* Sta started case */
 
 #ifdef CONFIG_SCSC_WLAN_WIFI_SHARING
-       if (SLSI_IS_INTERFACE_WIFI_SHARING_AP(ndev_vif))
+       if (SLSI_IS_VIF_INDEX_MHS(sdev, ndev_vif))
                if (ndev_vif->iftype == NL80211_IFTYPE_P2P_CLIENT) {
                        SLSI_NET_ERR(dev, "Iftype: %d\n", ndev_vif->iftype);
                        goto exit_with_error;
@@ -1417,7 +1443,7 @@ int slsi_tdls_oper(struct wiphy *wiphy, struct net_device *dev, u8 *peer, enum n
 
        SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
 
-       if ((!ndev_vif->activated) || SLSI_IS_VIF_INDEX_P2P_GROUP(ndev_vif) ||
+       if ((!ndev_vif->activated) || SLSI_IS_VIF_INDEX_P2P_GROUP(sdev, ndev_vif) ||
            (ndev_vif->sta.vif_status != SLSI_VIF_STATUS_CONNECTED)) {
                r = -ENOTSUPP;
                goto exit;
@@ -1951,7 +1977,7 @@ int slsi_start_ap(struct wiphy *wiphy, struct net_device *dev,
        beacon_ie_head_len = settings->beacon.head_len - ((u8 *)mgmt->u.beacon.variable - (u8 *)mgmt);
 #ifdef CONFIG_SCSC_WLAN_WIFI_SHARING
        ndev_sta_vif = netdev_priv(wlan_dev);
-       if (SLSI_IS_INTERFACE_WIFI_SHARING_AP(ndev_vif)) {
+       if (SLSI_IS_VIF_INDEX_MHS(sdev, ndev_vif)) {
                SLSI_MUTEX_LOCK(ndev_sta_vif->vif_mutex);
                if ((ndev_sta_vif->activated) && (ndev_sta_vif->vif_type == FAPI_VIFTYPE_STATION) &&
                    (ndev_sta_vif->sta.vif_status == SLSI_VIF_STATUS_CONNECTING ||
@@ -2181,7 +2207,7 @@ int slsi_start_ap(struct wiphy *wiphy, struct net_device *dev,
        }
 #endif
 
-       if ((indoor_channel == 1)
+       if (indoor_channel == 1
 #ifdef CONFIG_SCSC_WLAN_WIFI_SHARING
        || (wifi_sharing_channel_switched == 1)
 #endif
@@ -2284,7 +2310,7 @@ int slsi_start_ap(struct wiphy *wiphy, struct net_device *dev,
        if (r == 0)
                SLSI_NET_DBG1(dev, SLSI_CFG80211, "Soft Ap started on frequency: %d\n",
                              settings->chandef.chan->center_freq);
-       if (SLSI_IS_INTERFACE_WIFI_SHARING_AP(ndev_vif))
+       if (SLSI_IS_VIF_INDEX_MHS(sdev, ndev_vif))
                ndev_vif->chan = settings->chandef.chan;
 #endif
 
@@ -2560,7 +2586,7 @@ int     slsi_mgmt_tx_cancel_wait(struct wiphy      *wiphy,
                }
        } else if ((SLSI_IS_P2P_GROUP_STATE(sdev)) && (sdev->p2p_group_exp_frame != SLSI_P2P_PA_INVALID)) {
                /* acquire mutex lock if it is not group net dev */
-               slsi_clear_offchannel_data(sdev, (!SLSI_IS_VIF_INDEX_P2P_GROUP(ndev_vif)) ? true : false);
+               slsi_clear_offchannel_data(sdev, (!SLSI_IS_VIF_INDEX_P2P_GROUP(sdev, ndev_vif)) ? true : false);
        } else if ((sdev->wlan_unsync_vif_state == WLAN_UNSYNC_VIF_TX) && (ndev_vif->mgmt_tx_data.cookie == cookie)) {
                sdev->wlan_unsync_vif_state = WLAN_UNSYNC_VIF_ACTIVE;
                cancel_delayed_work(&ndev_vif->unsync.hs2_del_vif_work);
@@ -2606,7 +2632,7 @@ static int slsi_wlan_mgmt_tx(struct slsi_dev *sdev, struct net_device *dev,
        int                r = 0;
        struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
 
-       slsi_wlan_dump_public_action_subtype(mgmt, true);
+       slsi_wlan_dump_public_action_subtype(sdev, mgmt, true);
 
        if (!ndev_vif->activated) {
                r = slsi_wlan_unsync_vif_activate(sdev, dev, chan, wait);
@@ -2755,7 +2781,7 @@ int slsi_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
                        r = slsi_p2p_group_mgmt_tx(mgmt, wiphy, dev, chan, wait, buf, len, dont_wait_for_ack, cookie);
                else
                        r = slsi_p2p_mgmt_tx(mgmt, wiphy, dev, ndev_vif, chan, wait, buf, len, dont_wait_for_ack, cookie);
-       } else if (SLSI_IS_VIF_INDEX_P2P_GROUP(ndev_vif))
+       } else if (SLSI_IS_VIF_INDEX_P2P_GROUP(sdev, ndev_vif))
                if (chan->hw_value == ndev_vif->chan->hw_value) {
                        struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
                        u16             host_tag = slsi_tx_mgmt_host_tag(sdev);
@@ -3329,8 +3355,10 @@ struct slsi_dev                           *slsi_cfg80211_new(struct device *dev)
        wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
 #endif
        /* Mac Randomization */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0))
 #ifdef CONFIG_SCSC_WLAN_ENABLE_MAC_RANDOMISATION
        wiphy->features |= NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;
+#endif
 #endif
        return sdev;
 }
index 7d4dbfe1319aa431e72a0f8e3f2e0113178a05fa..62ce3b7230b00fdf2d14fb5b011ef078cd0aaf57 100755 (executable)
 #include "kic.h"
 #endif
 
-static char *mib_file = "wlan.hcf";
-module_param(mib_file, charp, S_IRUGO | S_IWUSR);
+char *slsi_mib_file = "wlan.hcf";
+module_param_named(mib_file, slsi_mib_file, charp, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(mib_file, "mib data filename");
 
-static char *mib_file2 = "wlan_sw.hcf";
-module_param(mib_file2, charp, S_IRUGO | S_IWUSR);
+char *slsi_mib_file2 = "wlan_sw.hcf";
+module_param_named(mib_file2, slsi_mib_file2, charp, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(mib_file2, "sw mib data filename");
 
 static char *local_mib_file = "localmib.hcf";
@@ -258,8 +258,8 @@ struct slsi_dev *slsi_dev_attach(struct device *dev, struct scsc_mx *core, struc
        sdev->p2p_certif = false;
        sdev->allow_switch_40_mhz = true;
        sdev->allow_switch_80_mhz = true;
-       sdev->mib[0].mib_file_name = mib_file;
-       sdev->mib[1].mib_file_name = mib_file2;
+       sdev->mib[0].mib_file_name = slsi_mib_file;
+       sdev->mib[1].mib_file_name = slsi_mib_file2;
        sdev->local_mib.mib_file_name = local_mib_file;
        sdev->maddr_file_name = maddr_file;
        sdev->device_config.qos_info = -1;
@@ -363,10 +363,16 @@ struct slsi_dev *slsi_dev_attach(struct device *dev, struct scsc_mx *core, struc
                SLSI_ERR(sdev, "failed to register with p2p netdev\n");
                goto err_wlan_registered;
        }
+
+       if (slsi_netif_register(sdev, sdev->netdev[SLSI_NET_INDEX_P2PX_SWLAN]) != 0) {
+               SLSI_ERR(sdev, "failed to register with p2px_wlan1 netdev\n");
+               goto err_mhs_registered;
+       }
+       rcu_assign_pointer(sdev->netdev_ap, sdev->netdev[SLSI_NET_INDEX_P2PX_SWLAN]);
 #if CONFIG_SCSC_WLAN_MAX_INTERFACES >= 4
        if (slsi_netif_register(sdev, sdev->netdev[SLSI_NET_INDEX_NAN]) != 0) {
                SLSI_ERR(sdev, "failed to register with NAN netdev\n");
-               goto err_p2p_registered;
+               goto err_mhs_registered;
        }
 #endif
 #endif
@@ -396,6 +402,10 @@ err_nan_registered:
        slsi_netif_remove(sdev, sdev->netdev[SLSI_NET_INDEX_NAN]);
 #endif
 
+err_mhs_registered:
+       slsi_netif_remove(sdev, sdev->netdev[SLSI_NET_INDEX_P2PX_SWLAN]);
+       rcu_assign_pointer(sdev->netdev_ap, NULL);
+
 err_p2p_registered:
        slsi_netif_remove(sdev, sdev->netdev[SLSI_NET_INDEX_P2P]);
 
index d1f038f5e603dd8c857f9924d8f6fa41dcad1f44..eb27876c45a838d0242ea48b5dd4b8bb57e2de7f 100755 (executable)
@@ -559,6 +559,9 @@ struct slsi_vif_unsync {
 
 struct slsi_last_disconnected_sta {
        u8 address[ETH_ALEN];
+       u32 rx_retry_packets;
+       u32 rx_bc_mc_packets;
+       u16 capabilities;
        int bandwidth;
        int antenna_mode;
        int rssi;
@@ -759,9 +762,6 @@ struct netdev_vif {
        struct slsi_tcp_ack_s *last_tcp_ack;
        struct slsi_tcp_ack_s ack_suppression[TCP_ACK_SUPPRESSION_RECORDS_MAX];
        struct slsi_tcp_ack_stats tcp_ack_stats;
-#ifdef CONFIG_SCSC_WLAN_WIFI_SHARING
-       bool wifi_sharing;
-#endif
        /* traffic monitor */
        ktime_t last_timer_time;
        u32 report_time;
@@ -972,6 +972,7 @@ struct slsi_dev {
 #endif
        int                        netdev_up_count;
        struct net_device          __rcu *netdev[CONFIG_SCSC_WLAN_MAX_INTERFACES + 1];               /* 0 is reserved */
+       struct net_device          __rcu *netdev_ap;
        u8                         netdev_addresses[CONFIG_SCSC_WLAN_MAX_INTERFACES + 1][ETH_ALEN];  /* 0 is reserved */
 
        int                        device_state;
@@ -1233,4 +1234,8 @@ static inline int slsi_get_supported_mode(const u8 *peer_ie)
        return SLSI_80211_MODE_11B;
 }
 
+/* Names of full mode HCF files */
+extern char *slsi_mib_file;
+extern char *slsi_mib_file2;
+
 #endif
index de762b2e5f4979604771b34f46e8c32cfb192a38..3ae77329d489adb1823b9fa9dc7acffa182cd9d3 100755 (executable)
@@ -1913,7 +1913,7 @@ int hip4_init(struct slsi_hip4 *hip)
        memset(&hip->hip_priv->stats, 0, sizeof(hip->hip_priv->stats));
        hip->hip_priv->stats.start = ktime_get();
        hip->hip_priv->stats.procfs_dir = proc_mkdir("driver/hip4", NULL);
-       if (!hip->hip_priv->stats.procfs_dir) {
+       if (hip->hip_priv->stats.procfs_dir) {
                proc_create_data("info", S_IRUSR | S_IRGRP,
                                 hip->hip_priv->stats.procfs_dir, &hip4_procfs_stats_fops, hip);
                proc_create_data("history", S_IRUSR | S_IRGRP,
index 4da79ab1b247d6fd877d3005113d22099e9c81a8..bc4e8e521177626f0b657beeebf51b12c0bf90e6 100755 (executable)
@@ -665,22 +665,10 @@ static ssize_t slsi_create_interface(struct net_device *dev, char *intf_name)
        struct netdev_vif *ndev_vif = netdev_priv(dev);
        struct slsi_dev   *sdev = ndev_vif->sdev;
        struct net_device   *swlan_dev;
-       struct netdev_vif *ndev_swlan_vif;
 
        swlan_dev = slsi_get_netdev(sdev, SLSI_NET_INDEX_P2PX_SWLAN);
-       if (swlan_dev) {
-               SLSI_NET_ERR(dev, "swlan already created\n");
-               return -EINVAL;
-       }
-
-       swlan_dev = slsi_new_interface_create(sdev->wiphy, intf_name, NL80211_IFTYPE_AP, NULL);
-       if (swlan_dev) {
-               ndev_swlan_vif = netdev_priv(swlan_dev);
-               SLSI_MUTEX_LOCK(ndev_swlan_vif->vif_mutex);
-               ndev_swlan_vif->wifi_sharing = true;
-               SLSI_MUTEX_UNLOCK(ndev_swlan_vif->vif_mutex);
+       if (swlan_dev && (swlan_dev->name == intf_name))
                return 0;
-       }
 
        SLSI_NET_ERR(dev, "Failed to create interface %s\n", intf_name);
        return -EINVAL;
@@ -690,23 +678,18 @@ static ssize_t slsi_delete_interface(struct net_device *dev, char *intf_name)
 {
        struct netdev_vif *ndev_vif = netdev_priv(dev);
        struct slsi_dev   *sdev = ndev_vif->sdev;
+       struct net_device   *swlan_dev;
 
-       if (strcmp(intf_name, "swlan0") == 0)
-               dev = sdev->netdev[SLSI_NET_INDEX_P2PX_SWLAN];
-
-       if (WARN_ON(!dev))
-               return -EINVAL;
-       ndev_vif = netdev_priv(dev);
-
-       SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
-       ndev_vif->wifi_sharing = false;
-       SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
-
-       if (ndev_vif->activated)
-               slsi_stop_net_dev(sdev, dev);
-       slsi_netif_remove_rtlnl_locked(sdev, dev);
+       swlan_dev = slsi_get_netdev(sdev, SLSI_NET_INDEX_P2PX_SWLAN);
+       if (swlan_dev && (swlan_dev->name == intf_name)) {
+               ndev_vif = netdev_priv(swlan_dev);
+               if (ndev_vif->activated)
+                       slsi_stop_net_dev(sdev, swlan_dev);
+               return 0;
+       }
 
-       return 0;
+       SLSI_NET_ERR(dev, "Failed to delete interface %s\n", intf_name);
+       return -EINVAL;
 }
 
 static ssize_t slsi_set_indoor_channels(struct net_device *dev, char *arg)
@@ -2129,7 +2112,7 @@ int slsi_get_sta_info(struct net_device *dev, char *command, int buf_len)
        if (ap_dev) {
                ndev_ap_vif = netdev_priv(ap_dev);
                SLSI_MUTEX_LOCK(ndev_ap_vif->vif_mutex);
-               if (SLSI_IS_INTERFACE_WIFI_SHARING_AP(ndev_ap_vif))
+               if (SLSI_IS_VIF_INDEX_MHS(sdev, ndev_ap_vif))
                        ndev_vif = ndev_ap_vif;
                SLSI_MUTEX_UNLOCK(ndev_ap_vif->vif_mutex);
        }
@@ -2144,9 +2127,17 @@ int slsi_get_sta_info(struct net_device *dev, char *command, int buf_len)
                return -EINVAL;
        }
 
-       len = snprintf(command, buf_len, "wl_get_sta_info : %02x%02x%02x %u %d %d %d %d %d %d %u ",
-                      ndev_vif->ap.last_disconnected_sta.address[0], ndev_vif->ap.last_disconnected_sta.address[1],
-                      ndev_vif->ap.last_disconnected_sta.address[2], ndev_vif->ap.channel_freq,
+       len = snprintf(command, buf_len, "GETSTAINFO %pM Rx_Retry_Pkts=%d Rx_BcMc_Pkts=%d CAP=%04x %02x:%02x:%02x ",
+                      ndev_vif->ap.last_disconnected_sta.address,
+                      ndev_vif->ap.last_disconnected_sta.rx_retry_packets,
+                      ndev_vif->ap.last_disconnected_sta.rx_bc_mc_packets,
+                      ndev_vif->ap.last_disconnected_sta.capabilities,
+                      ndev_vif->ap.last_disconnected_sta.address[0],
+                      ndev_vif->ap.last_disconnected_sta.address[1],
+                      ndev_vif->ap.last_disconnected_sta.address[2]);
+
+       len += snprintf(&command[len], (buf_len - len), "%d %d %d %d %d %d %d %u",
+                      ieee80211_frequency_to_channel(ndev_vif->ap.channel_freq),
                       ndev_vif->ap.last_disconnected_sta.bandwidth, ndev_vif->ap.last_disconnected_sta.rssi,
                       ndev_vif->ap.last_disconnected_sta.tx_data_rate, ndev_vif->ap.last_disconnected_sta.mode,
                       ndev_vif->ap.last_disconnected_sta.antenna_mode,
index 8a4b08614bfce6233f4a5a088c32e29375e6771c..52baef68d451e7a67d062ac84cdf223b262d34a4 100755 (executable)
@@ -547,9 +547,13 @@ int slsi_start(struct slsi_dev *sdev)
        sdev->collect_mib.enabled = false;
 #endif
 #ifndef CONFIG_SCSC_DOWNLOAD_FILE
-       if (slsi_is_rf_test_mode_enabled()) {
+       /* The "_t" HCF is used in RF Test mode and wlanlite/production test mode */
+       if (slsi_is_rf_test_mode_enabled() || slsi_is_test_mode_enabled()) {
                sdev->mib[0].mib_file_name = mib_file_t;
                sdev->mib[1].mib_file_name = mib_file2_t;
+       } else {
+               sdev->mib[0].mib_file_name = slsi_mib_file;
+               sdev->mib[1].mib_file_name = slsi_mib_file2;
        }
 
        /* Place MIB files in shared memory */
@@ -700,7 +704,7 @@ done:
        return err;
 }
 
-struct net_device *slsi_new_interface_create(struct wiphy        *wiphy,
+struct net_device *slsi_dynamic_interface_create(struct wiphy        *wiphy,
                                             const char          *name,
                                             enum nl80211_iftype type,
                                             struct vif_params   *params)
@@ -713,7 +717,7 @@ struct net_device *slsi_new_interface_create(struct wiphy        *wiphy,
 
        SLSI_DBG1(sdev, SLSI_CFG80211, "name:%s\n", name);
 
-       iface = slsi_netif_add(sdev, name);
+       iface = slsi_netif_dynamic_iface_add(sdev, name);
        if (iface < 0)
                return NULL;
 
@@ -871,7 +875,7 @@ void slsi_scan_cleanup(struct slsi_dev *sdev, struct net_device *dev)
        SLSI_MUTEX_LOCK(ndev_vif->scan_mutex);
        for (i = 0; i < SLSI_SCAN_MAX; i++) {
                if (ndev_vif->scan[i].scan_req && !sdev->mlme_blocked &&
-                   SLSI_IS_VIF_INDEX_P2P_GROUP(ndev_vif))
+                   SLSI_IS_VIF_INDEX_P2P_GROUP(sdev, ndev_vif))
                        slsi_mlme_del_scan(sdev, dev, (ndev_vif->ifnum << 8 | i), false);
                slsi_purge_scan_results(ndev_vif, i);
                if (ndev_vif->scan[i].scan_req && i == SLSI_SCAN_HW_ID)
@@ -1105,7 +1109,7 @@ static int slsi_mib_get_platform(struct slsi_dev_mib_info *mib_info)
        {
                size_t trunc_len = plat_name_len;
 
-               if (trunc_len > sizeof(mib_info->platform))
+               if (trunc_len >= sizeof(mib_info->platform))
                        trunc_len = sizeof(mib_info->platform) - 1;
 
                /* Extract platform name */
@@ -2411,6 +2415,9 @@ static int slsi_fill_last_disconnected_sta_info(struct slsi_dev *sdev, struct ne
        for (i = 0; i < ARRAY_SIZE(get_values); i++)
                get_values[i].index[0] = last_peer->aid;
 
+       ndev_vif->ap.last_disconnected_sta.rx_retry_packets = SLSI_DEFAULT_UNIFI_PEER_RX_RETRY_PACKETS;
+       ndev_vif->ap.last_disconnected_sta.rx_bc_mc_packets = SLSI_DEFAULT_UNIFI_PEER_RX_BC_MC_PACKETS;
+       ndev_vif->ap.last_disconnected_sta.capabilities = last_peer->capabilities;
        ndev_vif->ap.last_disconnected_sta.bandwidth = SLSI_DEFAULT_UNIFI_PEER_BANDWIDTH;
        ndev_vif->ap.last_disconnected_sta.antenna_mode = SLSI_DEFAULT_UNIFI_PEER_NSS;
        ndev_vif->ap.last_disconnected_sta.rssi = SLSI_DEFAULT_UNIFI_PEER_RSSI;
@@ -2486,15 +2493,15 @@ int slsi_handle_disconnect(struct slsi_dev *sdev, struct net_device *dev, u8 *pe
                 * the connection with the AP has been lost
                 */
                if (ndev_vif->sta.vif_status == SLSI_VIF_STATUS_CONNECTING) {
-                       if (peer_address)
-                               SLSI_NET_WARN(dev, "Unexpected mlme_disconnect_ind - whilst connecting\n");
-                       else
+                       if (!peer_address)
                                SLSI_NET_WARN(dev, "Connection failure\n");
                } else if (ndev_vif->sta.vif_status == SLSI_VIF_STATUS_CONNECTED) {
                        if (reason == FAPI_REASONCODE_SYNCHRONISATION_LOSS)
                                reason = 0; /*reason code to recognise beacon loss */
                        else if (reason == FAPI_REASONCODE_KEEP_ALIVE_FAILURE)
                                reason = WLAN_REASON_DEAUTH_LEAVING;/* Change to a standard reason code */
+                       else if (reason >= 0x8200 && reason <= 0x82FF)
+                               reason = reason & 0x00FF;
 
                        if (ndev_vif->sta.is_wps) /* Ignore sending deauth or disassoc event to cfg80211 during WPS session */
                                SLSI_NET_INFO(dev, "Ignoring Deauth notification to cfg80211 from the peer during WPS procedure\n");
@@ -3872,23 +3879,52 @@ u8 slsi_p2p_get_exp_peer_frame_subtype(u8 subtype)
        }
 }
 
-void slsi_wlan_dump_public_action_subtype(struct ieee80211_mgmt *mgmt, bool tx)
+void slsi_wlan_dump_public_action_subtype(struct slsi_dev *sdev, struct ieee80211_mgmt *mgmt, bool tx)
 {
        u8 action_code = ((u8 *)&mgmt->u.action.u)[0];
        u8 action_category = mgmt->u.action.category;
+       char *tx_rx_string = "Received";
+       char wnm_action_fields[28][35] = { "Event Request", "Event Report", "Diagnostic Request",
+                                          "Diagnostic Report", "Location Configuration Request",
+                                          "Location Configuration Response", "BSS Transition Management Query",
+                                          "BSS Transition Management Request",
+                                          "BSS Transition Management Response", "FMS Request", "FMS Response",
+                                          "Collocated Interference Request", "Collocated Interference Report",
+                                          "TFS Request", "TFS Response", "TFS Notify", "WNM Sleep Mode Request",
+                                          "WNM Sleep Mode Response", "TIM Broadcast Request",
+                                          "TIM Broadcast Response", "QoS Traffic Capability Update",
+                                          "Channel Usage Request", "Channel Usage Response", "DMS Request",
+                                          "DMS Response", "Timing Measurement Request",
+                                          "WNM Notification Request", "WNM Notification Response" };
+
+       if (tx)
+               tx_rx_string = "Send";
 
        switch (action_category) {
        case WLAN_CATEGORY_RADIO_MEASUREMENT:
                switch (action_code) {
+               case SLSI_RM_RADIO_MEASUREMENT_REQ:
+                       SLSI_INFO(sdev, "%s Radio Measurement Frame (Radio Measurement Req)\n", tx_rx_string);
+                       break;
+               case SLSI_RM_RADIO_MEASUREMENT_REP:
+                       SLSI_INFO(sdev, "%s Radio Measurement Frame (Radio Measurement Rep)\n", tx_rx_string);
+                       break;
+               case SLSI_RM_LINK_MEASUREMENT_REQ:
+                       SLSI_INFO(sdev, "%s Radio Measurement Frame (Link Measurement Req)\n", tx_rx_string);
+                       break;
+               case SLSI_RM_LINK_MEASUREMENT_REP:
+                       SLSI_INFO(sdev, "%s Radio Measurement Frame (Link Measurement Rep)\n", tx_rx_string);
+                       break;
                case SLSI_RM_NEIGH_REP_REQ:
-                       SLSI_DBG1_NODEV(SLSI_CFG80211, "%s: RM Neigh Report Request\n", tx ? "TX" : "RX");
+                       SLSI_INFO(sdev, "%s Radio Measurement Frame (Neighbor Report Req)\n", tx_rx_string);
                        break;
                case SLSI_RM_NEIGH_REP_RSP:
-                       SLSI_DBG1_NODEV(SLSI_CFG80211, "%s: RM Neigh Report Response\n", tx ? "TX" : "RX");
+                       SLSI_INFO(sdev, "%s Radio Measurement Frame (Neighbor Report Resp)\n", tx_rx_string);
                        break;
                default:
-                       SLSI_DBG1_NODEV(SLSI_CFG80211, "Unknown Radio Measurement Frame : %d\n", action_code);
+                       SLSI_INFO(sdev, "%s Radio Measurement Frame (Reserved)\n", tx_rx_string);
                }
+               break;
        case WLAN_CATEGORY_PUBLIC:
                switch (action_code) {
                case SLSI_PA_GAS_INITIAL_REQ:
@@ -3906,6 +3942,13 @@ void slsi_wlan_dump_public_action_subtype(struct ieee80211_mgmt *mgmt, bool tx)
                default:
                        SLSI_DBG1_NODEV(SLSI_CFG80211, "Unknown GAS Frame : %d\n", action_code);
                }
+               break;
+       case WLAN_CATEGORY_WNM:
+               if (action_code >= SLSI_WNM_ACTION_FIELD_MIN && action_code <= SLSI_WNM_ACTION_FIELD_MAX)
+                       SLSI_INFO(sdev, "%s WNM Frame (%s)\n", tx_rx_string, wnm_action_fields[action_code]);
+               else
+                       SLSI_INFO(sdev, "%s WNM Frame (Reserved)\n", tx_rx_string);
+               break;
        }
 }
 
index db928f324b180dbe9aa39fcf059239879380a24d..19ab4479fbf97d4c97d0d1917ab206a92b322bd1 100755 (executable)
@@ -28,8 +28,9 @@
 #define SLSI_IEEE8021X_TYPE_EAPOL_KEY    3
 #define SLSI_IEEE8021X_TYPE_EAP_PACKET   0
 
-#define SLSI_EAPOL_KEY_INFO_KEY_TYPE_BIT_IN_LOWER_BYTE     (1 << 3) /* Group = 0, Pairwise = 1 */
-#define SLSI_EAPOL_KEY_INFO_MIC_BIT_IN_HIGHER_BYTE           (1 << 0)
+#define SLSI_EAPOL_KEY_INFO_KEY_TYPE_BIT_IN_LOWER_BYTE      BIT(3) /* Group = 0, Pairwise = 1 */
+#define SLSI_EAPOL_KEY_INFO_MIC_BIT_IN_HIGHER_BYTE          BIT(0)
+#define SLSI_EAPOL_KEY_INFO_SECURE_BIT_IN_HIGHER_BYTE       BIT(1)
 /* pkt_data would start from 802.1X Authentication field (pkt_data[0] = Version).
  * For M4 packet, it will be something as below... member(size, position)
  * Version (1, 0) + Type (1, 1) + Length (2, 2:3) + Descriptor Type (1, 4) + Key Information (2, 5:6) +
 #define SLSI_IS_VIF_INDEX_WLAN(ndev_vif) (ndev_vif->ifnum == SLSI_NET_INDEX_WLAN)
 #define SLSI_IS_VIF_INDEX_P2P(ndev_vif) (ndev_vif->ifnum == SLSI_NET_INDEX_P2P)
 #ifdef CONFIG_SCSC_WLAN_WIFI_SHARING
-#define SLSI_IS_VIF_INDEX_P2P_GROUP(ndev_vif) ((ndev_vif->ifnum == SLSI_NET_INDEX_P2PX_SWLAN) &&\
-                                              (ndev_vif->wifi_sharing == 0))
-#define SLSI_IS_INTERFACE_WIFI_SHARING_AP(ndev_vif) ((ndev_vif->ifnum == SLSI_NET_INDEX_P2PX_SWLAN) &&\
-                                                    (ndev_vif->wifi_sharing == 1))
+#define SLSI_IS_VIF_INDEX_P2P_GROUP(sdev, ndev_vif) ((ndev_vif->ifnum == SLSI_NET_INDEX_P2PX_SWLAN) &&\
+                                                    (sdev->netdev_ap != sdev->netdev[SLSI_NET_INDEX_P2PX_SWLAN]))
+#define SLSI_IS_VIF_INDEX_MHS(sdev, ndev_vif) ((ndev_vif->ifnum == SLSI_NET_INDEX_P2PX_SWLAN) &&\
+                                              (sdev->netdev_ap == sdev->netdev[SLSI_NET_INDEX_P2PX_SWLAN]))
 #else
-#define SLSI_IS_VIF_INDEX_P2P_GROUP(ndev_vif) (ndev_vif->ifnum == SLSI_NET_INDEX_P2PX_SWLAN)
+#define SLSI_IS_VIF_INDEX_P2P_GROUP(sdev, ndev_vif) (ndev_vif->ifnum == SLSI_NET_INDEX_P2PX_SWLAN)
 #endif
 #define SLSI_IS_VIF_INDEX_NAN(ndev_vif) ((ndev_vif)->ifnum == SLSI_NET_INDEX_NAN)
 
 #define SLSI_PA_GAS_COMEBACK_RSP (13)
 
 /*Radio Measurement action frames types */
-#define SLSI_RM_NEIGH_REP_REQ  (4)
-#define SLSI_RM_NEIGH_REP_RSP  (5)
+#define SLSI_RM_RADIO_MEASUREMENT_REQ (0)
+#define SLSI_RM_RADIO_MEASUREMENT_REP (1)
+#define SLSI_RM_LINK_MEASUREMENT_REQ  (2)
+#define SLSI_RM_LINK_MEASUREMENT_REP  (3)
+#define SLSI_RM_NEIGH_REP_REQ         (4)
+#define SLSI_RM_NEIGH_REP_RSP         (5)
+
+#define SLSI_WNM_ACTION_FIELD_MIN (0)
+#define SLSI_WNM_ACTION_FIELD_MAX (27)
 
 /* For service discovery action frames dummy subtype is used by setting the 7th bit */
 #define SLSI_PA_GAS_DUMMY_SUBTYPE_MASK   0x80
 
 #define SLSI_DHCP_MSG_MAGIC_OFFSET 278
 #define SLSI_DHCP_OPTION 53
-#define SLSI_DHCP_MESSAGE_TYPE_OFFER 0x02
-#define SLSI_DHCP_MESSAGE_TYPE_ACK 0x05
+#define SLSI_DHCP_MESSAGE_TYPE_DISCOVER   0x01
+#define SLSI_DHCP_MESSAGE_TYPE_OFFER      0x02
+#define SLSI_DHCP_MESSAGE_TYPE_REQUEST    0x03
+#define SLSI_DHCP_MESSAGE_TYPE_DECLINE    0x04
+#define SLSI_DHCP_MESSAGE_TYPE_ACK        0x05
+#define SLSI_DHCP_MESSAGE_TYPE_NAK        0x06
+#define SLSI_DHCP_MESSAGE_TYPE_RELEASE    0x07
+#define SLSI_DHCP_MESSAGE_TYPE_INFORM     0x08
+#define SLSI_DHCP_MESSAGE_TYPE_FORCERENEW 0x09
+#define SLSI_DHCP_MESSAGE_TYPE_INVALID    0x0A
+
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 4, 0))
+       #define WLAN_CATEGORY_WNM 10
+#endif
 
 enum slsi_dhcp_tx {
        SLSI_TX_IS_NOT_DHCP,
@@ -442,7 +462,7 @@ int slsi_set_mib_wifi_sharing_5ghz_channel(struct slsi_dev *sdev, u16 psid, int
 int slsi_get_byte_position(int bit);
 int slsi_check_if_channel_restricted_already(struct slsi_dev *sdev, int channel);
 #endif
-struct net_device *slsi_new_interface_create(struct wiphy        *wiphy,
+struct net_device *slsi_dynamic_interface_create(struct wiphy        *wiphy,
                                             const char          *name,
                                             enum nl80211_iftype type,
                                             struct vif_params   *params);
@@ -474,7 +494,7 @@ void slsi_update_supported_channels_regd_flags(struct slsi_dev *sdev);
 #ifdef CONFIG_SCSC_WLAN_HANG_TEST
 int slsi_test_send_hanged_vendor_event(struct net_device *dev);
 #endif
-void slsi_wlan_dump_public_action_subtype(struct ieee80211_mgmt *mgmt, bool tx);
+void slsi_wlan_dump_public_action_subtype(struct slsi_dev *sdev, struct ieee80211_mgmt *mgmt, bool tx);
 void slsi_reset_channel_flags(struct slsi_dev *sdev);
 
 /* Sysfs based mac address override */
index 7528441b2831df4bfbf9515d95acaa593f9dbb64..127ce2e6a1876d9f42a8f4c5fb3f2454be15ff9b 100755 (executable)
@@ -1,6 +1,6 @@
 /*****************************************************************************
  *
- * Copyright (c) 2012 - 2018 Samsung Electronics Co., Ltd. All rights reserved
+ * Copyright (c) 2012 - 2019 Samsung Electronics Co., Ltd. All rights reserved
  *
  ****************************************************************************/
 
@@ -2345,15 +2345,11 @@ int slsi_mlme_disconnect(struct slsi_dev *sdev, struct net_device *dev, u8 *mac,
 
        SLSI_NET_DBG1(dev, SLSI_MLME, "mlme_disconnect_req(vif:%u, bssid:%pM, reason:%d)\n", ndev_vif->ifnum, mac, reason_code);
 
-#ifdef CONFIG_SCSC_LOG_COLLECTION
-       scsc_log_collector_schedule_collection(SCSC_LOG_HOST_WLAN, SCSC_LOG_HOST_WLAN_REASON_DISCONNECT);
-#else
-       mx140_log_dump();
-#endif
        /* No data reference required */
        req = fapi_alloc(mlme_disconnect_req, MLME_DISCONNECT_REQ, ndev_vif->ifnum, 0);
        if (!req)
                return -ENOMEM;
+       SLSI_INFO(sdev, "Send DEAUTH, reason = %d\n", reason_code);
        fapi_set_u16(req, u.mlme_disconnect_req.reason_code, reason_code);
        if (mac)
                fapi_set_memcpy(req, u.mlme_disconnect_req.peer_sta_address, mac);
index 7e2c2f781a916166b9783ac551de9341abb30868..dd9e6ed8c15b609ad51f8d12fa74a33082080b9e 100755 (executable)
@@ -101,10 +101,12 @@ extern struct ieee80211_sta_vht_cap       slsi_vht_cap;
 #define SLSI_MAX_PATTERN_LENGTH 6
 
 /*Default values of MIBS params for GET_STA_INFO driver private command */
-#define SLSI_DEFAULT_UNIFI_PEER_BANDWIDTH             -1
-#define SLSI_DEFAULT_UNIFI_PEER_NSS                          0
-#define SLSI_DEFAULT_UNIFI_PEER_RSSI                         1
-#define SLSI_DEFAULT_UNIFI_PEER_TX_DATA_RATE          0
+#define SLSI_DEFAULT_UNIFI_PEER_RX_RETRY_PACKETS 0
+#define SLSI_DEFAULT_UNIFI_PEER_RX_BC_MC_PACKETS 0
+#define SLSI_DEFAULT_UNIFI_PEER_BANDWIDTH       -1
+#define SLSI_DEFAULT_UNIFI_PEER_NSS              0
+#define SLSI_DEFAULT_UNIFI_PEER_RSSI             1
+#define SLSI_DEFAULT_UNIFI_PEER_TX_DATA_RATE     0
 
 #define SLSI_CHECK_TYPE(sdev, recv_type, exp_type) \
        do { \
index 82094c0fd42dd6bdfe3c5e76e7d9c9fd80d2be60..9bb0f622ff30d052a8e1f69ac63e207f8e9ff4ce 100755 (executable)
@@ -177,7 +177,7 @@ static int slsi_net_open(struct net_device *dev)
        }
 
 #ifdef CONFIG_SCSC_WLAN_WIFI_SHARING
-       if (SLSI_IS_INTERFACE_WIFI_SHARING_AP(ndev_vif))
+       if (SLSI_IS_VIF_INDEX_MHS(sdev, ndev_vif))
                SLSI_ETHER_COPY(dev->dev_addr, sdev->netdev_addresses[SLSI_NET_INDEX_P2P]);
        else
                SLSI_ETHER_COPY(dev->dev_addr, sdev->netdev_addresses[ndev_vif->ifnum]);
@@ -1160,7 +1160,7 @@ int slsi_netif_add_locked(struct slsi_dev *sdev, const char *name, int ifnum)
        netif_carrier_off(dev);
 
 #ifdef CONFIG_SCSC_WLAN_WIFI_SHARING
-       if (strcmp(name, "swlan0") == 0)
+       if (strcmp(name, CONFIG_SCSC_AP_INTERFACE_NAME) == 0)
                SLSI_ETHER_COPY(dev->dev_addr, sdev->netdev_addresses[SLSI_NET_INDEX_P2P]);
        else
                SLSI_ETHER_COPY(dev->dev_addr, sdev->netdev_addresses[ifnum]);
@@ -1182,31 +1182,22 @@ exit_with_error:
        return ret;
 }
 
-int slsi_netif_add(struct slsi_dev *sdev, const char *name)
+int slsi_netif_dynamic_iface_add(struct slsi_dev *sdev, const char *name)
 {
        int index = -EINVAL;
-       int i;
        int err;
 
        SLSI_MUTEX_LOCK(sdev->netdev_add_remove_mutex);
 
-       for (i = 1; i <= CONFIG_SCSC_WLAN_MAX_INTERFACES; i++)
-               if (!sdev->netdev[i]) {
-                       index = i;
-                       break;
-               }
-
-       if (index > 0) {
-               err = slsi_netif_add_locked(sdev, name, index);
-               if (err != 0)
-                       index = err;
+       if (sdev->netdev[SLSI_NET_INDEX_P2PX_SWLAN] == sdev->netdev_ap) {
+               rcu_assign_pointer(sdev->netdev[SLSI_NET_INDEX_P2PX_SWLAN], NULL);
+               err = slsi_netif_add_locked(sdev, name, SLSI_NET_INDEX_P2PX_SWLAN);
+               index = err ? err : SLSI_NET_INDEX_P2PX_SWLAN;
        }
        SLSI_MUTEX_UNLOCK(sdev->netdev_add_remove_mutex);
        return index;
 }
 
-static void slsi_netif_remove_locked(struct slsi_dev *sdev, struct net_device *dev);
-
 int slsi_netif_init(struct slsi_dev *sdev)
 {
        int i;
@@ -1231,11 +1222,21 @@ int slsi_netif_init(struct slsi_dev *sdev)
                SLSI_MUTEX_UNLOCK(sdev->netdev_add_remove_mutex);
                return -EINVAL;
        }
+
+       if (slsi_netif_add_locked(sdev, CONFIG_SCSC_AP_INTERFACE_NAME, SLSI_NET_INDEX_P2PX_SWLAN) != 0) {
+               rtnl_lock();
+               slsi_netif_remove_locked(sdev, sdev->netdev[SLSI_NET_INDEX_WLAN]);
+               slsi_netif_remove_locked(sdev, sdev->netdev[SLSI_NET_INDEX_P2P]);
+               rtnl_unlock();
+               SLSI_MUTEX_UNLOCK(sdev->netdev_add_remove_mutex);
+               return -EINVAL;
+       }
 #if CONFIG_SCSC_WLAN_MAX_INTERFACES >= 4
        if (slsi_netif_add_locked(sdev, "nan%d", SLSI_NET_INDEX_NAN) != 0) {
                rtnl_lock();
                slsi_netif_remove_locked(sdev, sdev->netdev[SLSI_NET_INDEX_WLAN]);
                slsi_netif_remove_locked(sdev, sdev->netdev[SLSI_NET_INDEX_P2P]);
+               slsi_netif_remove_locked(sdev, sdev->netdev[SLSI_NET_INDEX_P2PX_SWLAN]);
                rtnl_unlock();
                SLSI_MUTEX_UNLOCK(sdev->netdev_add_remove_mutex);
                return -EINVAL;
@@ -1287,7 +1288,7 @@ int slsi_netif_register(struct slsi_dev *sdev, struct net_device *dev)
        return err;
 }
 
-static void slsi_netif_remove_locked(struct slsi_dev *sdev, struct net_device *dev)
+void slsi_netif_remove_locked(struct slsi_dev *sdev, struct net_device *dev)
 {
        int               i;
        struct netdev_vif *ndev_vif = netdev_priv(dev);
@@ -1374,6 +1375,7 @@ void slsi_netif_remove_all(struct slsi_dev *sdev)
        for (i = 1; i <= CONFIG_SCSC_WLAN_MAX_INTERFACES; i++)
                if (sdev->netdev[i])
                        slsi_netif_remove_locked(sdev, sdev->netdev[i]);
+       rcu_assign_pointer(sdev->netdev_ap, NULL);
        SLSI_MUTEX_UNLOCK(sdev->netdev_add_remove_mutex);
        rtnl_unlock();
 }
old mode 100644 (file)
new mode 100755 (executable)
index 7eacfd7..3a59c94
@@ -91,7 +91,7 @@ struct slsi_peer;
 
 int slsi_netif_init(struct slsi_dev *sdev);
 /* returns the index or -E<error> code */
-int slsi_netif_add(struct slsi_dev *sdev, const char *name);
+int slsi_netif_dynamic_iface_add(struct slsi_dev *sdev, const char *name);
 int slsi_netif_register(struct slsi_dev *sdev, struct net_device *dev);
 int slsi_netif_register_rtlnl_locked(struct slsi_dev *sdev, struct net_device *dev);
 void slsi_netif_remove(struct slsi_dev *sdev, struct net_device *dev);
@@ -100,5 +100,6 @@ void slsi_netif_remove_all(struct slsi_dev *sdev);
 void slsi_netif_deinit(struct slsi_dev *sdev);
 void slsi_tdls_move_packets(struct slsi_dev *sdev, struct net_device *dev,
                            struct slsi_peer *sta_peer, struct slsi_peer *tdls_peer, bool connection);
+void slsi_netif_remove_locked(struct slsi_dev *sdev, struct net_device *dev);
 
 #endif /*__SLSI_NETIF_H__*/
index c475041fa73e04d7ade6d50987a82e8781958dfa..50679c5ed3dfc3a8a5f6668e232a0e36253c3693 100755 (executable)
@@ -2613,7 +2613,7 @@ static void slsi_lls_iface_ap_stats(struct slsi_dev *sdev, struct netdev_vif *nd
                peer_type = SLSI_LLS_PEER_STA;
        } else if (ndev_vif->ifnum == SLSI_NET_INDEX_P2PX_SWLAN) {
                dev = sdev->netdev[SLSI_NET_INDEX_P2PX_SWLAN];
-               if (SLSI_IS_VIF_INDEX_P2P_GROUP(ndev_vif)) {
+               if (SLSI_IS_VIF_INDEX_P2P_GROUP(sdev, ndev_vif)) {
                        iface_stat->info.mode = SLSI_LLS_INTERFACE_P2P_GO;
                        peer_type = SLSI_LLS_PEER_P2P_CLIENT;
                }
@@ -3323,8 +3323,10 @@ void slsi_rx_range_ind(struct slsi_dev *sdev, struct net_device *dev, struct sk_
        nl_skb = cfg80211_vendor_event_alloc(sdev->wiphy, NLMSG_DEFAULT_SIZE, SLSI_NL80211_RTT_RESULT_EVENT,
                                             GFP_KERNEL);
 #endif
+#ifdef CONFIG_SCSC_WLAN_DEBUG
        SLSI_DBG1_NODEV(SLSI_GSCAN, "Event: %s(%d)\n",
                        slsi_print_event_name(SLSI_NL80211_RTT_RESULT_EVENT), SLSI_NL80211_RTT_RESULT_EVENT);
+#endif
 
        if (!nl_skb) {
                SLSI_ERR(sdev, "NO MEM for nl_skb!!!\n");
@@ -3410,8 +3412,10 @@ void slsi_rx_range_done_ind(struct slsi_dev *sdev, struct net_device *dev, struc
        struct netdev_vif *ndev_vif = netdev_priv(dev);
        u16 rtt_id = fapi_get_u16(skb, u.mlme_range_ind.rtt_id);
        SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
+#ifdef CONFIG_SCSC_WLAN_DEBUG
        SLSI_DBG1_NODEV(SLSI_GSCAN, "Event: %s(%d)\n",
                        slsi_print_event_name(SLSI_NL80211_RTT_COMPLETE_EVENT), SLSI_NL80211_RTT_COMPLETE_EVENT);
+#endif
        slsi_vendor_event(sdev, SLSI_NL80211_RTT_COMPLETE_EVENT, &rtt_id, sizeof(rtt_id));
        slsi_kfree_skb(skb);
        SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
@@ -4788,6 +4792,7 @@ void slsi_nan_followup_ind(struct slsi_dev *sdev, struct net_device *dev, struct
        fapi_data_len = fapi_get_datalen(skb);
        if (!fapi_data_len) {
                SLSI_ERR(sdev, "mlme_nan_followup_ind no mbulk data\n");
+               kfree(hal_evt);
                return;
        }
 
@@ -4797,17 +4802,20 @@ void slsi_nan_followup_ind(struct slsi_dev *sdev, struct net_device *dev, struct
                ptr = fapi_data_p;
                if (fapi_data_len < ptr[1] + 2) {
                        SLSI_ERR(sdev, "len err[avail:%d,ie:%d]\n", fapi_data_len, fapi_data_p[1] + 2);
+                       kfree(hal_evt);
                        return;
                }
                if (ptr[1] < sizeof(followup_ie_header) - 2 + 6 + 1 + 1) {
                        SLSI_ERR(sdev, "len err[min:%d,ie:%d]\n", (u32)sizeof(followup_ie_header) - 2 + 6 + 1 + 1,
                                 fapi_data_p[1] + 2);
+                       kfree(hal_evt);
                        return;
                }
                if (followup_ie_header[0] != ptr[0] ||  followup_ie_header[2] != ptr[2] ||
                    followup_ie_header[3] != ptr[3] ||  followup_ie_header[4] != ptr[4] ||
                    followup_ie_header[5] != ptr[5] || followup_ie_header[6] != ptr[6]) {
                        SLSI_ERR(sdev, "unknown IE:%x-%d\n", fapi_data_p[0], fapi_data_p[1] + 2);
+                       kfree(hal_evt);
                        return;
                }
 
@@ -4825,6 +4833,7 @@ void slsi_nan_followup_ind(struct slsi_dev *sdev, struct net_device *dev, struct
                        ptr += 2;
                        if (fapi_data_p[1] + 2 < (ptr - fapi_data_p) + tag_len) {
                                SLSI_ERR(sdev, "TLV error\n");
+                               kfree(hal_evt);
                                return;
                        }
                        if (tag_id == SLSI_FAPI_NAN_SERVICE_SPECIFIC_INFO) {
index 1ef94dd567a7a144047c571f79cf985fa845c59b..2b3a402eb3fac863fcabdd967e43bc38f47f552f 100755 (executable)
@@ -385,6 +385,8 @@ static int slsi_procfs_build_show(struct seq_file *m, void *v)
 #else
        seq_puts(m, "CONFIG_SCSC_WLAN_ENHANCED_LOGGING                      : n\n");
 #endif
+       seq_printf(m, "CONFIG_SCSC_AP_INTERFACE_NAME                   : %s\n", CONFIG_SCSC_AP_INTERFACE_NAME);
+
        return 0;
 }
 
index 693f6e9ad026e9dedbca27ffd94d1edee8d53816..ded0e3a6271d757d6b40ea7b707a093b3504e2b4 100755 (executable)
@@ -1,6 +1,6 @@
 /*****************************************************************************
  *
- * Copyright (c) 2012 - 2018 Samsung Electronics Co., Ltd. All rights reserved
+ * Copyright (c) 2012 - 2019 Samsung Electronics Co., Ltd. All rights reserved
  *
  ****************************************************************************/
 #include <linux/etherdevice.h>
@@ -1285,8 +1285,10 @@ void slsi_rx_roamed_ind(struct slsi_dev *sdev, struct net_device *dev, struct sk
 #endif
 
        if (!ndev_vif->sta.sta_bss || !ndev_vif->sta.roam_mlme_procedure_started_ind) {
-               WARN(!ndev_vif->sta.sta_bss, "bss not updated in cfg80211");
-               WARN(!ndev_vif->sta.roam_mlme_procedure_started_ind, "proc-started-ind not received before roamed-ind");
+               if (!ndev_vif->sta.sta_bss)
+                       SLSI_INFO(sdev, "BSS not updated in cfg80211\n");
+               if (!ndev_vif->sta.roam_mlme_procedure_started_ind)
+                       SLSI_INFO(sdev, "procedure-started-ind not received before roamed-ind\n");
                netif_carrier_off(dev);
                slsi_mlme_disconnect(sdev, dev, peer->address, 0, true);
                slsi_handle_disconnect(sdev, dev, peer->address, 0);
@@ -1621,6 +1623,7 @@ void slsi_rx_connected_ind(struct slsi_dev *sdev, struct net_device *dev, struct
        SLSI_NET_DBG1(dev, SLSI_MLME, "mlme_connected_ind(vif:%d, peer_index:%d)\n",
                      fapi_get_vif(skb),
                      aid);
+       SLSI_INFO(sdev, "Received Association Response\n");
 
        if (!ndev_vif->activated) {
                SLSI_NET_DBG1(dev, SLSI_MLME, "VIF not activated\n");
@@ -1795,6 +1798,7 @@ void slsi_rx_connect_ind(struct slsi_dev *sdev, struct net_device *dev, struct s
 
        SLSI_NET_DBG1(dev, SLSI_MLME, "mlme_connect_ind(vif:%d, result:%d)\n",
                      fapi_get_vif(skb), fw_result_code);
+       SLSI_INFO(sdev, "Received Association Response\n");
 
        if (!ndev_vif->activated) {
                SLSI_NET_DBG1(dev, SLSI_MLME, "VIF not activated\n");
@@ -1819,6 +1823,10 @@ void slsi_rx_connect_ind(struct slsi_dev *sdev, struct net_device *dev, struct s
        sdev->assoc_result_code = fw_result_code;
        if (fw_result_code != FAPI_RESULTCODE_SUCCESS) {
                SLSI_NET_ERR(dev, "Connect failed. FAPI code:%d\n", fw_result_code);
+#ifdef CONFIG_SCSC_LOG_COLLECTION
+               /* Trigger log collection if fw result code is not success */
+               scsc_log_collector_schedule_collection(SCSC_LOG_HOST_WLAN, SCSC_LOG_HOST_WLAN_REASON_CONNECT_ERR);
+#endif
                status = fw_result_code;
        } else {
                if (!peer || !peer->assoc_ie) {
@@ -1970,6 +1978,8 @@ void slsi_rx_disconnect_ind(struct slsi_dev *sdev, struct net_device *dev, struc
 #else
        mx140_log_dump();
 #endif
+
+       SLSI_INFO(sdev, "Received DEAUTH, reason = 0\n");
        slsi_handle_disconnect(sdev,
                               dev,
                               fapi_get_buff(skb, u.mlme_disconnect_ind.peer_sta_address),
@@ -1982,9 +1992,10 @@ void slsi_rx_disconnect_ind(struct slsi_dev *sdev, struct net_device *dev, struc
 void slsi_rx_disconnected_ind(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb)
 {
        struct netdev_vif *ndev_vif = netdev_priv(dev);
+       u16 reason;
 
        SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
-
+       reason = fapi_get_u16(skb, u.mlme_disconnected_ind.reason_code);
        SLSI_NET_DBG1(dev, SLSI_MLME, "mlme_disconnected_ind(vif:%d, reason:%d, MAC:%pM)\n",
                      fapi_get_vif(skb),
                      fapi_get_u16(skb, u.mlme_disconnected_ind.reason_code),
@@ -1995,6 +2006,15 @@ void slsi_rx_disconnected_ind(struct slsi_dev *sdev, struct net_device *dev, str
 #else
        mx140_log_dump();
 #endif
+       if (reason >= 0 && reason <= 0xFF) {
+               SLSI_INFO(sdev, "Received DEAUTH, reason = %d\n", reason);
+       } else if (reason >= 0x8200 && reason <= 0x82FF) {
+               reason = reason & 0x00FF;
+               SLSI_INFO(sdev, "Received DEAUTH, reason = %d\n", reason);
+       } else {
+               SLSI_INFO(sdev, "Received DEAUTH, reason = Local Disconnect <%d>\n", reason);
+       }
+
        if (ndev_vif->vif_type == FAPI_VIFTYPE_AP) {
                if (fapi_get_u16(skb, u.mlme_disconnected_ind.reason_code) ==
                    FAPI_REASONCODE_HOTSPOT_MAX_CLIENT_REACHED) {
@@ -2059,6 +2079,7 @@ void slsi_rx_procedure_started_ind(struct slsi_dev *sdev, struct net_device *dev
                      fapi_get_vif(skb),
                      fapi_get_u16(skb, u.mlme_procedure_started_ind.procedure_type),
                      fapi_get_u16(skb, u.mlme_procedure_started_ind.peer_index));
+       SLSI_INFO(sdev, "Send Association Request\n");
 
        if (!ndev_vif->activated) {
                SLSI_NET_DBG1(dev, SLSI_MLME, "VIF not activated\n");
@@ -2196,7 +2217,7 @@ void slsi_rx_frame_transmission_ind(struct slsi_dev *sdev, struct net_device *de
                                SLSI_P2P_STATE_CHANGE(sdev, P2P_LISTENING);
                        else
                                SLSI_P2P_STATE_CHANGE(sdev, P2P_IDLE_VIF_ACTIVE);
-               } else if (SLSI_IS_VIF_INDEX_P2P_GROUP(ndev_vif)) {
+               } else if (SLSI_IS_VIF_INDEX_P2P_GROUP(sdev, ndev_vif)) {
                        const struct ieee80211_mgmt *mgmt = (const struct ieee80211_mgmt *)ndev_vif->mgmt_tx_data.buf;
 
                        /* If frame transmission was initiated on P2P device vif by supplicant, then use the net_dev of that vif (i.e. p2p0) */
@@ -2280,6 +2301,9 @@ void slsi_rx_received_frame_ind(struct slsi_dev *sdev, struct net_device *dev, s
        struct netdev_vif *ndev_vif = netdev_priv(dev);
        u16 data_unit_descriptor = fapi_get_u16(skb, u.mlme_received_frame_ind.data_unit_descriptor);
        u16 frequency = SLSI_FREQ_FW_TO_HOST(fapi_get_u16(skb, u.mlme_received_frame_ind.channel_frequency));
+       u8 *eapol = NULL;
+       u16 protocol = 0;
+       u32 dhcp_message_type = SLSI_DHCP_MESSAGE_TYPE_INVALID;
 
        SLSI_NET_DBG2(dev, SLSI_MLME, "mlme_received_frame_ind(vif:%d, data descriptor:%d, freq:%d)\n",
                      fapi_get_vif(skb),
@@ -2309,7 +2333,7 @@ void slsi_rx_received_frame_ind(struct slsi_dev *sdev, struct net_device *dev, s
                        if (mgmt->u.action.category == WLAN_CATEGORY_WMM) {
                                cac_rx_wmm_action(sdev, dev, mgmt, mgmt_len);
                        } else {
-                               slsi_wlan_dump_public_action_subtype(mgmt, false);
+                               slsi_wlan_dump_public_action_subtype(sdev, mgmt, false);
                                if (sdev->wlan_unsync_vif_state == WLAN_UNSYNC_VIF_TX)
                                        sdev->wlan_unsync_vif_state = WLAN_UNSYNC_VIF_ACTIVE;
                        }
@@ -2354,7 +2378,8 @@ void slsi_rx_received_frame_ind(struct slsi_dev *sdev, struct net_device *dev, s
                        } else if ((sdev->p2p_group_exp_frame != SLSI_P2P_PA_INVALID) && (sdev->p2p_group_exp_frame == subtype)) {
                                SLSI_NET_DBG2(dev, SLSI_MLME, "Expected action frame (%s) received on Group VIF\n", slsi_p2p_pa_subtype_text(subtype));
                                slsi_clear_offchannel_data(sdev,
-                                                          (!SLSI_IS_VIF_INDEX_P2P_GROUP(ndev_vif)) ? true : false);
+                                                          (!SLSI_IS_VIF_INDEX_P2P_GROUP(sdev,
+                                                                                        ndev_vif)) ? true : false);
                        }
                }
 
@@ -2384,8 +2409,57 @@ void slsi_rx_received_frame_ind(struct slsi_dev *sdev, struct net_device *dev, s
 #if (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 10, 0))
                dev->last_rx = jiffies;
 #endif
+               /* Storing Data for Logging Information */
+               if ((skb->len + sizeof(struct ethhdr)) >= 99)
+                       eapol = skb->data + sizeof(struct ethhdr);
+               if (skb->len >= 285 && slsi_is_dhcp_packet(skb->data) != SLSI_TX_IS_NOT_DHCP)
+                       dhcp_message_type = skb->data[284];
 
                skb->protocol = eth_type_trans(skb, dev);
+               protocol = ntohs(skb->protocol);
+               if (protocol == ETH_P_PAE && eapol) {
+                       if (eapol[SLSI_EAPOL_IEEE8021X_TYPE_POS] == SLSI_IEEE8021X_TYPE_EAPOL_KEY) {
+                               if ((eapol[SLSI_EAPOL_TYPE_POS] == SLSI_EAPOL_TYPE_RSN_KEY ||
+                                    eapol[SLSI_EAPOL_TYPE_POS] == SLSI_EAPOL_TYPE_WPA_KEY) &&
+                                   (eapol[SLSI_EAPOL_KEY_INFO_LOWER_BYTE_POS] &
+                                    SLSI_EAPOL_KEY_INFO_KEY_TYPE_BIT_IN_LOWER_BYTE) &&
+                                   (eapol[SLSI_EAPOL_KEY_INFO_HIGHER_BYTE_POS] &
+                                    SLSI_EAPOL_KEY_INFO_MIC_BIT_IN_HIGHER_BYTE) &&
+                                   (eapol[SLSI_EAPOL_KEY_DATA_LENGTH_HIGHER_BYTE_POS] == 0) &&
+                                   (eapol[SLSI_EAPOL_KEY_DATA_LENGTH_LOWER_BYTE_POS] == 0)) {
+                                       SLSI_INFO(sdev, "Received 4way-H/S, M4\n");
+                               } else if (!(eapol[SLSI_EAPOL_KEY_INFO_HIGHER_BYTE_POS] &
+                                            SLSI_EAPOL_KEY_INFO_MIC_BIT_IN_HIGHER_BYTE)) {
+                                       SLSI_INFO(sdev, "Received 4way-H/S, M1\n");
+                               } else if (eapol[SLSI_EAPOL_KEY_INFO_HIGHER_BYTE_POS] &
+                                          SLSI_EAPOL_KEY_INFO_SECURE_BIT_IN_HIGHER_BYTE) {
+                                       SLSI_INFO(sdev, "Received 4way-H/S, M3\n");
+                               } else {
+                                       SLSI_INFO(sdev, "Received 4way-H/S, M2\n");
+                               }
+                       }
+               } else if (protocol == ETH_P_IP) {
+                       if (dhcp_message_type == SLSI_DHCP_MESSAGE_TYPE_DISCOVER)
+                               SLSI_INFO(sdev, "Received DHCP [DISCOVER]\n");
+                       else if (dhcp_message_type == SLSI_DHCP_MESSAGE_TYPE_OFFER)
+                               SLSI_INFO(sdev, "Received DHCP [OFFER]\n");
+                       else if (dhcp_message_type == SLSI_DHCP_MESSAGE_TYPE_REQUEST)
+                               SLSI_INFO(sdev, "Received DHCP [REQUEST]\n");
+                       else if (dhcp_message_type == SLSI_DHCP_MESSAGE_TYPE_DECLINE)
+                               SLSI_INFO(sdev, "Received DHCP [DECLINE]\n");
+                       else if (dhcp_message_type == SLSI_DHCP_MESSAGE_TYPE_ACK)
+                               SLSI_INFO(sdev, "Received DHCP [ACK]\n");
+                       else if (dhcp_message_type == SLSI_DHCP_MESSAGE_TYPE_NAK)
+                               SLSI_INFO(sdev, "Received DHCP [NAK]\n");
+                       else if (dhcp_message_type == SLSI_DHCP_MESSAGE_TYPE_RELEASE)
+                               SLSI_INFO(sdev, "Received DHCP [RELEASE]\n");
+                       else if (dhcp_message_type == SLSI_DHCP_MESSAGE_TYPE_INFORM)
+                               SLSI_INFO(sdev, "Received DHCP [INFORM]\n");
+                       else if (dhcp_message_type == SLSI_DHCP_MESSAGE_TYPE_FORCERENEW)
+                               SLSI_INFO(sdev, "Received DHCP [FORCERENEW]\n");
+                       else
+                               SLSI_INFO(sdev, "Received DHCP [INVALID]\n");
+               }
                slsi_dbg_untrack_skb(skb);
                SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
                SLSI_DBG2(sdev, SLSI_MLME, "pass %u bytes up (proto:%d)\n", skb->len, ntohs(skb->protocol));
index 2f7c49b275afd4bf14c9eeda7d41803d3764f03a..502d81de100cdf0f33cec74947fdcb2e23226429 100755 (executable)
@@ -118,28 +118,36 @@ static int slsi_rx_amsdu_deaggregate(struct net_device *dev, struct sk_buff *skb
 
                /* For the last subframe skb length and subframe length will be same */
                if (skb->len == subframe_len) {
-                       /* Use the original skb for the last subframe */
                        subframe = slsi_skb_copy(skb, GFP_ATOMIC);
 
+                       if (!subframe) {
+                               SLSI_NET_ERR(dev, "failed to alloc the SKB for A-MSDU subframe\n");
+                               __skb_queue_purge(msdu_list);
+                               slsi_kfree_skb(skb);
+                               return -ENOMEM;
+                       }
+
                        /* There is no padding for last subframe */
                        padding = 0;
                        last_sub_frame = true;
                } else {
-                       /* Clone the skb for the subframe */
+                       /* Copy the skb for the subframe */
                        subframe = slsi_skb_copy(skb, GFP_ATOMIC);
+
                        if (!subframe) {
+                               SLSI_NET_ERR(dev, "failed to alloc the SKB for A-MSDU subframe\n");
+                               __skb_queue_purge(msdu_list);
                                slsi_kfree_skb(skb);
-                               SLSI_NET_ERR(dev, "Failed to clone the SKB for A-MSDU subframe\n");
                                return -ENOMEM;
                        }
 
                        padding = (4 - (subframe_len % 4)) & 0x3;
                }
 
-               /* Remove the other subframes by adjusting the tail pointer of the cloned skb */
+               /* Remove the other subframes by adjusting the tail pointer of the copied skb */
                skb_trim(subframe, subframe_len);
 
-               /* Overwrite LLC+SNAP header with src & dest addr */
+               /* Overwrite LLC+SNAP header with src and dest addr */
                SLSI_ETHER_COPY(&subframe->data[14], &subframe->data[6]);
                SLSI_ETHER_COPY(&subframe->data[8], &subframe->data[0]);
 
index 30e3c2bc62fb2b8e0c0dc21febc5c21d6507d28d..c35ae12b92741ea61c2ae6bf3f25232b775c49b6 100755 (executable)
@@ -33,7 +33,7 @@ static int slsi_tx_eapol(struct slsi_dev *sdev, struct net_device *dev, struct s
 {
        struct netdev_vif       *ndev_vif = netdev_priv(dev);
        struct slsi_peer        *peer;
-       u8                      *eapol;
+       u8                      *eapol = NULL;
        u16                     msg_type = 0;
        u16                     proto = ntohs(skb->protocol);
        int                     ret = 0;
@@ -57,8 +57,9 @@ static int slsi_tx_eapol(struct slsi_dev *sdev, struct net_device *dev, struct s
                 *   - Key type bit set in key info (pairwise=1, Group=0)
                 *   - Key Data Length would be 0
                 */
-               eapol = skb->data + sizeof(struct ethhdr);
-               if (eapol[SLSI_EAPOL_IEEE8021X_TYPE_POS] == SLSI_IEEE8021X_TYPE_EAPOL_KEY) {
+               if ((skb->len + sizeof(struct ethhdr)) >= 99)
+                       eapol = skb->data + sizeof(struct ethhdr);
+               if (eapol && eapol[SLSI_EAPOL_IEEE8021X_TYPE_POS] == SLSI_IEEE8021X_TYPE_EAPOL_KEY) {
                        msg_type = FAPI_MESSAGETYPE_EAPOL_KEY_M123;
 
                        if ((eapol[SLSI_EAPOL_TYPE_POS] == SLSI_EAPOL_TYPE_RSN_KEY || eapol[SLSI_EAPOL_TYPE_POS] == SLSI_EAPOL_TYPE_WPA_KEY) &&
@@ -66,9 +67,18 @@ static int slsi_tx_eapol(struct slsi_dev *sdev, struct net_device *dev, struct s
                            (eapol[SLSI_EAPOL_KEY_INFO_HIGHER_BYTE_POS] & SLSI_EAPOL_KEY_INFO_MIC_BIT_IN_HIGHER_BYTE) &&
                            (eapol[SLSI_EAPOL_KEY_DATA_LENGTH_HIGHER_BYTE_POS] == 0) &&
                            (eapol[SLSI_EAPOL_KEY_DATA_LENGTH_LOWER_BYTE_POS] == 0)) {
-                               SLSI_NET_DBG1(dev, SLSI_MLME, "message M4\n");
+                               SLSI_INFO(sdev, "Send 4way-H/S, M4\n");
                                msg_type = FAPI_MESSAGETYPE_EAPOL_KEY_M4;
                                dwell_time = 0;
+                       } else if (msg_type == FAPI_MESSAGETYPE_EAPOL_KEY_M123) {
+                               if (!(eapol[SLSI_EAPOL_KEY_INFO_HIGHER_BYTE_POS] &
+                                     SLSI_EAPOL_KEY_INFO_MIC_BIT_IN_HIGHER_BYTE))
+                                       SLSI_INFO(sdev, "Send 4way-H/S, M1\n");
+                               else if (eapol[SLSI_EAPOL_KEY_INFO_HIGHER_BYTE_POS] &
+                                        SLSI_EAPOL_KEY_INFO_SECURE_BIT_IN_HIGHER_BYTE)
+                                       SLSI_INFO(sdev, "Send 4way-H/S, M3\n");
+                               else
+                                       SLSI_INFO(sdev, "Send 4way-H/S, M2\n");
                        }
                } else {
                        msg_type = FAPI_MESSAGETYPE_EAP_MESSAGE;
@@ -121,6 +131,7 @@ int slsi_tx_data(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *
        u32 dwell_time = 0;
        u8 *frame;
        u32 arp_opcode;
+       u32 dhcp_message_type = SLSI_DHCP_MESSAGE_TYPE_INVALID;
 
        if (slsi_is_test_mode_enabled()) {
                /* This signals is in XML file because parts of the Firmware need the symbols defined by them
@@ -166,10 +177,30 @@ int slsi_tx_data(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *
                        }
                        return slsi_mlme_send_frame_data(sdev, dev, skb, FAPI_MESSAGETYPE_ARP, 0, dwell_time, 0);
                case ETH_P_IP:
-                       if (slsi_is_dhcp_packet(skb->data) != SLSI_TX_IS_NOT_DHCP) {
-                               SLSI_NET_DBG2(dev, SLSI_MLME, "transmit DHCP packet from SLSI_NETIF_Q_PRIORITY\n");
+                       if (skb->len >= 285 && slsi_is_dhcp_packet(skb->data) != SLSI_TX_IS_NOT_DHCP) {
                                if (skb->data[42] == 1)  /*opcode 1 refers to DHCP discover/request*/
                                        dwell_time = sdev->fw_dwell_time;
+                               dhcp_message_type = skb->data[284];
+                               if (dhcp_message_type == SLSI_DHCP_MESSAGE_TYPE_DISCOVER)
+                                       SLSI_INFO(sdev, "Send DHCP [DISCOVER]\n");
+                               else if (dhcp_message_type == SLSI_DHCP_MESSAGE_TYPE_OFFER)
+                                       SLSI_INFO(sdev, "Send DHCP [OFFER]\n");
+                               else if (dhcp_message_type == SLSI_DHCP_MESSAGE_TYPE_REQUEST)
+                                       SLSI_INFO(sdev, "Send DHCP [REQUEST]\n");
+                               else if (dhcp_message_type == SLSI_DHCP_MESSAGE_TYPE_DECLINE)
+                                       SLSI_INFO(sdev, "Send DHCP [DECLINE]\n");
+                               else if (dhcp_message_type == SLSI_DHCP_MESSAGE_TYPE_ACK)
+                                       SLSI_INFO(sdev, "Send DHCP [ACK]\n");
+                               else if (dhcp_message_type == SLSI_DHCP_MESSAGE_TYPE_NAK)
+                                       SLSI_INFO(sdev, "Send DHCP [NAK]\n");
+                               else if (dhcp_message_type == SLSI_DHCP_MESSAGE_TYPE_RELEASE)
+                                       SLSI_INFO(sdev, "Send DHCP [RELEASE]\n");
+                               else if (dhcp_message_type == SLSI_DHCP_MESSAGE_TYPE_INFORM)
+                                       SLSI_INFO(sdev, "Send DHCP [INFORM]\n");
+                               else if (dhcp_message_type == SLSI_DHCP_MESSAGE_TYPE_FORCERENEW)
+                                       SLSI_INFO(sdev, "Send DHCP [FORCERENEW]\n");
+                               else
+                                       SLSI_INFO(sdev, "Send DHCP [INVALID]\n");
                                return slsi_mlme_send_frame_data(sdev, dev, skb, FAPI_MESSAGETYPE_DHCP, 0, dwell_time,
                                                                 0);
                        }
index 0bbb8691d1e25ff258d2bd7225dceb75814ba7ab..33cb9bdbc8ae04dbc93fd134cdd07b4c952799b9 100644 (file)
@@ -1,6 +1,6 @@
 /****************************************************************************
  *
- * Copyright (c) 2014 - 2018 Samsung Electronics Co., Ltd. All rights reserved
+ * Copyright (c) 2014 - 2019 Samsung Electronics Co., Ltd. All rights reserved
  *
  ****************************************************************************/
 
@@ -8,7 +8,7 @@
 #define __SCSC_LOG_COLLECTOR_H__
 
 /* High nibble is Major, Low nibble is Minor */
-#define SCSC_LOG_HEADER_VERSION_MAJOR  0x01
+#define SCSC_LOG_HEADER_VERSION_MAJOR  0x02
 #define SCSC_LOG_HEADER_VERSION_MINOR  0x00
 /* Magic string. 4 bytes "SCSC"*/
 /* Header version. 1 byte */
@@ -18,7 +18,7 @@
 /* Reserved. 1 byte */
 /* Reason Code . 2 bytes */
 #define SCSC_LOG_HEADER_SIZE           (12)
-#define SCSC_LOG_FW_VERSION_SIZE       (64)
+#define SCSC_LOG_FW_VERSION_SIZE       (128)
 #define SCSC_LOG_HOST_VERSION_SIZE     (64)
 #define SCSC_LOG_FAPI_VERSION_SIZE     (64)
 /* Reserved 2 . 4 byte */
@@ -85,6 +85,7 @@ enum scsc_log_chunk_type {
 #define SCSC_LOG_HOST_WLAN_REASON_DISCONNECT_IND       0x0001
 #define SCSC_LOG_HOST_WLAN_REASON_DISCONNECTED_IND     0x0002
 #define SCSC_LOG_HOST_WLAN_REASON_DRIVERDEBUGDUMP      0x0003
+#define SCSC_LOG_HOST_WLAN_REASON_CONNECT_ERR          0x0004
 /* Reason codes for SCSC_LOG_HOST_BT */
 /* Reason codes for SCSC_LOG_HOST_COMMON */
 #define SCSC_LOG_HOST_COMMON_REASON_START              0x0000
index ebea1c3a87e25a085b55ac54e732a9d647f0c089..39eec60d897ce7e6e8e09f7f586a5c682ca62a0c 100644 (file)
@@ -1,6 +1,6 @@
 /****************************************************************************
  *
- * Copyright (c) 2014 - 2018 Samsung Electronics Co., Ltd. All rights reserved
+ * Copyright (c) 2014 - 2019 Samsung Electronics Co., Ltd. All rights reserved
  *
  *****************************************************************************/
 
@@ -10,8 +10,8 @@
 #define SCSC_RELEASE_SOLUTION "mx250"
 
 #define SCSC_RELEASE_PRODUCT 6
-#define SCSC_RELEASE_ITERATION 57
-#define SCSC_RELEASE_CANDIDATE 0
+#define SCSC_RELEASE_ITERATION 60
+#define SCSC_RELEASE_CANDIDATE 1
 
 #define SCSC_RELEASE_POINT 0