drivers/net/dsa/xrs700x/xrs700x_mdio.c

Source file repositories/reference/linux-study-clean/drivers/net/dsa/xrs700x/xrs700x_mdio.c

File Facts

System
Linux kernel
Corpus path
drivers/net/dsa/xrs700x/xrs700x_mdio.c
Extension
.c
Size
4198 bytes
Lines
181
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
/*
 * Copyright (C) 2020 NovaTech LLC
 * George McCollister <george.mccollister@gmail.com>
 */

#include <linux/bitfield.h>
#include <linux/bits.h>
#include <linux/mdio.h>
#include <linux/module.h>
#include <linux/phy.h>
#include <linux/if_vlan.h>
#include <linux/of.h>
#include "xrs700x.h"
#include "xrs700x_reg.h"

#define XRS_MDIO_IBA0	0x10
#define XRS_MDIO_IBA1	0x11
#define XRS_MDIO_IBD	0x14

#define XRS_IB_READ	0x0
#define XRS_IB_WRITE	0x1

static int xrs700x_mdio_reg_read(void *context, unsigned int reg,
				 unsigned int *val)
{
	struct mdio_device *mdiodev = context;
	struct device *dev = &mdiodev->dev;
	u16 uval;
	int ret;

	uval = (u16)FIELD_GET(GENMASK(31, 16), reg);

	ret = mdiodev_write(mdiodev, XRS_MDIO_IBA1, uval);
	if (ret < 0) {
		dev_err(dev, "xrs mdiobus_write returned %d\n", ret);
		return ret;
	}

	uval = (u16)((reg & GENMASK(15, 1)) | XRS_IB_READ);

	ret = mdiodev_write(mdiodev, XRS_MDIO_IBA0, uval);
	if (ret < 0) {
		dev_err(dev, "xrs mdiobus_write returned %d\n", ret);
		return ret;
	}

	ret = mdiodev_read(mdiodev, XRS_MDIO_IBD);
	if (ret < 0) {
		dev_err(dev, "xrs mdiobus_read returned %d\n", ret);
		return ret;
	}

	*val = (unsigned int)ret;

	return 0;
}

static int xrs700x_mdio_reg_write(void *context, unsigned int reg,
				  unsigned int val)
{
	struct mdio_device *mdiodev = context;
	struct device *dev = &mdiodev->dev;
	u16 uval;
	int ret;

	ret = mdiodev_write(mdiodev, XRS_MDIO_IBD, (u16)val);
	if (ret < 0) {
		dev_err(dev, "xrs mdiobus_write returned %d\n", ret);
		return ret;
	}

	uval = (u16)FIELD_GET(GENMASK(31, 16), reg);

	ret = mdiodev_write(mdiodev, XRS_MDIO_IBA1, uval);
	if (ret < 0) {
		dev_err(dev, "xrs mdiobus_write returned %d\n", ret);
		return ret;
	}

	uval = (u16)((reg & GENMASK(15, 1)) | XRS_IB_WRITE);

	ret = mdiodev_write(mdiodev, XRS_MDIO_IBA0, uval);
	if (ret < 0) {
		dev_err(dev, "xrs mdiobus_write returned %d\n", ret);
		return ret;
	}

	return 0;
}

Annotation

Implementation Notes