Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5be90f99 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'aquantia-next'



Igor Russkikh says:

====================
net: atlantic: Aquantia driver updates 2019-04

This patchset contains various improvements:

- Work targeting link up speedups: link interrupt introduced, some other
  logic changes to imrove this.
- FW operations securing with mutex
- Counters and statistics logic improved by Dmitry
- read out of chip temperature via hwmon interface implemented by
  Yana and Nikita.

v4 changes:
- remove drvinfo_exit noop
- 64bit stats should be readed out sequentially (lsw, then msw)
  declare 64bit read ops for that

v3 changes:
- temp ops renamed to phy_temp ops
- mutex commits squashed for better structure

v2 changes:
- use threaded irq for link state handling
- rework hwmon via devm_hwmon_device_register_with_info
Extra comments on review from Andrew:
- direct device name pointer is used in hwmon registration.
  This causes hwmon device to derive possible interface name changes
- Will consider sanity checks for firmware mutex lock separately.
  Right now there is no single point exsists where such check could
  be easily added.
- There is no way now to fetch and configure min/max/crit temperatures
  via FW. Will investigate this separately.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 2b5bc3c8 9eec0303
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ atlantic-objs := aq_main.o \
	aq_ring.o \
	aq_hw_utils.o \
	aq_ethtool.o \
	aq_drvinfo.o \
	aq_filters.o \
	hw_atl/hw_atl_a0.o \
	hw_atl/hw_atl_b0.o \
+0 −3
Original line number Diff line number Diff line
@@ -41,9 +41,6 @@
#define AQ_DEVICE_ID_AQC111S	0x91B1
#define AQ_DEVICE_ID_AQC112S	0x92B1

#define AQ_DEVICE_ID_AQC111E	0x51B1
#define AQ_DEVICE_ID_AQC112E	0x52B1

#define HW_ATL_NIC_NAME "aQuantia AQtion 10Gbit Network Adapter"

#define AQ_HWREV_ANY	0
+125 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-or-later
/* Copyright (C) 2014-2019 aQuantia Corporation. */

/* File aq_drvinfo.c: Definition of common code for firmware info in sys.*/

#include <linux/init.h>
#include <linux/kobject.h>
#include <linux/module.h>
#include <linux/stat.h>
#include <linux/string.h>
#include <linux/hwmon.h>
#include <linux/uaccess.h>

#include "aq_drvinfo.h"

static int aq_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
			 u32 attr, int channel, long *value)
{
	struct aq_nic_s *aq_nic = dev_get_drvdata(dev);
	int temp;
	int err;

	if (!aq_nic)
		return -EIO;

	if (type != hwmon_temp)
		return -EOPNOTSUPP;

	if (!aq_nic->aq_fw_ops->get_phy_temp)
		return -EOPNOTSUPP;

	switch (attr) {
	case hwmon_temp_input:
		err = aq_nic->aq_fw_ops->get_phy_temp(aq_nic->aq_hw, &temp);
		*value = temp;
		return err;
	default:
		return -EOPNOTSUPP;
	}
}

static int aq_hwmon_read_string(struct device *dev,
				enum hwmon_sensor_types type,
				u32 attr, int channel, const char **str)
{
	struct aq_nic_s *aq_nic = dev_get_drvdata(dev);

	if (!aq_nic)
		return -EIO;

	if (type != hwmon_temp)
		return -EOPNOTSUPP;

	if (!aq_nic->aq_fw_ops->get_phy_temp)
		return -EOPNOTSUPP;

	switch (attr) {
	case hwmon_temp_label:
		*str = "PHY Temperature";
		return 0;
	default:
		return -EOPNOTSUPP;
	}
}

static umode_t aq_hwmon_is_visible(const void *data,
				   enum hwmon_sensor_types type,
				   u32 attr, int channel)
{
	if (type != hwmon_temp)
		return 0;

	switch (attr) {
	case hwmon_temp_input:
	case hwmon_temp_label:
		return 0444;
	default:
		return 0;
	}
}

static const struct hwmon_ops aq_hwmon_ops = {
	.is_visible = aq_hwmon_is_visible,
	.read = aq_hwmon_read,
	.read_string = aq_hwmon_read_string,
};

static u32 aq_hwmon_temp_config[] = {
	HWMON_T_INPUT | HWMON_T_LABEL,
	0,
};

