drivers/net/ethernet/asix/ax88796c_ioctl.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/asix/ax88796c_ioctl.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/asix/ax88796c_ioctl.c
Extension
.c
Size
5857 bytes
Lines
240
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2010 ASIX Electronics Corporation
 * Copyright (c) 2020 Samsung Electronics Co., Ltd.
 *
 * ASIX AX88796C SPI Fast Ethernet Linux driver
 */

#define pr_fmt(fmt)	"ax88796c: " fmt

#include <linux/bitmap.h>
#include <linux/iopoll.h>
#include <linux/phy.h>
#include <linux/netdevice.h>

#include "ax88796c_main.h"
#include "ax88796c_ioctl.h"

static const char ax88796c_priv_flag_names[][ETH_GSTRING_LEN] = {
	"SPICompression",
};

static void
ax88796c_get_drvinfo(struct net_device *ndev, struct ethtool_drvinfo *info)
{
	/* Inherit standard device info */
	strscpy(info->driver, DRV_NAME, sizeof(info->driver));
}

static u32 ax88796c_get_msglevel(struct net_device *ndev)
{
	struct ax88796c_device *ax_local = to_ax88796c_device(ndev);

	return ax_local->msg_enable;
}

static void ax88796c_set_msglevel(struct net_device *ndev, u32 level)
{
	struct ax88796c_device *ax_local = to_ax88796c_device(ndev);

	ax_local->msg_enable = level;
}

static void
ax88796c_get_pauseparam(struct net_device *ndev, struct ethtool_pauseparam *pause)
{
	struct ax88796c_device *ax_local = to_ax88796c_device(ndev);

	pause->tx_pause = !!(ax_local->flowctrl & AX_FC_TX);
	pause->rx_pause = !!(ax_local->flowctrl & AX_FC_RX);
	pause->autoneg = (ax_local->flowctrl & AX_FC_ANEG) ?
		AUTONEG_ENABLE :
		AUTONEG_DISABLE;
}

static int
ax88796c_set_pauseparam(struct net_device *ndev, struct ethtool_pauseparam *pause)
{
	struct ax88796c_device *ax_local = to_ax88796c_device(ndev);
	int fc;

	/* The following logic comes from phylink_ethtool_set_pauseparam() */
	fc = pause->tx_pause ? AX_FC_TX : 0;
	fc |= pause->rx_pause ? AX_FC_RX : 0;
	fc |= pause->autoneg ? AX_FC_ANEG : 0;

	ax_local->flowctrl = fc;

	if (pause->autoneg) {
		phy_set_asym_pause(ax_local->phydev, pause->tx_pause,
				   pause->rx_pause);
	} else {
		int maccr = 0;

		phy_set_asym_pause(ax_local->phydev, 0, 0);
		maccr |= (ax_local->flowctrl & AX_FC_RX) ? MACCR_RXFC_ENABLE : 0;
		maccr |= (ax_local->flowctrl & AX_FC_TX) ? MACCR_TXFC_ENABLE : 0;

		mutex_lock(&ax_local->spi_lock);

		maccr |= AX_READ(&ax_local->ax_spi, P0_MACCR) &
			~(MACCR_TXFC_ENABLE | MACCR_RXFC_ENABLE);
		AX_WRITE(&ax_local->ax_spi, maccr, P0_MACCR);

		mutex_unlock(&ax_local->spi_lock);
	}

	return 0;
}

Annotation

Implementation Notes