From patchwork Tue Oct 8 02:23:53 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jijie Shao X-Patchwork-Id: 13825573 X-Patchwork-Delegate: kuba@kernel.org Received: from szxga01-in.huawei.com (szxga01-in.huawei.com [45.249.212.187]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E78D8339A1; Tue, 8 Oct 2024 02:30:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.187 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728354634; cv=none; b=spuhmQomjcVnsbtEaJfHSQZHtCWebxww5QDl3DAaTekibTfwHK3HrF0hQAyjhcSEpQqKF9aa4vbtr55yEz1wBnF1fr5F3pT65NoN06FXLtfgOosZnekK8qa9VLLzIa+XhAjvM6XdkwUAA/CGhHJ6qyX28adqbpkN1+gf+puOqfw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728354634; c=relaxed/simple; bh=YRj7LRPVV111EM7J/iVjQNTH1jOEk7ozJDqbetAyj18=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Pq6oybQEABrHohs/5m3BT1V046AafDP13h9fVAv3MnNCm1ZPRzcs6Inl9wIn0FU7lmWlrQbG6QhzwX3rTCrPoaZ/yqb6izgg4nUZuWKNeMsmkL5PVb8p4RXHELrqJRy742+l8UB3k5xZ4mJsKPgVL54jmHAHTudJ4Alx9myM0XM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; arc=none smtp.client-ip=45.249.212.187 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Received: from mail.maildlp.com (unknown [172.19.88.105]) by szxga01-in.huawei.com (SkyGuard) with ESMTP id 4XN0MY6V0WzySxY; Tue, 8 Oct 2024 10:29:13 +0800 (CST) Received: from kwepemm000007.china.huawei.com (unknown [7.193.23.189]) by mail.maildlp.com (Postfix) with ESMTPS id B7FA01403D5; Tue, 8 Oct 2024 10:30:28 +0800 (CST) Received: from localhost.localdomain (10.90.30.45) by kwepemm000007.china.huawei.com (7.193.23.189) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.39; Tue, 8 Oct 2024 10:30:27 +0800 From: Jijie Shao To: , , , CC: , , , , , , , , , , , , , , , , , , Subject: [PATCH V11 net-next 05/10] net: hibmcge: Implement some .ndo functions Date: Tue, 8 Oct 2024 10:23:53 +0800 Message-ID: <20241008022358.863393-6-shaojijie@huawei.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20241008022358.863393-1-shaojijie@huawei.com> References: <20241008022358.863393-1-shaojijie@huawei.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: dggems702-chm.china.huawei.com (10.3.19.179) To kwepemm000007.china.huawei.com (7.193.23.189) X-Patchwork-Delegate: kuba@kernel.org Implement the .ndo_open() .ndo_stop() .ndo_set_mac_address() and .ndo_change_mtu functions(). And .ndo_validate_addr calls the eth_validate_addr function directly Signed-off-by: Jijie Shao Reviewed-by: Kalesh AP --- ChangeLog: v10 -> v11: - return -EBUSY in ndo.change_mtu() if interface is running, suggested by Jakub. - Remove ndo.get_stats64() because dev_get_tstats64() do same thing. v10: https://lore.kernel.org/all/20240912025127.3912972-1-shaojijie@huawei.com/ v9 -> v10: - Use ETH_DATA_LEN instead of HBG_DEFAULT_MTU_SIZE, suggested by Andrew. - Add validation for mac address in hbg_net_set_mac_address() v9: https://lore.kernel.org/all/20240910075942.1270054-1-shaojijie@huawei.com/ v8 -> v9: - Remove HBG_NIC_STATE_OPEN in ndo.open() and ndo.stop(), suggested by Kalesh and Andrew. - Use netif_running() instead of hbg_nic_is_open() in ndo.change_mtu(), suggested by Kalesh and Andrew v8: https://lore.kernel.org/all/20240909023141.3234567-1-shaojijie@huawei.com/ v6 -> v7: - Add implement ndo.get_stats64(), suggested by Paolo. v6: https://lore.kernel.org/all/20240830121604.2250904-6-shaojijie@huawei.com/ v5 -> v6: - Delete netif_carrier_off() in .ndo_open() and .ndo_stop(), suggested by Jakub and Andrew. v5: https://lore.kernel.org/all/20240827131455.2919051-1-shaojijie@huawei.com/ v3 -> v4: - Delete INITED_STATE in priv, suggested by Andrew. - Delete unnecessary defensive code in hbg_phy_start() and hbg_phy_stop(), suggested by Andrew. v3: https://lore.kernel.org/all/20240822093334.1687011-1-shaojijie@huawei.com/ RFC v1 -> RFC v2: - Delete validation for mtu in hbg_net_change_mtu(), suggested by Andrew. - Delete validation for mac address in hbg_net_set_mac_address(), suggested by Andrew. - Add a patch to add is_valid_ether_addr check in dev_set_mac_address, suggested by Andrew. RFC v1: https://lore.kernel.org/all/20240731094245.1967834-1-shaojijie@huawei.com/ --- .../net/ethernet/hisilicon/hibmcge/hbg_hw.c | 39 ++++++++ .../net/ethernet/hisilicon/hibmcge/hbg_hw.h | 3 + .../net/ethernet/hisilicon/hibmcge/hbg_main.c | 91 +++++++++++++++++++ .../net/ethernet/hisilicon/hibmcge/hbg_reg.h | 9 ++ 4 files changed, 142 insertions(+) diff --git a/drivers/net/ethernet/hisilicon/hibmcge/hbg_hw.c b/drivers/net/ethernet/hisilicon/hibmcge/hbg_hw.c index b201f2bc4ffe..229324fa659d 100644 --- a/drivers/net/ethernet/hisilicon/hibmcge/hbg_hw.c +++ b/drivers/net/ethernet/hisilicon/hibmcge/hbg_hw.c @@ -15,6 +15,7 @@ * ctrl means packet description, data means skb packet data */ #define HBG_ENDIAN_CTRL_LE_DATA_BE 0x0 +#define HBG_PCU_FRAME_LEN_PLUS 4 static bool hbg_hw_spec_is_valid(struct hbg_priv *priv) { @@ -129,6 +130,44 @@ void hbg_hw_irq_enable(struct hbg_priv *priv, u32 mask, bool enable) hbg_reg_write(priv, HBG_REG_CF_INTRPT_MSK_ADDR, value); } +void hbg_hw_set_uc_addr(struct hbg_priv *priv, u64 mac_addr) +{ + hbg_reg_write64(priv, HBG_REG_STATION_ADDR_LOW_2_ADDR, mac_addr); +} + +static void hbg_hw_set_pcu_max_frame_len(struct hbg_priv *priv, + u16 max_frame_len) +{ + max_frame_len = max_t(u32, max_frame_len, ETH_DATA_LEN); + + /* lower two bits of value must be set to 0. Otherwise, the value is ignored */ + max_frame_len = round_up(max_frame_len, HBG_PCU_FRAME_LEN_PLUS); + + hbg_reg_write_field(priv, HBG_REG_MAX_FRAME_LEN_ADDR, + HBG_REG_MAX_FRAME_LEN_M, max_frame_len); +} + +static void hbg_hw_set_mac_max_frame_len(struct hbg_priv *priv, + u16 max_frame_size) +{ + hbg_reg_write_field(priv, HBG_REG_MAX_FRAME_SIZE_ADDR, + HBG_REG_MAX_FRAME_LEN_M, max_frame_size); +} + +void hbg_hw_set_mtu(struct hbg_priv *priv, u16 mtu) +{ + hbg_hw_set_pcu_max_frame_len(priv, mtu); + hbg_hw_set_mac_max_frame_len(priv, mtu); +} + +void hbg_hw_mac_enable(struct hbg_priv *priv, u32 enable) +{ + hbg_reg_write_field(priv, HBG_REG_PORT_ENABLE_ADDR, + HBG_REG_PORT_ENABLE_TX_B, enable); + hbg_reg_write_field(priv, HBG_REG_PORT_ENABLE_ADDR, + HBG_REG_PORT_ENABLE_RX_B, enable); +} + void hbg_hw_adjust_link(struct hbg_priv *priv, u32 speed, u32 duplex) { hbg_reg_write_field(priv, HBG_REG_PORT_MODE_ADDR, diff --git a/drivers/net/ethernet/hisilicon/hibmcge/hbg_hw.h b/drivers/net/ethernet/hisilicon/hibmcge/hbg_hw.h index 4d09bdd41c76..0ce500e907b3 100644 --- a/drivers/net/ethernet/hisilicon/hibmcge/hbg_hw.h +++ b/drivers/net/ethernet/hisilicon/hibmcge/hbg_hw.h @@ -49,5 +49,8 @@ u32 hbg_hw_get_irq_status(struct hbg_priv *priv); void hbg_hw_irq_clear(struct hbg_priv *priv, u32 mask); bool hbg_hw_irq_is_enabled(struct hbg_priv *priv, u32 mask); void hbg_hw_irq_enable(struct hbg_priv *priv, u32 mask, bool enable); +void hbg_hw_set_mtu(struct hbg_priv *priv, u16 mtu); +void hbg_hw_mac_enable(struct hbg_priv *priv, u32 enable); +void hbg_hw_set_uc_addr(struct hbg_priv *priv, u64 mac_addr); #endif diff --git a/drivers/net/ethernet/hisilicon/hibmcge/hbg_main.c b/drivers/net/ethernet/hisilicon/hibmcge/hbg_main.c index e71ff821c582..3f6f3b381c50 100644 --- a/drivers/net/ethernet/hisilicon/hibmcge/hbg_main.c +++ b/drivers/net/ethernet/hisilicon/hibmcge/hbg_main.c @@ -2,6 +2,7 @@ // Copyright (c) 2024 Hisilicon Limited. #include +#include #include #include #include "hbg_common.h" @@ -9,6 +10,90 @@ #include "hbg_irq.h" #include "hbg_mdio.h" +static void hbg_all_irq_enable(struct hbg_priv *priv, bool enabled) +{ + struct hbg_irq_info *info; + u32 i; + + for (i = 0; i < priv->vectors.info_array_len; i++) { + info = &priv->vectors.info_array[i]; + hbg_hw_irq_enable(priv, info->mask, enabled); + } +} + +static int hbg_net_open(struct net_device *netdev) +{ + struct hbg_priv *priv = netdev_priv(netdev); + + hbg_all_irq_enable(priv, true); + hbg_hw_mac_enable(priv, HBG_STATUS_ENABLE); + netif_start_queue(netdev); + hbg_phy_start(priv); + + return 0; +} + +static int hbg_net_stop(struct net_device *netdev) +{ + struct hbg_priv *priv = netdev_priv(netdev); + + hbg_phy_stop(priv); + netif_stop_queue(netdev); + hbg_hw_mac_enable(priv, HBG_STATUS_DISABLE); + hbg_all_irq_enable(priv, false); + + return 0; +} + +static int hbg_net_set_mac_address(struct net_device *netdev, void *addr) +{ + struct hbg_priv *priv = netdev_priv(netdev); + u8 *mac_addr; + + mac_addr = ((struct sockaddr *)addr)->sa_data; + + if (!is_valid_ether_addr(mac_addr)) + return -EADDRNOTAVAIL; + + hbg_hw_set_uc_addr(priv, ether_addr_to_u64(mac_addr)); + dev_addr_set(netdev, mac_addr); + + return 0; +} + +static void hbg_change_mtu(struct hbg_priv *priv, int new_mtu) +{ + u32 frame_len; + + frame_len = new_mtu + VLAN_HLEN * priv->dev_specs.vlan_layers + + ETH_HLEN + ETH_FCS_LEN; + hbg_hw_set_mtu(priv, frame_len); +} + +static int hbg_net_change_mtu(struct net_device *netdev, int new_mtu) +{ + struct hbg_priv *priv = netdev_priv(netdev); + + if (netif_running(netdev)) + return -EBUSY; + + hbg_change_mtu(priv, new_mtu); + WRITE_ONCE(netdev->mtu, new_mtu); + + dev_dbg(&priv->pdev->dev, + "change mtu from %u to %u\n", netdev->mtu, new_mtu); + + return 0; +} + +static const struct net_device_ops hbg_netdev_ops = { + .ndo_open = hbg_net_open, + .ndo_stop = hbg_net_stop, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = hbg_net_set_mac_address, + .ndo_change_mtu = hbg_net_change_mtu, +}; + static int hbg_init(struct hbg_priv *priv) { int ret; @@ -82,6 +167,12 @@ static int hbg_probe(struct pci_dev *pdev, const struct pci_device_id *ent) return ret; netdev->pcpu_stat_type = NETDEV_PCPU_STAT_TSTATS; + netdev->max_mtu = priv->dev_specs.max_mtu; + netdev->min_mtu = priv->dev_specs.min_mtu; + netdev->netdev_ops = &hbg_netdev_ops; + + hbg_change_mtu(priv, ETH_DATA_LEN); + hbg_net_set_mac_address(priv->netdev, &priv->dev_specs.mac_addr); ret = devm_register_netdev(dev, netdev); if (ret) diff --git a/drivers/net/ethernet/hisilicon/hibmcge/hbg_reg.h b/drivers/net/ethernet/hisilicon/hibmcge/hbg_reg.h index 8cdf018c2de9..fbc17ca5564f 100644 --- a/drivers/net/ethernet/hisilicon/hibmcge/hbg_reg.h +++ b/drivers/net/ethernet/hisilicon/hibmcge/hbg_reg.h @@ -37,8 +37,12 @@ #define HBG_REG_SGMII_BASE 0x10000 #define HBG_REG_DUPLEX_TYPE_ADDR (HBG_REG_SGMII_BASE + 0x0008) #define HBG_REG_DUPLEX_B BIT(0) +#define HBG_REG_MAX_FRAME_SIZE_ADDR (HBG_REG_SGMII_BASE + 0x003C) #define HBG_REG_PORT_MODE_ADDR (HBG_REG_SGMII_BASE + 0x0040) #define HBG_REG_PORT_MODE_M GENMASK(3, 0) +#define HBG_REG_PORT_ENABLE_ADDR (HBG_REG_SGMII_BASE + 0x0044) +#define HBG_REG_PORT_ENABLE_RX_B BIT(1) +#define HBG_REG_PORT_ENABLE_TX_B BIT(2) #define HBG_REG_TRANSMIT_CTRL_ADDR (HBG_REG_SGMII_BASE + 0x0060) #define HBG_REG_TRANSMIT_CTRL_PAD_EN_B BIT(7) #define HBG_REG_TRANSMIT_CTRL_CRC_ADD_B BIT(6) @@ -49,6 +53,8 @@ #define HBG_REG_MODE_CHANGE_EN_B BIT(0) #define HBG_REG_RECV_CTRL_ADDR (HBG_REG_SGMII_BASE + 0x01E0) #define HBG_REG_RECV_CTRL_STRIP_PAD_EN_B BIT(3) +#define HBG_REG_STATION_ADDR_LOW_2_ADDR (HBG_REG_SGMII_BASE + 0x0210) +#define HBG_REG_STATION_ADDR_HIGH_2_ADDR (HBG_REG_SGMII_BASE + 0x0214) /* PCU */ #define HBG_REG_CF_INTRPT_MSK_ADDR (HBG_REG_SGMII_BASE + 0x042C) @@ -72,6 +78,8 @@ #define HBG_INT_MSK_RX_B BIT(0) /* just used in driver */ #define HBG_REG_CF_INTRPT_STAT_ADDR (HBG_REG_SGMII_BASE + 0x0434) #define HBG_REG_CF_INTRPT_CLR_ADDR (HBG_REG_SGMII_BASE + 0x0438) +#define HBG_REG_MAX_FRAME_LEN_ADDR (HBG_REG_SGMII_BASE + 0x0444) +#define HBG_REG_MAX_FRAME_LEN_M GENMASK(15, 0) #define HBG_REG_RX_BUF_SIZE_ADDR (HBG_REG_SGMII_BASE + 0x04E4) #define HBG_REG_RX_BUF_SIZE_M GENMASK(15, 0) #define HBG_REG_BUS_CTRL_ADDR (HBG_REG_SGMII_BASE + 0x04E8) @@ -86,6 +94,7 @@ #define HBG_REG_RX_PKT_MODE_ADDR (HBG_REG_SGMII_BASE + 0x04F4) #define HBG_REG_RX_PKT_MODE_PARSE_MODE_M GENMASK(22, 21) #define HBG_REG_CF_IND_TXINT_MSK_ADDR (HBG_REG_SGMII_BASE + 0x0694) +#define HBG_REG_IND_INTR_MASK_B BIT(0) #define HBG_REG_CF_IND_TXINT_STAT_ADDR (HBG_REG_SGMII_BASE + 0x0698) #define HBG_REG_CF_IND_TXINT_CLR_ADDR (HBG_REG_SGMII_BASE + 0x069C) #define HBG_REG_CF_IND_RXINT_MSK_ADDR (HBG_REG_SGMII_BASE + 0x06a0)