--- /dev/null
+/*
+ *
+ * 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;
+}
/****************************************************************************
*
- * Copyright (c) 2014 - 2018 Samsung Electronics Co., Ltd. All rights reserved
+ * Copyright (c) 2014 - 2019 Samsung Electronics Co., Ltd. All rights reserved
*
****************************************************************************/
{
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:
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:
*
****************************************************************************/
#include <linux/mutex.h>
+#include <linux/wakelock.h>
+
#include "scsc_wlbtd.h"
#define MAX_TIMEOUT 30000 /* in milisecounds */
static char *build_type;
static DEFINE_MUTEX(sable_lock);
+static struct wake_lock wlbtd_wakelock;
+
/**
* This callback runs whenever the socket receives messages.
*/
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);
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);
}
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
* 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;
}
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);
* 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");
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;
}
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");
* 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");
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;
}
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) {
return -1;
}
- init_completion(&event_done);
-
return r;
}
}
kfree(build_type);
build_type = NULL;
+ wake_lock_destroy(&wlbtd_wakelock);
+
return ret;
}
#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;
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");
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;
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;
}
}
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);
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);
bt_service.h4_write_offset = 0;
}
+ slsi_bt_notify_remove();
put_device(bt_service.dev);
common_service.maxwell_core = NULL;
/* 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;
}
}
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)
/* 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;
}
---help---
This option tells if there is support for single
antenna or dual antenna.
+
config SCSC_WLAN_ACS_ENABLE
bool "ACS Support"
default y
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.
/*****************************************************************************
*
- * Copyright (c) 2012 - 2018 Samsung Electronics Co., Ltd. All rights reserved
+ * Copyright (c) 2012 - 2019 Samsung Electronics Co., Ltd. All rights reserved
*
****************************************************************************/
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);
}
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,
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);
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;
}
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;
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;
} 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;
}
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();
/* 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;
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;
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 ||
}
#endif
- if ((indoor_channel == 1)
+ if (indoor_channel == 1
#ifdef CONFIG_SCSC_WLAN_WIFI_SHARING
|| (wifi_sharing_channel_switched == 1)
#endif
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
}
} 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);
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);
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);
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;
}
#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";
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;
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
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]);
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;
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;
#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;
return SLSI_80211_MODE_11B;
}
+/* Names of full mode HCF files */
+extern char *slsi_mib_file;
+extern char *slsi_mib_file2;
+
#endif
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,
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;
{
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)
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);
}
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,
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 */
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)
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;
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)
{
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 */
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;
* 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");
}
}
-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:
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;
}
}
#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,
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);
#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 */
/*****************************************************************************
*
- * Copyright (c) 2012 - 2018 Samsung Electronics Co., Ltd. All rights reserved
+ * Copyright (c) 2012 - 2019 Samsung Electronics Co., Ltd. All rights reserved
*
****************************************************************************/
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);
#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 { \
}
#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]);
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]);
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;
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;
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);
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();
}
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);
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__*/
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;
}
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");
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);
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;
}
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;
}
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) {
#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;
}
/*****************************************************************************
*
- * 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>
#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);
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");
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");
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) {
#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),
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),
#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) {
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");
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) */
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),
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;
}
} 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);
}
}
#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));
/* 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]);
{
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;
* - 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) &&
(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;
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
}
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);
}
/****************************************************************************
*
- * Copyright (c) 2014 - 2018 Samsung Electronics Co., Ltd. All rights reserved
+ * Copyright (c) 2014 - 2019 Samsung Electronics Co., Ltd. All rights reserved
*
****************************************************************************/
#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 */
/* 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 */
#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
/****************************************************************************
*
- * Copyright (c) 2014 - 2018 Samsung Electronics Co., Ltd. All rights reserved
+ * Copyright (c) 2014 - 2019 Samsung Electronics Co., Ltd. All rights reserved
*
*****************************************************************************/
#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