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

Commit 1b64e171 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "atlantic forwarding driver v1.1.6"

parents 5b3e7f14 8a072365
Loading
Loading
Loading
Loading
+7 −26
Original line number Diff line number Diff line
################################################################################
# SPDX-License-Identifier: GPL-2.0-only
# Atlantic Network Driver
#
# aQuantia Ethernet Controller AQtion Linux Driver
# Copyright(c) 2014-2017 aQuantia Corporation.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms and conditions of the GNU General Public License,
# version 2, as published by the Free Software Foundation.
#
# This program is distributed in the hope it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
# more details.
#
# You should have received a copy of the GNU General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
# The full GNU General Public License is included in this distribution in
# the file called "COPYING".
#
# Contact Information: <rdc-drv@aquantia.com>
# aQuantia Corporation, 105 E. Tasman Dr. San Jose, CA 95134, USA
#
################################################################################

#
# Makefile for the AQtion(tm) Ethernet driver
# Copyright(c) 2014-2019 aQuantia Corporation.
# Copyright(c) 2019-2020 Marvell International Ltd.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.

obj-$(CONFIG_AQFWD) += atlantic-fwd.o

+119 −16
Original line number Diff line number Diff line
/*
 * Marvell Semiconductor Altantic Network Driver
 * Copyright (C) 2019 Marvell Semiconductor. All rights reserved
// SPDX-License-Identifier: GPL-2.0-only
/* Atlantic Network Driver
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 * Copyright (C) 2019 aQuantia Corporation
 * Copyright (C) 2019-2020 Marvell International Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <linux/etherdevice.h>

#include "atl_common.h"
@@ -51,6 +54,15 @@ static void atl2_mif_shared_buf_get(struct atl_hw *hw, int offset,
		data[i] = atl_read(hw, ATL2_MIF_SHARED_BUFFER_IN(offset + i));
}

static void atl2_mif_shared_boot_buf_write(struct atl_hw *hw, int offset,
					   u32 *data, int len)
{
	int i;

	for (i = 0; i < len / sizeof(u32); i++)
		atl_write(hw, ATL2_MIF_SHARED_BUFFER_BOOT(i), data[i]);
}

static void atl2_mif_shared_buf_write(struct atl_hw *hw, int offset,
				  u32 *data, int len)
{
@@ -522,6 +534,7 @@ static int __atl2_fw_get_link_caps(struct atl_hw *hw)

	hw->link_state.supported = supported;
	hw->link_state.lp_lowest = fls(supported) - 1;
	mcp->caps_low = atl_fw2_wake_on_link_force;

	return ret;
}
@@ -614,7 +627,7 @@ static int atl2_fw_set_phy_loopback(struct atl_nic *nic, u32 mode)
	switch (mode) {
	case ATL_PF_LPB_INT_PHY:
		if (!device_link_caps.internal_loopback) {
			ret = -ENOTSUPP;
			ret = -EOPNOTSUPP;
			goto unlock;
		}

@@ -622,7 +635,7 @@ static int atl2_fw_set_phy_loopback(struct atl_nic *nic, u32 mode)
		break;
	case ATL_PF_LPB_EXT_PHY:
		if (!device_link_caps.external_loopback) {
			ret = -ENOTSUPP;
			ret = -EOPNOTSUPP;
			goto unlock;
		}
		link_options.external_loopback = on;
@@ -640,6 +653,8 @@ static int atl2_fw_set_phy_loopback(struct atl_nic *nic, u32 mode)

static int atl2_fw_enable_wol(struct atl_hw *hw, unsigned int wol_mode)
{
	struct link_options_s link_options;
	struct link_control_s link_control;
	struct wake_on_lan_s wake_on_lan;
	struct mac_address_s mac_address;
	int ret = 0;
@@ -650,23 +665,32 @@ static int atl2_fw_enable_wol(struct atl_hw *hw, unsigned int wol_mode)

	if (wol_mode & atl_fw_wake_on_link) {
		wake_on_lan.wake_on_link_up = 1;
		/* TODO: add wol_ex_wake_on_link_keep_rate */
		if (test_bit(ATL_ST_UP, &hw->state))
			wake_on_lan.restore_link_before_wake = 1;
	}

	if (wol_mode & atl_fw_wake_on_link_rtpm) {
		/* TODO: add wake_on_link_force - wake alive host on link up */
		wake_on_lan.wake_on_link_up = 1;
	}

	if (wol_mode & atl_fw_wake_on_magic) {
		/* TODO: add wol_ex_wake_on_link_keep_rate */
		wake_on_lan.wake_on_magic_packet = 1;
		if (test_bit(ATL_ST_UP, &hw->state))
			wake_on_lan.restore_link_before_wake = 1;
	}

	ether_addr_copy(mac_address.mac_address, hw->mac_addr);

	atl2_shared_buffer_write(hw, mac_address, mac_address);
	atl2_shared_buffer_write(hw, sleep_proxy, wake_on_lan);
	atl2_mif_host_finished_write_set(hw, 1);
	atl2_shared_buffer_get(hw, link_control, link_control);
	link_control.mode = ATL2_HOST_MODE_SLEEP_PROXY;
	atl2_shared_buffer_write(hw, link_control, link_control);

	atl2_shared_buffer_get(hw, link_options, link_options);
	link_options.link_up = 1;
	atl2_shared_buffer_write(hw, link_options, link_options);

	ret = atl2_shared_buffer_finish_ack(hw);

	atl_unlock_fw(hw);
