示例#1
0
static int mwifiex_parse_tdls_event(struct mwifiex_private *priv,
                                    struct sk_buff *event_skb)
{
    int ret = 0;
    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);
        ret = mwifiex_tdls_oper(priv, tdls_evt->peer_mac,
                                MWIFIEX_TDLS_DISABLE_LINK);
        queue_work(adapter->workqueue, &adapter->main_work);
        break;
    default:
        break;
    }

    return ret;
}
示例#2
0
static int mwifiex_parse_tdls_event(struct mwifiex_private *priv,
				    struct sk_buff *event_skb)
{
	int ret = 0;
	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);
	u8 *mac = tdls_evt->peer_mac;

	/* 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))) {
		mwifiex_dbg(adapter, ERROR, "Invalid event length!\n");
		return -1;
	}

	sta_ptr = mwifiex_get_sta_entry(priv, tdls_evt->peer_mac);
	if (!sta_ptr) {
		mwifiex_dbg(adapter, ERROR, "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;
	case TDLS_EVENT_CHAN_SWITCH_RESULT:
		mwifiex_dbg(adapter, EVENT, "tdls channel switch result :\n");
		mwifiex_dbg(adapter, EVENT,
			    "status=0x%x, reason=0x%x cur_chan=%d\n",
			    tdls_evt->u.switch_result.status,
			    tdls_evt->u.switch_result.reason,
			    tdls_evt->u.switch_result.cur_chan);

		/* tdls channel switch failed */
		if (tdls_evt->u.switch_result.status != 0) {
			switch (tdls_evt->u.switch_result.cur_chan) {
			case TDLS_BASE_CHANNEL:
				sta_ptr->tdls_status = TDLS_IN_BASE_CHAN;
				break;
			case TDLS_OFF_CHANNEL:
				sta_ptr->tdls_status = TDLS_IN_OFF_CHAN;
				break;
			default:
				break;
			}
			return ret;
		}

		/* tdls channel switch success */
		switch (tdls_evt->u.switch_result.cur_chan) {
		case TDLS_BASE_CHANNEL:
			if (sta_ptr->tdls_status == TDLS_IN_BASE_CHAN)
				break;
			mwifiex_update_ralist_tx_pause_in_tdls_cs(priv, mac,
								  false);
			sta_ptr->tdls_status = TDLS_IN_BASE_CHAN;
			break;
		case TDLS_OFF_CHANNEL:
			if (sta_ptr->tdls_status == TDLS_IN_OFF_CHAN)
				break;
			mwifiex_update_ralist_tx_pause_in_tdls_cs(priv, mac,
								  true);
			sta_ptr->tdls_status = TDLS_IN_OFF_CHAN;
			break;
		default:
			break;
		}

		break;
	case TDLS_EVENT_START_CHAN_SWITCH:
		mwifiex_dbg(adapter, EVENT, "tdls start channel switch...\n");
		sta_ptr->tdls_status = TDLS_CHAN_SWITCHING;
		break;
	case TDLS_EVENT_CHAN_SWITCH_STOPPED:
		mwifiex_dbg(adapter, EVENT,
			    "tdls chan switch stopped, reason=%d\n",
			    tdls_evt->u.cs_stop_reason);
		break;
	default:
		break;
	}

	return ret;
}