static const struct hwmon_channel_info aq_hwmon_temp = {
	.type = hwmon_temp,
	.config = aq_hwmon_temp_config,
};

static const struct hwmon_channel_info *aq_hwmon_info[] = {
	&aq_hwmon_temp,
	NULL,
};

static const struct hwmon_chip_info aq_hwmon_chip_info = {
	.ops = &aq_hwmon_ops,
	.info = aq_hwmon_info,
};

int aq_drvinfo_init(struct net_device *ndev)
{
	struct aq_nic_s *aq_nic = netdev_priv(ndev);
	struct device *dev = &aq_nic->pdev->dev;
	struct device *hwmon_dev;
	int err = 0;

	hwmon_dev = devm_hwmon_device_register_with_info(dev,
							 ndev->name,
							 aq_nic,
							 &aq_hwmon_chip_info,
							 NULL);

	if (IS_ERR(hwmon_dev))
		err = PTR_ERR(hwmon_dev);

	return err;
}
+15 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* Copyright (C) 2014-2017 aQuantia Corporation. */

/* File aq_drvinfo.h: Declaration of common code for firmware info in sys.*/

#ifndef AQ_DRVINFO_H
#define AQ_DRVINFO_H

#include "aq_nic.h"
#include "aq_hw.h"
#include "hw_atl/hw_atl_utils.h"

int aq_drvinfo_init(struct net_device *ndev);

#endif /* AQ_DRVINFO_H */
+18 −4
Original line number Diff line number Diff line
@@ -405,8 +405,10 @@ static int aq_ethtool_get_eee(struct net_device *ndev, struct ethtool_eee *eee)
	if (!aq_nic->aq_fw_ops->get_eee_rate)
		return -EOPNOTSUPP;

	mutex_lock(&aq_nic->fwreq_mutex);
	err = aq_nic->aq_fw_ops->get_eee_rate(aq_nic->aq_hw, &rate,
					      &supported_rates);
	mutex_unlock(&aq_nic->fwreq_mutex);
	if (err < 0)
		return err;

@@ -439,8 +441,10 @@ static int aq_ethtool_set_eee(struct net_device *ndev, struct ethtool_eee *eee)
		     !aq_nic->aq_fw_ops->set_eee_rate))
		return -EOPNOTSUPP;

	mutex_lock(&aq_nic->fwreq_mutex);
	err = aq_nic->aq_fw_ops->get_eee_rate(aq_nic->aq_hw, &rate,
					      &supported_rates);
	mutex_unlock(&aq_nic->fwreq_mutex);
	if (err < 0)
		return err;

@@ -452,20 +456,28 @@ static int aq_ethtool_set_eee(struct net_device *ndev, struct ethtool_eee *eee)
		cfg->eee_speeds = 0;
	}

	return aq_nic->aq_fw_ops->set_eee_rate(aq_nic->aq_hw, rate);
	mutex_lock(&aq_nic->fwreq_mutex);
	err = aq_nic->aq_fw_ops->set_eee_rate(aq_nic->aq_hw, rate);
	mutex_unlock(&aq_nic->fwreq_mutex);

	return err;
}

static int aq_ethtool_nway_reset(struct net_device *ndev)
{
	struct aq_nic_s *aq_nic = netdev_priv(ndev);
	int err = 0;

	if (unlikely(!aq_nic->aq_fw_ops->renegotiate))
		return -EOPNOTSUPP;

	if (netif_running(ndev))
		return aq_nic->aq_fw_ops->renegotiate(aq_nic->aq_hw);
	if (netif_running(ndev)) {
		mutex_lock(&aq_nic->fwreq_mutex);
		err = aq_nic->aq_fw_ops->renegotiate(aq_nic->aq_hw);
		mutex_unlock(&aq_nic->fwreq_mutex);
	}

	return 0;
	return err;
}

static void aq_ethtool_get_pauseparam(struct net_device *ndev,
@@ -503,7 +515,9 @@ static int aq_ethtool_set_pauseparam(struct net_device *ndev,
	else
		aq_nic->aq_hw->aq_nic_cfg->flow_control &= ~AQ_NIC_FC_TX;

	mutex_lock(&aq_nic->fwreq_mutex);
	err = aq_nic->aq_fw_ops->set_flow_control(aq_nic->aq_hw);
	mutex_unlock(&aq_nic->fwreq_mutex);

	return err;
}
Loading