@@ -717,9 +741,88 @@ static int atl2_fw_set_pad_stripping(struct atl_hw *hw, bool on)
	return err;
}

#define ATL2_FW_CFG_DUMP_SIZE (4 + (sizeof(struct link_options_s) * 3) + \
			      (sizeof(struct link_control_s) * 3))
static int atl2_fw_dump_cfg(struct atl_hw *hw)
{
	if (!hw->mcp.fw_cfg_dump)
		hw->mcp.fw_cfg_dump = devm_kzalloc(&hw->pdev->dev,
						   ATL2_FW_CFG_DUMP_SIZE,
						   GFP_KERNEL);
	if (!hw->mcp.fw_cfg_dump)
		return -ENOMEM;

	/* save link configuration */
	hw->mcp.fw_cfg_dump[0] = ((2 * 3 * 4) << 16) | 3;
	hw->mcp.fw_cfg_dump[1] = offsetof(struct fw_interface_in, link_control);
	atl2_shared_buffer_get(hw, link_control, hw->mcp.fw_cfg_dump[2]);
	hw->mcp.fw_cfg_dump[3] = ~0;

	hw->mcp.fw_cfg_dump[4] = offsetof(struct fw_interface_in, link_options);
	atl2_shared_buffer_get(hw, link_options, hw->mcp.fw_cfg_dump[5]);
	hw->mcp.fw_cfg_dump[6] = ~0;

	return 0;
}

static void atl2_confirm_buffer_write(struct atl_hw *hw,
				      uint32_t offset, uint32_t len)
{
	struct data_buffer_status_s buffer_status;

	buffer_status.data_offset = offset;
	buffer_status.data_length = len;
	atl2_shared_buffer_write(hw, data_buffer_status, buffer_status);
}

static int atl2_fw_restore_cfg(struct atl_hw *hw)
{
	uint32_t req_adr = atl_read(hw, ATL2_MIF_BOOT_READ_REQ_ADR);
	uint32_t req_len = atl_read(hw, ATL2_MIF_BOOT_READ_REQ_LEN);

	if (req_adr == ATL2_ITI_ADDRESS_START) {
		struct fw_iti_hdr iti_header;

		memset(&iti_header, 0, sizeof(iti_header));
		iti_header.instuction_bitmask = BIT(2);
		iti_header.iti[0].type = 2;
		iti_header.iti[0].length = ATL2_FW_CFG_DUMP_SIZE;
		atl2_mif_shared_boot_buf_write(hw, 0, (void *)&iti_header,
					       sizeof(iti_header));
		atl2_confirm_buffer_write(hw, req_adr, req_len);

		atl2_mif_host_finished_write_set(hw, 1U);

		return 0;
	} else if (req_adr == ATL2_ITI_ADDRESS_BLOCK_1) {
		atl2_confirm_buffer_write(hw, req_adr, req_len);
		atl2_mif_shared_boot_buf_write(hw, 0,
			(void *)hw->mcp.fw_cfg_dump, ATL2_FW_CFG_DUMP_SIZE);
		atl2_mif_host_finished_write_set(hw, 1U);
		return 0;
	}

	atl_dev_err("FW requests invalid address %#x", req_adr);

	return -EFAULT;
}

static int atl2_fw_set_mediadetect(struct atl_hw *hw, bool on)
{
	struct link_options_s link_options;

	atl2_shared_buffer_get(hw, link_options, link_options);

	link_options.low_power_autoneg = on;

	atl2_shared_buffer_write(hw, link_options, link_options);

	return  atl2_shared_buffer_finish_ack(hw);
}

static int atl2_fw_unsupported(struct atl_hw *hw)
{
	return -ENOTSUPP;
	return -EOPNOTSUPP;
}

