https://github.com/torvalds/linux
Revision 203ec2fed17ade9582277570eb234be52085f8c5 authored by Linus Torvalds on 20 May 2018, 02:56:15 UTC, committed by Linus Torvalds on 20 May 2018, 02:56:15 UTC
Pull ARM SoC fixes from Olof Johansson:
 "A handful of fixes. I've been queuing them up a bit too long so the
  list is longer than it otherwise would have been spread out across a
  few -rcs.

  In general, it's a scattering of fixes across several platforms,
  nothing truly serious enough to point out.

  There's a slightly larger batch of them for the Davinci platforms due
  to work to bring them back to life after some time, so there's a
  handful of regressions, some of them going back very far, others more
  recent.

  There's also a few patches fixing DT on Renesas platforms since they
  changed some bindings without remaining backwards compatible,
  splitting up describing LVDS as a proper bridge instead of having it
  as part of the display unit.

  We could push for them to be backwards compatible with old device
  trees, but it's likely to regress eventually if nobody's actually
  using said compatibility"

* tag 'armsoc-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (36 commits)
  ARM: davinci: board-dm646x-evm: set VPIF capture card name
  ARM: davinci: board-dm646x-evm: pass correct I2C adapter id for VPIF
  ARM: davinci: dm646x: fix timer interrupt generation
  ARM: keystone: fix platform_domain_notifier array overrun
  arm64: dts: exynos: Fix interrupt type for I2S1 device on Exynos5433
  ARM: dts: imx51-zii-rdu1: fix touchscreen bindings
  firmware: arm_scmi: Use after free in scmi_create_protocol_device()
  ARM: dts: cygnus: fix irq type for arm global timer
  Revert "ARM: dts: logicpd-som-lv: Fix pinmux controller references"
  tee: check shm references are consistent in offset/size
  tee: shm: fix use-after-free via temporarily dropped reference
  ARM: dts: imx7s: Pass the 'fsl,sec-era' property
  ARM: dts: tegra20: Revert "Fix ULPI regression on Tegra20"
  ARM: dts: correct missing "compatible" entry for ti81xx SoCs
  ARM: OMAP1: ams-delta: fix deferred_fiq handler
  arm64: tegra: Make BCM89610 PHY interrupt as active low
  ARM: davinci: fix GPIO lookup for I2C
  ARM: dts: logicpd-som-lv: Fix pinmux controller references
  ARM: dts: logicpd-som-lv: Fix Audio Mute
  ARM: dts: logicpd-som-lv: Fix WL127x Startup Issues
  ...
2 parent s 0b449a4 + 709f490
Raw File
Tip revision: 203ec2fed17ade9582277570eb234be52085f8c5 authored by Linus Torvalds on 20 May 2018, 02:56:15 UTC
Merge tag 'armsoc-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Tip revision: 203ec2f
ethtool.c
/*
 * mac80211 ethtool hooks for cfg80211
 *
 * Copied from cfg.c - originally
 * Copyright 2006-2010	Johannes Berg <johannes@sipsolutions.net>
 * Copyright 2014	Intel Corporation (Author: Johannes Berg)
 *
 * This file is GPLv2 as found in COPYING.
 */
#include <linux/types.h>
#include <net/cfg80211.h>
#include "ieee80211_i.h"
#include "sta_info.h"
#include "driver-ops.h"

static int ieee80211_set_ringparam(struct net_device *dev,
				   struct ethtool_ringparam *rp)
{
	struct ieee80211_local *local = wiphy_priv(dev->ieee80211_ptr->wiphy);

	if (rp->rx_mini_pending != 0 || rp->rx_jumbo_pending != 0)
		return -EINVAL;

	return drv_set_ringparam(local, rp->tx_pending, rp->rx_pending);
}

static void ieee80211_get_ringparam(struct net_device *dev,
				    struct ethtool_ringparam *rp)
{
	struct ieee80211_local *local = wiphy_priv(dev->ieee80211_ptr->wiphy);

	memset(rp, 0, sizeof(*rp));

	drv_get_ringparam(local, &rp->tx_pending, &rp->tx_max_pending,
			  &rp->rx_pending, &rp->rx_max_pending);
}

static const char ieee80211_gstrings_sta_stats[][ETH_GSTRING_LEN] = {
	"rx_packets", "rx_bytes",
	"rx_duplicates", "rx_fragments", "rx_dropped",
	"tx_packets", "tx_bytes",
	"tx_filtered", "tx_retry_failed", "tx_retries",
	"sta_state", "txrate", "rxrate", "signal",
	"channel", "noise", "ch_time", "ch_time_busy",
	"ch_time_ext_busy", "ch_time_rx", "ch_time_tx"
};
#define STA_STATS_LEN	ARRAY_SIZE(ieee80211_gstrings_sta_stats)

static int ieee80211_get_sset_count(struct net_device *dev, int sset)
{
	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
	int rv = 0;

	if (sset == ETH_SS_STATS)
		rv += STA_STATS_LEN;

	rv += drv_get_et_sset_count(sdata, sset);

	if (rv == 0)
		return -EOPNOTSUPP;
	return rv;
}

