drivers/net/ethernet/mucse/rnpgbe/rnpgbe_main.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_main.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/mucse/rnpgbe/rnpgbe_main.c
Extension
.c
Size
8148 bytes
Lines
321
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern 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

static const struct net_device_ops rnpgbe_netdev_ops = {
	.ndo_open       = rnpgbe_open,
	.ndo_stop       = rnpgbe_close,
	.ndo_start_xmit = rnpgbe_xmit_frame,
};

/**
 * rnpgbe_add_adapter - Add netdev for this pci_dev
 * @pdev: PCI device information structure
 * @board_type: board type
 *
 * rnpgbe_add_adapter initializes a netdev for this pci_dev
 * structure. Initializes Bar map, private structure, and a
 * hardware reset occur.
 *
 * Return: 0 on success, negative errno on failure
 **/
static int rnpgbe_add_adapter(struct pci_dev *pdev,
			      int board_type)
{
	struct net_device *netdev;
	u8 perm_addr[ETH_ALEN];
	void __iomem *hw_addr;
	struct mucse *mucse;
	struct mucse_hw *hw;
	int err, err_notify;

	netdev = alloc_etherdev_mq(sizeof(struct mucse), RNPGBE_MAX_QUEUES);
	if (!netdev)
		return -ENOMEM;

	SET_NETDEV_DEV(netdev, &pdev->dev);
	mucse = netdev_priv(netdev);
	mucse->netdev = netdev;
	mucse->pdev = pdev;
	pci_set_drvdata(pdev, mucse);

	hw = &mucse->hw;
	hw_addr = devm_ioremap(&pdev->dev,
			       pci_resource_start(pdev, 2),
			       pci_resource_len(pdev, 2));
	if (!hw_addr) {
		err = -EIO;
		goto err_free_net;
	}

	hw->hw_addr = hw_addr;
	hw->pdev = pdev;

	err = rnpgbe_init_hw(hw, board_type);
	if (err) {
		dev_err(&pdev->dev, "Init hw err %d\n", err);
		goto err_free_net;
	}
	/* Step 1: Send power-up notification to firmware (no response expected)
	 * This informs firmware to initialize hardware power state, but
	 * firmware only acknowledges receipt without returning data. Must be
	 * done before synchronization as firmware may be in low-power idle
	 * state initially.
	 */
	err_notify = rnpgbe_send_notify(hw, true, mucse_fw_powerup);
	if (err_notify) {
		dev_warn(&pdev->dev, "Send powerup to hw failed %d\n",
			 err_notify);
		dev_warn(&pdev->dev, "Maybe low performance\n");
	}
	/* Step 2: Synchronize mailbox communication with firmware (requires
	 * response) After power-up, confirm firmware is ready to process
	 * requests with responses. This ensures subsequent request/response
	 * interactions work reliably.
	 */
	err = mucse_mbx_sync_fw(hw);
	if (err) {
		dev_err(&pdev->dev, "Sync fw failed! %d\n", err);
		goto err_powerdown;
	}

	netdev->netdev_ops = &rnpgbe_netdev_ops;
	err = rnpgbe_reset_hw(hw);
	if (err) {
		dev_err(&pdev->dev, "Hw reset failed %d\n", err);
		goto err_powerdown;
	}

	err = rnpgbe_get_permanent_mac(hw, perm_addr);
	if (!err) {
		eth_hw_addr_set(netdev, perm_addr);
	} else if (err == -EINVAL) {
		dev_warn(&pdev->dev, "Using random MAC\n");
		eth_hw_addr_random(netdev);

Annotation

Implementation Notes