int atl2_get_fw_version(struct atl_hw *hw, u32 *fw_version)
@@ -742,15 +845,15 @@ static struct atl_fw_ops atl2_fw_ops = {
		.restart_aneg = atl2_fw_restart_aneg,
		.set_default_link = atl2_fw_set_default_link,
		.get_phy_temperature = atl2_fw_get_phy_temperature,
		.set_mediadetect = (void *)atl2_fw_unsupported,
		.set_mediadetect = atl2_fw_set_mediadetect,
		.send_macsec_req = (void *)atl2_fw_unsupported,
		.set_pad_stripping = atl2_fw_set_pad_stripping,
		.get_mac_addr = atl2_fw_get_mac_addr,
		.__get_hbeat = __atl2_fw_get_hbeat,
		.set_phy_loopback = atl2_fw_set_phy_loopback,
		.enable_wol = atl2_fw_enable_wol,
		.dump_cfg = (void *)atl2_fw_unsupported,
		.restore_cfg = (void *)atl2_fw_unsupported,
		.dump_cfg = (void *)atl2_fw_dump_cfg,
		.restore_cfg = atl2_fw_restore_cfg,
		.update_thermal = atl2_fw_update_thermal,
	};

+27 −8
Original line number Diff line number Diff line
/*
 * Marvell Semiconductor Altantic Network Driver
 * Copyright (C) 2019 Marvell Semiconductor. All rights reserved
/* SPDX-License-Identifier: GPL-2.0-only */
/* Atlantic Network Driver
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 * Copyright (C) 2019 aQuantia Corporation
 * Copyright (C) 2019-2020 Marvell International Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#ifndef _ATL2_FW_H_
@@ -40,7 +42,8 @@ struct link_options_s {
	uint32_t eee_2P5G:1;
	uint32_t eee_5G:1;
	uint32_t eee_10G:1;
	uint32_t rsvd3:3;
	uint32_t rsvd3:2;
	uint32_t low_power_autoneg:1;

	uint32_t pause_rx:1;
	uint32_t pause_tx:1;
@@ -88,7 +91,10 @@ struct sleep_proxy_s {
		uint32_t wake_on_link_down:1;
		uint32_t wake_on_ping:1;
		uint32_t wake_on_timer:1;
		uint32_t rsvd:26;
		uint32_t wake_on_link_mac_method:1;
		uint32_t rsrvd1:1;
		uint32_t restore_link_before_wake:1;
		uint32_t rsvd:23;

		uint32_t link_up_timeout;
		uint32_t link_down_timeout;
@@ -538,6 +544,16 @@ struct fw_interface_out {
	struct trace_s trace;
};

struct fw_iti_subblock_header {
	uint32_t type :8;
	uint32_t length :24;
};

struct fw_iti_hdr {
	uint32_t instuction_bitmask;
	uint32_t reserved;
	struct fw_iti_subblock_header iti[6];
};
/* End of HW byte packed interface declaration */
#pragma pack(pop)

@@ -574,6 +590,9 @@ struct fw_interface_out {
#define ATL2_FW_HOST_INTERRUPT_TEMPERATURE_WARNING 0x2000
#define ATL2_FW_HOST_INTERRUPT_HEARTBEAT           0x4000

#define ATL2_ITI_ADDRESS_START    0x100000
#define ATL2_ITI_ADDRESS_BLOCK_1  (ATL2_ITI_ADDRESS_START +\
				   sizeof(struct fw_iti_hdr) / sizeof(uint32_t))
enum {
	ATL2_MEMORY_MAILBOX_STATUS_FAIL = 0,
	ATL2_MEMORY_MAILBOX_STATUS_SUCCESS = 1
+9 −7
Original line number Diff line number Diff line
/*
 * aQuantia Corporation Network Driver
 * Copyright (C) 2017 aQuantia Corporation. All rights reserved
/* SPDX-License-Identifier: GPL-2.0-only */
/* Atlantic Network Driver
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 * Copyright (C) 2017 aQuantia Corporation
 * Copyright (C) 2019-2020 Marvell International Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#ifndef _ATL_COMMON_H_
@@ -18,7 +20,7 @@
#include <linux/netdevice.h>
#include <linux/moduleparam.h>

#define ATL_VERSION "1.1.4"
#define ATL_VERSION "1.1.6"

struct atl_nic;

+7 −6
Original line number Diff line number Diff line
/*
 * aQuantia Corporation Network Driver
 * Copyright (C) 2017 aQuantia Corporation. All rights reserved
// SPDX-License-Identifier: GPL-2.0-only
/* Atlantic Network Driver
 *
 * Copyright (C) 2017 aQuantia Corporation
 * Copyright (C) 2019-2020 Marvell International Ltd.
 * Portions Copyright (C) various contributors (see specific commit references)
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include "atl_common.h"
Loading