static void ieee80211_get_stats(struct net_device *dev,
				struct ethtool_stats *stats,
				u64 *data)
{
	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
	struct ieee80211_chanctx_conf *chanctx_conf;
	struct ieee80211_channel *channel;
	struct sta_info *sta;
	struct ieee80211_local *local = sdata->local;
	struct station_info sinfo;
	struct survey_info survey;
	int i, q;
#define STA_STATS_SURVEY_LEN 7

	memset(data, 0, sizeof(u64) * STA_STATS_LEN);

#define ADD_STA_STATS(sta)					\
	do {							\
		data[i++] += sta->rx_stats.packets;		\
		data[i++] += sta->rx_stats.bytes;		\
		data[i++] += sta->rx_stats.num_duplicates;	\
		data[i++] += sta->rx_stats.fragments;		\
		data[i++] += sta->rx_stats.dropped;		\
								\
		data[i++] += sinfo.tx_packets;			\
		data[i++] += sinfo.tx_bytes;			\
		data[i++] += sta->status_stats.filtered;	\
		data[i++] += sta->status_stats.retry_failed;	\
		data[i++] += sta->status_stats.retry_count;	\
	} while (0)

	/* For Managed stations, find the single station based on BSSID
	 * and use that.  For interface types, iterate through all available
	 * stations and add stats for any station that is assigned to this
	 * network device.
	 */

	mutex_lock(&local->sta_mtx);

	if (sdata->vif.type == NL80211_IFTYPE_STATION) {
		sta = sta_info_get_bss(sdata, sdata->u.mgd.bssid);

		if (!(sta && !WARN_ON(sta->sdata->dev != dev)))
			goto do_survey;

		sinfo.filled = 0;
		sta_set_sinfo(sta, &sinfo);

		i = 0;
		ADD_STA_STATS(sta);

		data[i++] = sta->sta_state;


		if (sinfo.filled & BIT(NL80211_STA_INFO_TX_BITRATE))
			data[i] = 100000 *
				cfg80211_calculate_bitrate(&sinfo.txrate);
		i++;
		if (sinfo.filled & BIT(NL80211_STA_INFO_RX_BITRATE))
			data[i] = 100000 *
				cfg80211_calculate_bitrate(&sinfo.rxrate);
		i++;

		if (sinfo.filled & BIT(NL80211_STA_INFO_SIGNAL_AVG))
			data[i] = (u8)sinfo.signal_avg;
		i++;
	} else {
		list_for_each_entry(sta, &local->sta_list, list) {
			/* Make sure this station belongs to the proper dev */
			if (sta->sdata->dev != dev)
				continue;

			sinfo.filled = 0;
			sta_set_sinfo(sta, &sinfo);
			i = 0;
			ADD_STA_STATS(sta);
		}
	}

do_survey:
	i = STA_STATS_LEN - STA_STATS_SURVEY_LEN;
	/* Get survey stats for current channel */
	survey.filled = 0;

	rcu_read_lock();
	chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
	if (chanctx_conf)
		channel = chanctx_conf->def.chan;
	else
		channel = NULL;
	rcu_read_unlock();

	if (channel) {
		q = 0;
		do {
			survey.filled = 0;
			if (drv_get_survey(local, q, &survey) != 0) {
				survey.filled = 0;
				break;
			}
			q++;
		} while (channel != survey.channel);
	}

	if (survey.filled)
		data[i++] = survey.channel->center_freq;
	else
		data[i++] = 0;
	if (survey.filled & SURVEY_INFO_NOISE_DBM)
		data[i++] = (u8)survey.noise;
	else
		data[i++] = -1LL;
	if (survey.filled & SURVEY_INFO_TIME)
		data[i++] = survey.time;
	else
		data[i++] = -1LL;
	if (survey.filled & SURVEY_INFO_TIME_BUSY)
		data[i++] = survey.time_busy;
	else
		data[i++] = -1LL;
	if (survey.filled & SURVEY_INFO_TIME_EXT_BUSY)
		data[i++] = survey.time_ext_busy;
	else
		data[i++] = -1LL;
	if (survey.filled & SURVEY_INFO_TIME_RX)
		data[i++] = survey.time_rx;
	else
		data[i++] = -1LL;
	if (survey.filled & SURVEY_INFO_TIME_TX)
		data[i++] = survey.time_tx;
	else
		data[i++] = -1LL;

	mutex_unlock(&local->sta_mtx);

	if (WARN_ON(i != STA_STATS_LEN))
		return;

	drv_get_et_stats(sdata, stats, &(data[STA_STATS_LEN]));
}

static void ieee80211_get_strings(struct net_device *dev, u32 sset, u8 *data)
{
	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
	int sz_sta_stats = 0;

	if (sset == ETH_SS_STATS) {
		sz_sta_stats = sizeof(ieee80211_gstrings_sta_stats);
		memcpy(data, ieee80211_gstrings_sta_stats, sz_sta_stats);
	}
	drv_get_et_strings(sdata, sset, &(data[sz_sta_stats]));
}

static int ieee80211_get_regs_len(struct net_device *dev)
{
	return 0;
}

static void ieee80211_get_regs(struct net_device *dev,
			       struct ethtool_regs *regs,
			       void *data)
{
	struct wireless_dev *wdev = dev->ieee80211_ptr;

	regs->version = wdev->wiphy->hw_version;
	regs->len = 0;
}

const struct ethtool_ops ieee80211_ethtool_ops = {
	.get_drvinfo = cfg80211_get_drvinfo,
	.get_regs_len = ieee80211_get_regs_len,
	.get_regs = ieee80211_get_regs,
	.get_link = ethtool_op_get_link,
	.get_ringparam = ieee80211_get_ringparam,
	.set_ringparam = ieee80211_set_ringparam,
	.get_strings = ieee80211_get_strings,
	.get_ethtool_stats = ieee80211_get_stats,
	.get_sset_count = ieee80211_get_sset_count,
};
back to top