Exemple #1
0
static void wil_connect_worker(struct work_struct *work)
{
	int rc;
	struct wil6210_priv *wil = container_of(work, struct wil6210_priv,
						connect_worker);
	int cid = wil->pending_connect_cid;
	int tid = wil->tid_to_use & 0xf;
	int ringid = wil_find_free_vring(wil);

	if (cid < 0) {
		wil_err(wil, "No connection pending\n");
		return;
	}

	wil_dbg_wmi(wil, "Configure for connection CID %d\n", cid);

	rc = wil_vring_init_tx(wil, ringid, WIL6210_TX_RING_SIZE, cid, tid);
	wil->pending_connect_cid = -1;
	if (rc == 0) {
		wil->sta[cid].status = wil_sta_connected;
		wil_link_on(wil);
	} else {
		wil->sta[cid].status = wil_sta_unused;
	}
}
static void wil_connect_worker(struct work_struct *work)
{
	int rc;
	struct wil6210_priv *wil = container_of(work, struct wil6210_priv,
						connect_worker);
	int cid = wil->pending_connect_cid;

	if (cid < 0) {
		wil_err(wil, "No connection pending\n");
		return;
	}

	wil_dbg_wmi(wil, "Configure for connection CID %d\n", cid);

	rc = wil_vring_init_tx(wil, 0, WIL6210_TX_RING_SIZE, cid, 0);
	wil->pending_connect_cid = -1;
	if (rc == 0)
		wil_link_on(wil);
}
Exemple #3
0
static int wil_cid_fill_sinfo(struct wil6210_priv *wil, int cid,
                              struct station_info *sinfo)
{
    struct wmi_notify_req_cmd cmd = {
        .cid = cid,
        .interval_usec = 0,
    };
    struct {
        struct wil6210_mbox_hdr_wmi wmi;
        struct wmi_notify_req_done_event evt;
    } __packed reply;
    struct wil_net_stats *stats = &wil->sta[cid].stats;
    int rc;

    rc = wmi_call(wil, WMI_NOTIFY_REQ_CMDID, &cmd, sizeof(cmd),
                  WMI_NOTIFY_REQ_DONE_EVENTID, &reply, sizeof(reply), 20);
    if (rc)
        return rc;

    wil_dbg_wmi(wil, "Link status for CID %d: {\n"
                "  MCS %d TSF 0x%016llx\n"
                "  BF status 0x%08x SNR 0x%08x SQI %d%%\n"
                "  Tx Tpt %d goodput %d Rx goodput %d\n"
                "  Sectors(rx:tx) my %d:%d peer %d:%d\n""}\n",
                cid, le16_to_cpu(reply.evt.bf_mcs),
                le64_to_cpu(reply.evt.tsf), reply.evt.status,
                le32_to_cpu(reply.evt.snr_val),
                reply.evt.sqi,
                le32_to_cpu(reply.evt.tx_tpt),
                le32_to_cpu(reply.evt.tx_goodput),
                le32_to_cpu(reply.evt.rx_goodput),
                le16_to_cpu(reply.evt.my_rx_sector),
                le16_to_cpu(reply.evt.my_tx_sector),
                le16_to_cpu(reply.evt.other_rx_sector),
                le16_to_cpu(reply.evt.other_tx_sector));

    sinfo->generation = wil->sinfo_gen;

    sinfo->filled = STATION_INFO_RX_BYTES |
                    STATION_INFO_TX_BYTES |
                    STATION_INFO_RX_PACKETS |
                    STATION_INFO_TX_PACKETS |
                    STATION_INFO_RX_BITRATE |
                    STATION_INFO_TX_BITRATE |
                    STATION_INFO_RX_DROP_MISC |
                    STATION_INFO_TX_FAILED;

    sinfo->txrate.flags = RATE_INFO_FLAGS_MCS | RATE_INFO_FLAGS_60G;
    sinfo->txrate.mcs = le16_to_cpu(reply.evt.bf_mcs);
    sinfo->rxrate.flags = RATE_INFO_FLAGS_MCS | RATE_INFO_FLAGS_60G;
    sinfo->rxrate.mcs = stats->last_mcs_rx;
    sinfo->rx_bytes = stats->rx_bytes;
    sinfo->rx_packets = stats->rx_packets;
    sinfo->rx_dropped_misc = stats->rx_dropped;
    sinfo->tx_bytes = stats->tx_bytes;
    sinfo->tx_packets = stats->tx_packets;
    sinfo->tx_failed = stats->tx_errors;

    if (test_bit(wil_status_fwconnected, &wil->status)) {
        sinfo->filled |= STATION_INFO_SIGNAL;
        sinfo->signal = reply.evt.sqi;
    }

    return rc;
}

static int wil_cfg80211_get_station(struct wiphy *wiphy,
                                    struct net_device *ndev,
                                    u8 *mac, struct station_info *sinfo)
{
    struct wil6210_priv *wil = wiphy_to_wil(wiphy);
    int rc;

    int cid = wil_find_cid(wil, mac);

    wil_dbg_misc(wil, "%s(%pM) CID %d\n", __func__, mac, cid);
    if (cid < 0)
        return cid;

    rc = wil_cid_fill_sinfo(wil, cid, sinfo);

    return rc;
}

/*
 * Find @idx-th active STA for station dump.
 */
static int wil_find_cid_by_idx(struct wil6210_priv *wil, int idx)
{
    int i;

    for (i = 0; i < ARRAY_SIZE(wil->sta); i++) {
        if (wil->sta[i].status == wil_sta_unused)
            continue;
        if (idx == 0)
            return i;
        idx--;
    }

    return -ENOENT;
}