|
@@ -134,6 +134,42 @@ mwifiex_reset_connect_state(struct mwifiex_private *priv, u16 reason_code)
|
|
|
netif_carrier_off(priv->netdev);
|
|
|
}
|
|
|
|
|
|
+static int mwifiex_parse_tdls_event(struct mwifiex_private *priv,
|
|
|
+ struct sk_buff *event_skb)
|
|
|
+{
|
|
|
+ struct mwifiex_adapter *adapter = priv->adapter;
|
|
|
+ struct mwifiex_sta_node *sta_ptr;
|
|
|
+ struct mwifiex_tdls_generic_event *tdls_evt =
|
|
|
+ (void *)event_skb->data + sizeof(adapter->event_cause);
|
|
|
+
|
|
|
+ /* reserved 2 bytes are not mandatory in tdls event */
|
|
|
+ if (event_skb->len < (sizeof(struct mwifiex_tdls_generic_event) -
|
|
|
+ sizeof(u16) - sizeof(adapter->event_cause))) {
|
|
|
+ dev_err(adapter->dev, "Invalid event length!\n");
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ sta_ptr = mwifiex_get_sta_entry(priv, tdls_evt->peer_mac);
|
|
|
+ if (!sta_ptr) {
|
|
|
+ dev_err(adapter->dev, "cannot get sta entry!\n");
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ switch (le16_to_cpu(tdls_evt->type)) {
|
|
|
+ case TDLS_EVENT_LINK_TEAR_DOWN:
|
|
|
+ cfg80211_tdls_oper_request(priv->netdev,
|
|
|
+ tdls_evt->peer_mac,
|
|
|
+ NL80211_TDLS_TEARDOWN,
|
|
|
+ le16_to_cpu(tdls_evt->u.reason_code),
|
|
|
+ GFP_KERNEL);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* This function handles events generated by firmware.
|
|
|
*
|
|
@@ -459,6 +495,10 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
|
|
|
false);
|
|
|
break;
|
|
|
|
|
|
+ case EVENT_TDLS_GENERIC_EVENT:
|
|
|
+ ret = mwifiex_parse_tdls_event(priv, adapter->event_skb);
|
|
|
+ break;
|
|
|
+
|
|
|
default:
|
|
|
dev_dbg(adapter->dev, "event: unknown event id: %#x\n",
|
|
|
eventcause);
|