mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 16:54:27 +00:00
net: hibmcge: Implement some .ndo functions
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 <shaojijie@huawei.com> Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
parent
4d089035fa
commit
ff4edac6e9
4 changed files with 142 additions and 0 deletions
|
@ -15,6 +15,7 @@
|
||||||
* ctrl means packet description, data means skb packet data
|
* ctrl means packet description, data means skb packet data
|
||||||
*/
|
*/
|
||||||
#define HBG_ENDIAN_CTRL_LE_DATA_BE 0x0
|
#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)
|
static bool hbg_hw_spec_is_valid(struct hbg_priv *priv)
|
||||||
{
|
{
|
||||||
|
@ -132,6 +133,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);
|
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 */
|
||||||
|
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)
|
void hbg_hw_adjust_link(struct hbg_priv *priv, u32 speed, u32 duplex)
|
||||||
{
|
{
|
||||||
hbg_reg_write_field(priv, HBG_REG_PORT_MODE_ADDR,
|
hbg_reg_write_field(priv, HBG_REG_PORT_MODE_ADDR,
|
||||||
|
|
|
@ -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);
|
void hbg_hw_irq_clear(struct hbg_priv *priv, u32 mask);
|
||||||
bool hbg_hw_irq_is_enabled(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_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
|
#endif
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
// Copyright (c) 2024 Hisilicon Limited.
|
// Copyright (c) 2024 Hisilicon Limited.
|
||||||
|
|
||||||
#include <linux/etherdevice.h>
|
#include <linux/etherdevice.h>
|
||||||
|
#include <linux/if_vlan.h>
|
||||||
#include <linux/netdevice.h>
|
#include <linux/netdevice.h>
|
||||||
#include <linux/pci.h>
|
#include <linux/pci.h>
|
||||||
#include "hbg_common.h"
|
#include "hbg_common.h"
|
||||||
|
@ -9,6 +10,90 @@
|
||||||
#include "hbg_irq.h"
|
#include "hbg_irq.h"
|
||||||
#include "hbg_mdio.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)
|
static int hbg_init(struct hbg_priv *priv)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -82,6 +167,12 @@ static int hbg_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
netdev->pcpu_stat_type = NETDEV_PCPU_STAT_TSTATS;
|
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);
|
ret = devm_register_netdev(dev, netdev);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
|
|
@ -37,8 +37,12 @@
|
||||||
#define HBG_REG_SGMII_BASE 0x10000
|
#define HBG_REG_SGMII_BASE 0x10000
|
||||||
#define HBG_REG_DUPLEX_TYPE_ADDR (HBG_REG_SGMII_BASE + 0x0008)
|
#define HBG_REG_DUPLEX_TYPE_ADDR (HBG_REG_SGMII_BASE + 0x0008)
|
||||||
#define HBG_REG_DUPLEX_B BIT(0)
|
#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_ADDR (HBG_REG_SGMII_BASE + 0x0040)
|
||||||
#define HBG_REG_PORT_MODE_M GENMASK(3, 0)
|
#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_ADDR (HBG_REG_SGMII_BASE + 0x0060)
|
||||||
#define HBG_REG_TRANSMIT_CTRL_PAD_EN_B BIT(7)
|
#define HBG_REG_TRANSMIT_CTRL_PAD_EN_B BIT(7)
|
||||||
#define HBG_REG_TRANSMIT_CTRL_CRC_ADD_B BIT(6)
|
#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_MODE_CHANGE_EN_B BIT(0)
|
||||||
#define HBG_REG_RECV_CTRL_ADDR (HBG_REG_SGMII_BASE + 0x01E0)
|
#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_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 */
|
/* PCU */
|
||||||
#define HBG_REG_CF_INTRPT_MSK_ADDR (HBG_REG_SGMII_BASE + 0x042C)
|
#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_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_STAT_ADDR (HBG_REG_SGMII_BASE + 0x0434)
|
||||||
#define HBG_REG_CF_INTRPT_CLR_ADDR (HBG_REG_SGMII_BASE + 0x0438)
|
#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_ADDR (HBG_REG_SGMII_BASE + 0x04E4)
|
||||||
#define HBG_REG_RX_BUF_SIZE_M GENMASK(15, 0)
|
#define HBG_REG_RX_BUF_SIZE_M GENMASK(15, 0)
|
||||||
#define HBG_REG_BUS_CTRL_ADDR (HBG_REG_SGMII_BASE + 0x04E8)
|
#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_ADDR (HBG_REG_SGMII_BASE + 0x04F4)
|
||||||
#define HBG_REG_RX_PKT_MODE_PARSE_MODE_M GENMASK(22, 21)
|
#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_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_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_TXINT_CLR_ADDR (HBG_REG_SGMII_BASE + 0x069C)
|
||||||
#define HBG_REG_CF_IND_RXINT_MSK_ADDR (HBG_REG_SGMII_BASE + 0x06a0)
|
#define HBG_REG_CF_IND_RXINT_MSK_ADDR (HBG_REG_SGMII_BASE + 0x06a0)
|
||||||
|
|
Loading…
Add table
Reference in a new issue