diff options
Diffstat (limited to 'drivers/net/ethernet/hisilicon')
-rw-r--r-- | drivers/net/ethernet/hisilicon/hix5hd2_gmac.c | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c | 93 | ||||
-rw-r--r-- | drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c | 260 | ||||
-rw-r--r-- | drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h | 12 | ||||
-rw-r--r-- | drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c | 209 | ||||
-rw-r--r-- | drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h | 21 | ||||
-rw-r--r-- | drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c | 171 | ||||
-rw-r--r-- | drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c | 67 | ||||
-rw-r--r-- | drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.h | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c | 187 | ||||
-rw-r--r-- | drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.h | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h | 44 | ||||
-rw-r--r-- | drivers/net/ethernet/hisilicon/hns/hns_enet.c | 23 | ||||
-rw-r--r-- | drivers/net/ethernet/hisilicon/hns/hns_enet.h | 3 |
14 files changed, 611 insertions, 484 deletions
diff --git a/drivers/net/ethernet/hisilicon/hix5hd2_gmac.c b/drivers/net/ethernet/hisilicon/hix5hd2_gmac.c index e51892d518ff..b9f2ea59308a 100644 --- a/drivers/net/ethernet/hisilicon/hix5hd2_gmac.c +++ b/drivers/net/ethernet/hisilicon/hix5hd2_gmac.c @@ -636,7 +636,7 @@ static int hix5hd2_net_xmit(struct sk_buff *skb, struct net_device *dev) pos = dma_ring_incr(pos, TX_DESC_NUM); writel_relaxed(dma_byte(pos), priv->base + TX_BQ_WR_ADDR); - dev->trans_start = jiffies; + netif_trans_update(dev); dev->stats.tx_packets++; dev->stats.tx_bytes += skb->len; netdev_sent_queue(dev, skb->len); diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c index a1cb461ac45f..7a757e88c89a 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c @@ -29,25 +29,6 @@ static struct hns_mac_cb *hns_get_mac_cb(struct hnae_handle *handle) return vf_cb->mac_cb; } -/** - * hns_ae_map_eport_to_dport - translate enet port id to dsaf port id - * @port_id: enet port id - *: debug port 0-1, service port 2 -7 (dsaf mode only 2) - * return: dsaf port id - *: service ports 0 - 5, debug port 6-7 - **/ -static int hns_ae_map_eport_to_dport(u32 port_id) -{ - int port_index; - - if (port_id < DSAF_DEBUG_NW_NUM) - port_index = port_id + DSAF_SERVICE_PORT_NUM_PER_DSAF; - else - port_index = port_id - DSAF_DEBUG_NW_NUM; - - return port_index; -} - static struct dsaf_device *hns_ae_get_dsaf_dev(struct hnae_ae_dev *dev) { return container_of(dev, struct dsaf_device, ae_dev); @@ -56,50 +37,35 @@ static struct dsaf_device *hns_ae_get_dsaf_dev(struct hnae_ae_dev *dev) static struct hns_ppe_cb *hns_get_ppe_cb(struct hnae_handle *handle) { int ppe_index; - int ppe_common_index; struct ppe_common_cb *ppe_comm; struct hnae_vf_cb *vf_cb = hns_ae_get_vf_cb(handle); - if (vf_cb->port_index < DSAF_SERVICE_PORT_NUM_PER_DSAF) { - ppe_index = vf_cb->port_index; - ppe_common_index = 0; - } else { - ppe_index = 0; - ppe_common_index = - vf_cb->port_index - DSAF_SERVICE_PORT_NUM_PER_DSAF + 1; - } - ppe_comm = vf_cb->dsaf_dev->ppe_common[ppe_common_index]; + ppe_comm = vf_cb->dsaf_dev->ppe_common[0]; + ppe_index = vf_cb->port_index; + return &ppe_comm->ppe_cb[ppe_index]; } static int hns_ae_get_q_num_per_vf( struct dsaf_device *dsaf_dev, int port) { - int common_idx = hns_dsaf_get_comm_idx_by_port(port); - - return dsaf_dev->rcb_common[common_idx]->max_q_per_vf; + return dsaf_dev->rcb_common[0]->max_q_per_vf; } static int hns_ae_get_vf_num_per_port( struct dsaf_device *dsaf_dev, int port) { - int common_idx = hns_dsaf_get_comm_idx_by_port(port); - - return dsaf_dev->rcb_common[common_idx]->max_vfn; + return dsaf_dev->rcb_common[0]->max_vfn; } static struct ring_pair_cb *hns_ae_get_base_ring_pair( struct dsaf_device *dsaf_dev, int port) { - int common_idx = hns_dsaf_get_comm_idx_by_port(port); - struct rcb_common_cb *rcb_comm = dsaf_dev->rcb_common[common_idx]; + struct rcb_common_cb *rcb_comm = dsaf_dev->rcb_common[0]; int q_num = rcb_comm->max_q_per_vf; int vf_num = rcb_comm->max_vfn; - if (common_idx == HNS_DSAF_COMM_SERVICE_NW_IDX) - return &rcb_comm->ring_pair_cb[port * q_num * vf_num]; - else - return &rcb_comm->ring_pair_cb[0]; + return &rcb_comm->ring_pair_cb[port * q_num * vf_num]; } static struct ring_pair_cb *hns_ae_get_ring_pair(struct hnae_queue *q) @@ -110,7 +76,6 @@ static struct ring_pair_cb *hns_ae_get_ring_pair(struct hnae_queue *q) struct hnae_handle *hns_ae_get_handle(struct hnae_ae_dev *dev, u32 port_id) { - int port_idx; int vfnum_per_port; int qnum_per_vf; int i; @@ -120,11 +85,10 @@ struct hnae_handle *hns_ae_get_handle(struct hnae_ae_dev *dev, struct hnae_vf_cb *vf_cb; dsaf_dev = hns_ae_get_dsaf_dev(dev); - port_idx = hns_ae_map_eport_to_dport(port_id); - ring_pair_cb = hns_ae_get_base_ring_pair(dsaf_dev, port_idx); - vfnum_per_port = hns_ae_get_vf_num_per_port(dsaf_dev, port_idx); - qnum_per_vf = hns_ae_get_q_num_per_vf(dsaf_dev, port_idx); + ring_pair_cb = hns_ae_get_base_ring_pair(dsaf_dev, port_id); + vfnum_per_port = hns_ae_get_vf_num_per_port(dsaf_dev, port_id); + qnum_per_vf = hns_ae_get_q_num_per_vf(dsaf_dev, port_id); vf_cb = kzalloc(sizeof(*vf_cb) + qnum_per_vf * sizeof(struct hnae_queue *), GFP_KERNEL); @@ -163,14 +127,14 @@ struct hnae_handle *hns_ae_get_handle(struct hnae_ae_dev *dev, } vf_cb->dsaf_dev = dsaf_dev; - vf_cb->port_index = port_idx; - vf_cb->mac_cb = &dsaf_dev->mac_cb[port_idx]; + vf_cb->port_index = port_id; + vf_cb->mac_cb = dsaf_dev->mac_cb[port_id]; ae_handle->phy_if = vf_cb->mac_cb->phy_if; ae_handle->phy_node = vf_cb->mac_cb->phy_node; ae_handle->if_support = vf_cb->mac_cb->if_support; ae_handle->port_type = vf_cb->mac_cb->mac_type; - ae_handle->dport_id = port_idx; + ae_handle->dport_id = port_id; return ae_handle; vf_id_err: @@ -320,11 +284,8 @@ static void hns_ae_reset(struct hnae_handle *handle) struct hnae_vf_cb *vf_cb = hns_ae_get_vf_cb(handle); if (vf_cb->mac_cb->mac_type == HNAE_PORT_DEBUG) { - u8 ppe_common_index = - vf_cb->port_index - DSAF_SERVICE_PORT_NUM_PER_DSAF + 1; - hns_mac_reset(vf_cb->mac_cb); - hns_ppe_reset_common(vf_cb->dsaf_dev, ppe_common_index); + hns_ppe_reset_common(vf_cb->dsaf_dev, 0); } } @@ -399,11 +360,16 @@ static void hns_ae_get_ring_bdnum_limit(struct hnae_queue *queue, static void hns_ae_get_pauseparam(struct hnae_handle *handle, u32 *auto_neg, u32 *rx_en, u32 *tx_en) { - assert(handle); + struct hns_mac_cb *mac_cb = hns_get_mac_cb(handle); + struct dsaf_device *dsaf_dev = mac_cb->dsaf_dev; + + hns_mac_get_autoneg(mac_cb, auto_neg); - hns_mac_get_autoneg(hns_get_mac_cb(handle), auto_neg); + hns_mac_get_pauseparam(mac_cb, rx_en, tx_en); - hns_mac_get_pauseparam(hns_get_mac_cb(handle), rx_en, tx_en); + /* Service port's pause feature is provided by DSAF, not mac */ + if (handle->port_type == HNAE_PORT_SERVICE) + hns_dsaf_get_rx_mac_pause_en(dsaf_dev, mac_cb->mac_id, rx_en); } static int hns_ae_set_autoneg(struct hnae_handle *handle, u8 enable) @@ -436,12 +402,21 @@ static int hns_ae_set_pauseparam(struct hnae_handle *handle, u32 autoneg, u32 rx_en, u32 tx_en) { struct hns_mac_cb *mac_cb = hns_get_mac_cb(handle); + struct dsaf_device *dsaf_dev = mac_cb->dsaf_dev; int ret; ret = hns_mac_set_autoneg(mac_cb, autoneg); if (ret) return ret; + /* Service port's pause feature is provided by DSAF, not mac */ + if (handle->port_type == HNAE_PORT_SERVICE) { + ret = hns_dsaf_set_rx_mac_pause_en(dsaf_dev, + mac_cb->mac_id, rx_en); + if (ret) + return ret; + rx_en = 0; + } return hns_mac_set_pauseparam(mac_cb, rx_en, tx_en); } @@ -689,7 +664,7 @@ void hns_ae_update_led_status(struct hnae_handle *handle) assert(handle); mac_cb = hns_get_mac_cb(handle); - if (!mac_cb->cpld_vaddr) + if (!mac_cb->cpld_ctrl) return; hns_set_led_opt(mac_cb); } @@ -709,7 +684,6 @@ int hns_ae_cpld_set_led_id(struct hnae_handle *handle, void hns_ae_get_regs(struct hnae_handle *handle, void *data) { u32 *p = data; - u32 rcb_com_idx; int i; struct hnae_vf_cb *vf_cb = hns_ae_get_vf_cb(handle); struct hns_ppe_cb *ppe_cb = hns_get_ppe_cb(handle); @@ -717,8 +691,7 @@ void hns_ae_get_regs(struct hnae_handle *handle, void *data) hns_ppe_get_regs(ppe_cb, p); p += hns_ppe_get_regs_count(); - rcb_com_idx = hns_dsaf_get_comm_idx_by_port(vf_cb->port_index); - hns_rcb_get_common_regs(vf_cb->dsaf_dev->rcb_common[rcb_com_idx], p); + hns_rcb_get_common_regs(vf_cb->dsaf_dev->rcb_common[0], p); p += hns_rcb_get_common_regs_count(); for (i = 0; i < handle->q_num; i++) { diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c index a38084a22bf2..611581fccf2a 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c @@ -7,18 +7,19 @@ * (at your option) any later version. */ -#include <linux/module.h> -#include <linux/kernel.h> #include <linux/init.h> -#include <linux/netdevice.h> -#include <linux/phy_fixed.h> #include <linux/interrupt.h> -#include <linux/platform_device.h> +#include <linux/kernel.h> +#include <linux/mfd/syscon.h> +#include <linux/module.h> +#include <linux/netdevice.h> #include <linux/of.h> #include <linux/of_address.h> +#include <linux/phy_fixed.h> +#include <linux/platform_device.h> -#include "hns_dsaf_misc.h" #include "hns_dsaf_main.h" +#include "hns_dsaf_misc.h" #include "hns_dsaf_rcb.h" #define MAC_EN_FLAG_V 0xada0328 @@ -81,17 +82,6 @@ static enum mac_mode hns_get_enet_interface(const struct hns_mac_cb *mac_cb) } } -int hns_mac_get_sfp_prsnt(struct hns_mac_cb *mac_cb, int *sfp_prsnt) -{ - if (!mac_cb->cpld_vaddr) - return -ENODEV; - - *sfp_prsnt = !dsaf_read_b((u8 *)mac_cb->cpld_vaddr - + MAC_SFP_PORT_OFFSET); - - return 0; -} - void hns_mac_get_link_status(struct hns_mac_cb *mac_cb, u32 *link_status) { struct mac_driver *mac_ctrl_drv; @@ -168,10 +158,9 @@ static int hns_mac_get_inner_port_num(struct hns_mac_cb *mac_cb, u8 vmid, u8 *port_num) { u8 tmp_port; - u32 comm_idx; if (mac_cb->dsaf_dev->dsaf_mode <= DSAF_MODE_ENABLE) { - if (mac_cb->mac_id != DSAF_MAX_PORT_NUM_PER_CHIP) { + if (mac_cb->mac_id != DSAF_MAX_PORT_NUM) { dev_err(mac_cb->dev, "input invalid,%s mac%d vmid%d !\n", mac_cb->dsaf_dev->ae_dev.name, @@ -179,7 +168,7 @@ static int hns_mac_get_inner_port_num(struct hns_mac_cb *mac_cb, return -EINVAL; } } else if (mac_cb->dsaf_dev->dsaf_mode < DSAF_MODE_MAX) { - if (mac_cb->mac_id >= DSAF_MAX_PORT_NUM_PER_CHIP) { + if (mac_cb->mac_id >= DSAF_MAX_PORT_NUM) { dev_err(mac_cb->dev, "input invalid,%s mac%d vmid%d!\n", mac_cb->dsaf_dev->ae_dev.name, @@ -192,9 +181,7 @@ static int hns_mac_get_inner_port_num(struct hns_mac_cb *mac_cb, return -EINVAL; } - comm_idx = hns_dsaf_get_comm_idx_by_port(mac_cb->mac_id); - - if (vmid >= mac_cb->dsaf_dev->rcb_common[comm_idx]->max_vfn) { + if (vmid >= mac_cb->dsaf_dev->rcb_common[0]->max_vfn) { dev_err(mac_cb->dev, "input invalid,%s mac%d vmid%d !\n", mac_cb->dsaf_dev->ae_dev.name, mac_cb->mac_id, vmid); return -EINVAL; @@ -234,7 +221,7 @@ static int hns_mac_get_inner_port_num(struct hns_mac_cb *mac_cb, } /** - *hns_mac_get_inner_port_num - change vf mac address + *hns_mac_change_vf_addr - change vf mac address *@mac_cb: mac device *@vmid: vmid *@addr:mac address @@ -249,7 +236,7 @@ int hns_mac_change_vf_addr(struct hns_mac_cb *mac_cb, struct mac_entry_idx *old_entry; old_entry = &mac_cb->addr_entry_idx[vmid]; - if (dsaf_dev) { + if (!HNS_DSAF_IS_DEBUG(dsaf_dev)) { memcpy(mac_entry.addr, addr, sizeof(mac_entry.addr)); mac_entry.in_vlan_id = old_entry->vlan_id; mac_entry.in_port_num = mac_cb->mac_id; @@ -289,7 +276,7 @@ int hns_mac_set_multi(struct hns_mac_cb *mac_cb, struct dsaf_device *dsaf_dev = mac_cb->dsaf_dev; struct dsaf_drv_mac_single_dest_entry mac_entry; - if (dsaf_dev && addr) { + if (!HNS_DSAF_IS_DEBUG(dsaf_dev) && addr) { memcpy(mac_entry.addr, addr, sizeof(mac_entry.addr)); mac_entry.in_vlan_id = 0;/*vlan_id;*/ mac_entry.in_port_num = mac_cb->mac_id; @@ -380,7 +367,7 @@ static int hns_mac_port_config_bc_en(struct hns_mac_cb *mac_cb, if (mac_cb->mac_type == HNAE_PORT_DEBUG) return 0; - if (dsaf_dev) { + if (!HNS_DSAF_IS_DEBUG(dsaf_dev)) { memcpy(mac_entry.addr, addr, sizeof(mac_entry.addr)); mac_entry.in_vlan_id = vlan_id; mac_entry.in_port_num = mac_cb->mac_id; @@ -418,7 +405,7 @@ int hns_mac_vm_config_bc_en(struct hns_mac_cb *mac_cb, u32 vmid, bool enable) uc_mac_entry = &mac_cb->addr_entry_idx[vmid]; - if (dsaf_dev) { + if (!HNS_DSAF_IS_DEBUG(dsaf_dev)) { memcpy(mac_entry.addr, addr, sizeof(mac_entry.addr)); mac_entry.in_vlan_id = uc_mac_entry->vlan_id; mac_entry.in_port_num = mac_cb->mac_id; @@ -439,9 +426,8 @@ int hns_mac_vm_config_bc_en(struct hns_mac_cb *mac_cb, u32 vmid, bool enable) void hns_mac_reset(struct hns_mac_cb *mac_cb) { - struct mac_driver *drv; - - drv = hns_mac_get_drv(mac_cb); + struct mac_driver *drv = hns_mac_get_drv(mac_cb); + bool is_ver1 = AE_IS_VER1(mac_cb->dsaf_dev->dsaf_ver); drv->mac_init(drv); @@ -456,7 +442,7 @@ void hns_mac_reset(struct hns_mac_cb *mac_cb) if (drv->mac_pausefrm_cfg) { if (mac_cb->mac_type == HNAE_PORT_DEBUG) - drv->mac_pausefrm_cfg(drv, 0, 0); + drv->mac_pausefrm_cfg(drv, !is_ver1, !is_ver1); else /* mac rx must disable, dsaf pfc close instead of it*/ drv->mac_pausefrm_cfg(drv, 0, 1); } @@ -561,14 +547,6 @@ void hns_mac_get_pauseparam(struct hns_mac_cb *mac_cb, u32 *rx_en, u32 *tx_en) *rx_en = 0; *tx_en = 0; } - - /* Due to the chip defect, the service mac's rx pause CAN'T be enabled. - * We set the rx pause frm always be true (1), because DSAF deals with - * the rx pause frm instead of service mac. After all, we still support - * rx pause frm. - */ - if (mac_cb->mac_type == HNAE_PORT_SERVICE) - *rx_en = 1; } /** @@ -602,20 +580,13 @@ int hns_mac_set_autoneg(struct hns_mac_cb *mac_cb, u8 enable) int hns_mac_set_pauseparam(struct hns_mac_cb *mac_cb, u32 rx_en, u32 tx_en) { struct mac_driver *mac_ctrl_drv = hns_mac_get_drv(mac_cb); + bool is_ver1 = AE_IS_VER1(mac_cb->dsaf_dev->dsaf_ver); - if (mac_cb->mac_type == HNAE_PORT_SERVICE) { - if (!rx_en) { - dev_err(mac_cb->dev, "disable rx_pause is not allowed!"); + if (mac_cb->mac_type == HNAE_PORT_DEBUG) { + if (is_ver1 && (tx_en || rx_en)) { + dev_err(mac_cb->dev, "macv1 cann't enable tx/rx_pause!"); return -EINVAL; } - } else if (mac_cb->mac_type == HNAE_PORT_DEBUG) { - if (tx_en || rx_en) { - dev_err(mac_cb->dev, "enable tx_pause or enable rx_pause are not allowed!"); - return -EINVAL; - } - } else { - dev_err(mac_cb->dev, "Unsupport this operation!"); - return -EINVAL; } if (mac_ctrl_drv->mac_pausefrm_cfg) @@ -667,14 +638,18 @@ free_mac_drv: } /** - *mac_free_dev - get mac information from device node + *hns_mac_get_info - get mac information from device node *@mac_cb: mac device *@np:device node - *@mac_mode_idx:mac mode index + * return: 0 --success, negative --fail */ -static void hns_mac_get_info(struct hns_mac_cb *mac_cb, - struct device_node *np, u32 mac_mode_idx) +static int hns_mac_get_info(struct hns_mac_cb *mac_cb) { + struct device_node *np = mac_cb->dev->of_node; + struct regmap *syscon; + struct of_phandle_args cpld_args; + u32 ret; + mac_cb->link = false; mac_cb->half_duplex = false; mac_cb->speed = mac_phy_to_speed[mac_cb->phy_if]; @@ -690,12 +665,73 @@ static void hns_mac_get_info(struct hns_mac_cb *mac_cb, mac_cb->max_frm = MAC_DEFAULT_MTU; mac_cb->tx_pause_frm_time = MAC_DEFAULT_PAUSE_TIME; + mac_cb->port_rst_off = mac_cb->mac_id; + mac_cb->port_mode_off = 0; - /* Get the rest of the PHY information */ - mac_cb->phy_node = of_parse_phandle(np, "phy-handle", mac_cb->mac_id); + /* if the dsaf node doesn't contain a port subnode, get phy-handle + * from dsaf node + */ + if (!mac_cb->fw_port) { + mac_cb->phy_node = of_parse_phandle(np, "phy-handle", + mac_cb->mac_id); + if (mac_cb->phy_node) + dev_dbg(mac_cb->dev, "mac%d phy_node: %s\n", + mac_cb->mac_id, mac_cb->phy_node->name); + return 0; + } + if (!is_of_node(mac_cb->fw_port)) + return -EINVAL; + /* parse property from port subnode in dsaf */ + mac_cb->phy_node = of_parse_phandle(to_of_node(mac_cb->fw_port), + "phy-handle", 0); if (mac_cb->phy_node) dev_dbg(mac_cb->dev, "mac%d phy_node: %s\n", mac_cb->mac_id, mac_cb->phy_node->name); + syscon = syscon_node_to_regmap( + of_parse_phandle(to_of_node(mac_cb->fw_port), + "serdes-syscon", 0)); + if (IS_ERR_OR_NULL(syscon)) { + dev_err(mac_cb->dev, "serdes-syscon is needed!\n"); + return -EINVAL; + } + mac_cb->serdes_ctrl = syscon; + + ret = fwnode_property_read_u32(mac_cb->fw_port, + "port-rst-offset", + &mac_cb->port_rst_off); + if (ret) { + dev_dbg(mac_cb->dev, + "mac%d port-rst-offset not found, use default value.\n", + mac_cb->mac_id); + } + + ret = fwnode_property_read_u32(mac_cb->fw_port, + "port-mode-offset", + &mac_cb->port_mode_off); + if (ret) { + dev_dbg(mac_cb->dev, + "mac%d port-mode-offset not found, use default value.\n", + mac_cb->mac_id); + } + + ret = of_parse_phandle_with_fixed_args(to_of_node(mac_cb->fw_port), + "cpld-syscon", 1, 0, &cpld_args); + if (ret) { + dev_dbg(mac_cb->dev, "mac%d no cpld-syscon found.\n", + mac_cb->mac_id); + mac_cb->cpld_ctrl = NULL; + } else { + syscon = syscon_node_to_regmap(cpld_args.np); + if (IS_ERR_OR_NULL(syscon)) { + dev_dbg(mac_cb->dev, "no cpld-syscon found!\n"); + mac_cb->cpld_ctrl = NULL; + } else { + mac_cb->cpld_ctrl = syscon; + mac_cb->cpld_ctrl_reg = cpld_args.args[0]; + } + } + + return 0; } /** @@ -725,40 +761,31 @@ u8 __iomem *hns_mac_get_vaddr(struct dsaf_device *dsaf_dev, return base + 0x40000 + mac_id * 0x4000 - mac_mode_idx * 0x20000; else - return mac_cb->serdes_vaddr + 0x1000 - + (mac_id - DSAF_SERVICE_PORT_NUM_PER_DSAF) * 0x100000; + return dsaf_dev->ppe_base + 0x1000; } /** * hns_mac_get_cfg - get mac cfg from dtb or acpi table * @dsaf_dev: dsa fabric device struct pointer - * @mac_idx: mac index - * retuen 0 - success , negative --fail + * @mac_cb: mac control block + * return 0 - success , negative --fail */ -int hns_mac_get_cfg(struct dsaf_device *dsaf_dev, int mac_idx) +int hns_mac_get_cfg(struct dsaf_device *dsaf_dev, struct hns_mac_cb *mac_cb) { int ret; u32 mac_mode_idx; - struct hns_mac_cb *mac_cb = &dsaf_dev->mac_cb[mac_idx]; mac_cb->dsaf_dev = dsaf_dev; mac_cb->dev = dsaf_dev->dev; - mac_cb->mac_id = mac_idx; mac_cb->sys_ctl_vaddr = dsaf_dev->sc_base; mac_cb->serdes_vaddr = dsaf_dev->sds_base; - if (dsaf_dev->cpld_base && - mac_idx < DSAF_SERVICE_PORT_NUM_PER_DSAF) { - mac_cb->cpld_vaddr = dsaf_dev->cpld_base + - mac_cb->mac_id * CPLD_ADDR_PORT_OFFSET; - cpld_led_reset(mac_cb); - } mac_cb->sfp_prsnt = 0; mac_cb->txpkt_for_led = 0; mac_cb->rxpkt_for_led = 0; - if (mac_idx < DSAF_SERVICE_PORT_NUM_PER_DSAF) + if (!HNS_DSAF_IS_DEBUG(dsaf_dev)) mac_cb->mac_type = HNAE_PORT_SERVICE; else mac_cb->mac_type = HNAE_PORT_DEBUG; @@ -774,53 +801,100 @@ int hns_mac_get_cfg(struct dsaf_device *dsaf_dev, int mac_idx) } mac_mode_idx = (u32)ret; - hns_mac_get_info(mac_cb, mac_cb->dev->of_node, mac_mode_idx); + ret = hns_mac_get_info(mac_cb); + if (ret) + return ret; + cpld_led_reset(mac_cb); mac_cb->vaddr = hns_mac_get_vaddr(dsaf_dev, mac_cb, mac_mode_idx); return 0; } +static int hns_mac_get_max_port_num(struct dsaf_device *dsaf_dev) +{ + if (HNS_DSAF_IS_DEBUG(dsaf_dev)) + return 1; + else + return DSAF_MAX_PORT_NUM; +} + /** * hns_mac_init - init mac * @dsaf_dev: dsa fabric device struct pointer - * retuen 0 - success , negative --fail + * return 0 - success , negative --fail */ int hns_mac_init(struct dsaf_device *dsaf_dev) { - int i; + bool found = false; int ret; - size_t size; + u32 port_id; + int max_port_num = hns_mac_get_max_port_num(dsaf_dev); struct hns_mac_cb *mac_cb; + struct fwnode_handle *child; - size = sizeof(struct hns_mac_cb) * DSAF_MAX_PORT_NUM_PER_CHIP; - dsaf_dev->mac_cb = devm_kzalloc(dsaf_dev->dev, size, GFP_KERNEL); - if (!dsaf_dev->mac_cb) - return -ENOMEM; + device_for_each_child_node(dsaf_dev->dev, child) { + ret = fwnode_property_read_u32(child, "reg", &port_id); + if (ret) { + dev_err(dsaf_dev->dev, + "get reg fail, ret=%d!\n", ret); + return ret; + } + if (port_id >= max_port_num) { + dev_err(dsaf_dev->dev, + "reg(%u) out of range!\n", port_id); + return -EINVAL; + } + mac_cb = devm_kzalloc(dsaf_dev->dev, sizeof(*mac_cb), + GFP_KERNEL); + if (!mac_cb) + return -ENOMEM; + mac_cb->fw_port = child; + mac_cb->mac_id = (u8)port_id; + dsaf_dev->mac_cb[port_id] = mac_cb; + found = true; + } - for (i = 0; i < DSAF_MAX_PORT_NUM_PER_CHIP; i++) { - ret = hns_mac_get_cfg(dsaf_dev, i); - if (ret) - goto free_mac_cb; + /* if don't get any port subnode from dsaf node + * will init all port then, this is compatible with the old dts + */ + if (!found) { + for (port_id = 0; port_id < max_port_num; port_id++) { + mac_cb = devm_kzalloc(dsaf_dev->dev, sizeof(*mac_cb), + GFP_KERNEL); + if (!mac_cb) + return -ENOMEM; + + mac_cb->mac_id = port_id; + dsaf_dev->mac_cb[port_id] = mac_cb; + } + } + /* init mac_cb for all port */ + for (port_id = 0; port_id < max_port_num; port_id++) { + mac_cb = dsaf_dev->mac_cb[port_id]; + if (!mac_cb) + continue; - mac_cb = &dsaf_dev->mac_cb[i]; + ret = hns_mac_get_cfg(dsaf_dev, mac_cb); + if (ret) + return ret; ret = hns_mac_init_ex(mac_cb); if (ret) - goto free_mac_cb; + return ret; } return 0; - -free_mac_cb: - dsaf_dev->mac_cb = NULL; - - return ret; } void hns_mac_uninit(struct dsaf_device *dsaf_dev) { - cpld_led_reset(dsaf_dev->mac_cb); - dsaf_dev->mac_cb = NULL; + int i; + int max_port_num = hns_mac_get_max_port_num(dsaf_dev); + + for (i = 0; i < max_port_num; i++) { + cpld_led_reset(dsaf_dev->mac_cb[i]); + dsaf_dev->mac_cb[i] = NULL; + } } int hns_mac_config_mac_loopback(struct hns_mac_cb *mac_cb, @@ -908,7 +982,7 @@ void hns_set_led_opt(struct hns_mac_cb *mac_cb) int hns_cpld_led_set_id(struct hns_mac_cb *mac_cb, enum hnae_led_state status) { - if (!mac_cb || !mac_cb->cpld_vaddr) + if (!mac_cb || !mac_cb->cpld_ctrl) return 0; return cpld_set_led_id(mac_cb, status); diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h index 823b6e78c8aa..97ce9a750aaf 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h @@ -10,9 +10,10 @@ #ifndef _HNS_DSAF_MAC_H #define _HNS_DSAF_MAC_H -#include <linux/phy.h> -#include <linux/kernel.h> #include <linux/if_vlan.h> +#include <linux/kernel.h> +#include <linux/phy.h> +#include <linux/regmap.h> #include "hns_dsaf_main.h" struct dsaf_device; @@ -310,10 +311,15 @@ struct hns_mac_cb { struct device *dev; struct dsaf_device *dsaf_dev; struct mac_priv priv; + struct fwnode_handle *fw_port; u8 __iomem *vaddr; - u8 __iomem *cpld_vaddr; u8 __iomem *sys_ctl_vaddr; u8 __iomem *serdes_vaddr; + struct regmap *serdes_ctrl; + struct regmap *cpld_ctrl; + u32 cpld_ctrl_reg; + u32 port_rst_off; + u32 port_mode_off; struct mac_entry_idx addr_entry_idx[DSAF_MAX_VM_NUM]; u8 sfp_prsnt; u8 cpld_led_value; diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c index 5978a5c8ef35..1c2ddb25e776 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c @@ -7,27 +7,29 @@ * (at your option) any later version. */ -#include <linux/module.h> -#include <linux/kernel.h> +#include <linux/device.h> #include <linux/init.h> #include <linux/interrupt.h> +#include <linux/kernel.h> +#include <linux/module.h> #include <linux/netdevice.h> -#include <linux/platform_device.h> +#include <linux/mfd/syscon.h> #include <linux/of.h> #include <linux/of_address.h> #include <linux/of_irq.h> -#include <linux/device.h> +#include <linux/platform_device.h> #include <linux/vmalloc.h> +#include "hns_dsaf_mac.h" #include "hns_dsaf_main.h" -#include "hns_dsaf_rcb.h" #include "hns_dsaf_ppe.h" -#include "hns_dsaf_mac.h" +#include "hns_dsaf_rcb.h" const char *g_dsaf_mode_match[DSAF_MODE_MAX] = { [DSAF_MODE_DISABLE_2PORT_64VM] = "2port-64vf", [DSAF_MODE_DISABLE_6PORT_0VM] = "6port-16rss", [DSAF_MODE_DISABLE_6PORT_16VM] = "6port-16vf", + [DSAF_MODE_DISABLE_SP] = "single-port", }; int hns_dsaf_get_cfg(struct dsaf_device *dsaf_dev) @@ -35,8 +37,13 @@ int hns_dsaf_get_cfg(struct dsaf_device *dsaf_dev) int ret, i; u32 desc_num; u32 buf_size; + u32 reset_offset = 0; + u32 res_idx = 0; const char *mode_str; + struct regmap *syscon; + struct resource *res; struct device_node *np = dsaf_dev->dev->of_node; + struct platform_device *pdev = to_platform_device(dsaf_dev->dev); if (of_device_is_compatible(np, "hisilicon,hns-dsaf-v1")) dsaf_dev->dsaf_ver = AE_VERSION_1; @@ -73,42 +80,68 @@ int hns_dsaf_get_cfg(struct dsaf_device *dsaf_dev) else dsaf_dev->dsaf_tc_mode = HRD_DSAF_4TC_MODE; - dsaf_dev->sc_base = of_iomap(np, 0); - if (!dsaf_dev->sc_base) { - dev_err(dsaf_dev->dev, - "%s of_iomap 0 fail!\n", dsaf_dev->ae_dev.name); - ret = -ENOMEM; - goto unmap_base_addr; - } + syscon = syscon_node_to_regmap( + of_parse_phandle(np, "subctrl-syscon", 0)); + if (IS_ERR_OR_NULL(syscon)) { + res = platform_get_resource(pdev, IORESOURCE_MEM, res_idx++); + if (!res) { + dev_err(dsaf_dev->dev, "subctrl info is needed!\n"); + return -ENOMEM; + } + dsaf_dev->sc_base = devm_ioremap_resource(&pdev->dev, res); + if (!dsaf_dev->sc_base) { + dev_err(dsaf_dev->dev, "subctrl can not map!\n"); + return -ENOMEM; + } - dsaf_dev->sds_base = of_iomap(np, 1); - if (!dsaf_dev->sds_base) { - dev_err(dsaf_dev->dev, - "%s of_iomap 1 fail!\n", dsaf_dev->ae_dev.name); - ret = -ENOMEM; - goto unmap_base_addr; + res = platform_get_resource(pdev, IORESOURCE_MEM, res_idx++); + if (!res) { + dev_err(dsaf_dev->dev, "serdes-ctrl info is needed!\n"); + return -ENOMEM; + } + dsaf_dev->sds_base = devm_ioremap_resource(&pdev->dev, res); + if (!dsaf_dev->sds_base) { + dev_err(dsaf_dev->dev, "serdes-ctrl can not map!\n"); + return -ENOMEM; + } + } else { + dsaf_dev->sub_ctrl = syscon; } - dsaf_dev->ppe_base = of_iomap(np, 2); - if (!dsaf_dev->ppe_base) { - dev_err(dsaf_dev->dev, - "%s of_iomap 2 fail!\n", dsaf_dev->ae_dev.name); - ret = -ENOMEM; - goto unmap_base_addr; + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ppe-base"); + if (!res) { + res = platform_get_resource(pdev, IORESOURCE_MEM, res_idx++); + if (!res) { + dev_err(dsaf_dev->dev, "ppe-base info is needed!\n"); + return -ENOMEM; + } } - - dsaf_dev->io_base = of_iomap(np, 3); - if (!dsaf_dev->io_base) { - dev_err(dsaf_dev->dev, - "%s of_iomap 3 fail!\n", dsaf_dev->ae_dev.name); - ret = -ENOMEM; - goto unmap_base_addr; + dsaf_dev->ppe_base = devm_ioremap_resource(&pdev->dev, res); + if (!dsaf_dev->ppe_base) { + dev_err(dsaf_dev->dev, "ppe-base resource can not map!\n"); + return -ENOMEM; + } + dsaf_dev->ppe_paddr = res->start; + + if (!HNS_DSAF_IS_DEBUG(dsaf_dev)) { + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, + "dsaf-base"); + if (!res) { + res = platform_get_resource(pdev, IORESOURCE_MEM, + res_idx); + if (!res) { + dev_err(dsaf_dev->dev, + "dsaf-base info is needed!\n"); + return -ENOMEM; + } + } + dsaf_dev->io_base = devm_ioremap_resource(&pdev->dev, res); + if (!dsaf_dev->io_base) { + dev_err(dsaf_dev->dev, "dsaf-base resource can not map!\n"); + return -ENOMEM; + } } - dsaf_dev->cpld_base = of_iomap(np, 4); - if (!dsaf_dev->cpld_base) - dev_dbg(dsaf_dev->dev, "NO CPLD ADDR"); - ret = of_property_read_u32(np, "desc-num", &desc_num); if (ret < 0 || desc_num < HNS_DSAF_MIN_DESC_CNT || desc_num > HNS_DSAF_MAX_DESC_CNT) { @@ -118,6 +151,13 @@ int hns_dsaf_get_cfg(struct dsaf_device *dsaf_dev) } dsaf_dev->desc_num = desc_num; + ret = of_property_read_u32(np, "reset-field-offset", &reset_offset); + if (ret < 0) { + dev_dbg(dsaf_dev->dev, + "get reset-field-offset fail, ret=%d!\r\n", ret); + } + dsaf_dev->reset_offset = reset_offset; + ret = of_property_read_u32(np, "buf-size", &buf_size); if (ret < 0) { dev_err(dsaf_dev->dev, @@ -149,8 +189,6 @@ unmap_base_addr: iounmap(dsaf_dev->sds_base); if (dsaf_dev->sc_base) iounmap(dsaf_dev->sc_base); - if (dsaf_dev->cpld_base) - iounmap(dsaf_dev->cpld_base); return ret; } @@ -167,9 +205,6 @@ static void hns_dsaf_free_cfg(struct dsaf_device *dsaf_dev) if (dsaf_dev->sc_base) iounmap(dsaf_dev->sc_base); - - if (dsaf_dev->cpld_base) - iounmap(dsaf_dev->cpld_base); } /** @@ -217,9 +252,7 @@ static void hns_dsaf_mix_def_qid_cfg(struct dsaf_device *dsaf_dev) u32 q_id, q_num_per_port; u32 i; - hns_rcb_get_queue_mode(dsaf_dev->dsaf_mode, - HNS_DSAF_COMM_SERVICE_NW_IDX, - &max_vfn, &max_q_per_vf); + hns_rcb_get_queue_mode(dsaf_dev->dsaf_mode, &max_vfn, &max_q_per_vf); q_num_per_port = max_vfn * max_q_per_vf; for (i = 0, q_id = 0; i < DSAF_SERVICE_NW_NUM; i++) { @@ -239,9 +272,7 @@ static void hns_dsaf_inner_qid_cfg(struct dsaf_device *dsaf_dev) if (AE_IS_VER1(dsaf_dev->dsaf_ver)) return; - hns_rcb_get_queue_mode(dsaf_dev->dsaf_mode, - HNS_DSAF_COMM_SERVICE_NW_IDX, - &max_vfn, &max_q_per_vf); + hns_rcb_get_queue_mode(dsaf_dev->dsaf_mode, &max_vfn, &max_q_per_vf); q_num_per_port = max_vfn * max_q_per_vf; for (mac_id = 0, q_id = 0; mac_id < DSAF_SERVICE_NW_NUM; mac_id++) { @@ -712,13 +743,15 @@ static void hns_dsaf_tbl_tcam_data_ucast_pul( void hns_dsaf_set_promisc_mode(struct dsaf_device *dsaf_dev, u32 en) { - dsaf_set_dev_bit(dsaf_dev, DSAF_CFG_0_REG, DSAF_CFG_MIX_MODE_S, !!en); + if (!HNS_DSAF_IS_DEBUG(dsaf_dev)) + dsaf_set_dev_bit(dsaf_dev, DSAF_CFG_0_REG, + DSAF_CFG_MIX_MODE_S, !!en); } void hns_dsaf_set_inner_lb(struct dsaf_device *dsaf_dev, u32 mac_id, u32 en) { if (AE_IS_VER1(dsaf_dev->dsaf_ver) || - dsaf_dev->mac_cb[mac_id].mac_type == HNAE_PORT_DEBUG) + dsaf_dev->mac_cb[mac_id]->mac_type == HNAE_PORT_DEBUG) return; dsaf_set_dev_bit(dsaf_dev, DSAFV2_SERDES_LBK_0_REG + 4 * mac_id, @@ -1022,12 +1055,52 @@ static void hns_dsaf_tbl_tcam_init(struct dsaf_device *dsaf_dev) * @mac_cb: mac contrl block */ static void hns_dsaf_pfc_en_cfg(struct dsaf_device *dsaf_dev, - int mac_id, int en) + int mac_id, int tc_en) +{ + dsaf_write_dev(dsaf_dev, DSAF_PFC_EN_0_REG + mac_id * 4, tc_en); +} + +static void hns_dsaf_set_pfc_pause(struct dsaf_device *dsaf_dev, + int mac_id, int tx_en, int rx_en) +{ + if (AE_IS_VER1(dsaf_dev->dsaf_ver)) { + if (!tx_en || !rx_en) + dev_err(dsaf_dev->dev, "dsaf v1 can not close pfc!\n"); + + return; + } + + dsaf_set_dev_bit(dsaf_dev, DSAF_PAUSE_CFG_REG + mac_id * 4, + DSAF_PFC_PAUSE_RX_EN_B, !!rx_en); + dsaf_set_dev_bit(dsaf_dev, DSAF_PAUSE_CFG_REG + mac_id * 4, + DSAF_PFC_PAUSE_TX_EN_B, !!tx_en); +} + +int hns_dsaf_set_rx_mac_pause_en(struct dsaf_device *dsaf_dev, int mac_id, + u32 en) { - if (!en) - dsaf_write_dev(dsaf_dev, DSAF_PFC_EN_0_REG + mac_id * 4, 0); + if (AE_IS_VER1(dsaf_dev->dsaf_ver)) { + if (!en) + dev_err(dsaf_dev->dev, "dsafv1 can't close rx_pause!\n"); + + return -EINVAL; + } + + dsaf_set_dev_bit(dsaf_dev, DSAF_PAUSE_CFG_REG + mac_id * 4, + DSAF_MAC_PAUSE_RX_EN_B, !!en); + + return 0; +} + +void hns_dsaf_get_rx_mac_pause_en(struct dsaf_device *dsaf_dev, int mac_id, + u32 *en) +{ + if (AE_IS_VER1(dsaf_dev->dsaf_ver)) + *en = 1; else - dsaf_write_dev(dsaf_dev, DSAF_PFC_EN_0_REG + mac_id * 4, 0xff); + *en = dsaf_get_dev_bit(dsaf_dev, + DSAF_PAUSE_CFG_REG + mac_id * 4, + DSAF_MAC_PAUSE_RX_EN_B); } /** @@ -1039,6 +1112,7 @@ static void hns_dsaf_comm_init(struct dsaf_device *dsaf_dev) { u32 i; u32 o_dsaf_cfg; + bool is_ver1 = AE_IS_VER1(dsaf_dev->dsaf_ver); o_dsaf_cfg = dsaf_read_dev(dsaf_dev, DSAF_CFG_0_REG); dsaf_set_bit(o_dsaf_cfg, DSAF_CFG_EN_S, dsaf_dev->dsaf_en); @@ -1064,8 +1138,10 @@ static void hns_dsaf_comm_init(struct dsaf_device *dsaf_dev) hns_dsaf_sw_port_type_cfg(dsaf_dev, DSAF_SW_PORT_TYPE_NON_VLAN); /*set dsaf pfc to 0 for parseing rx pause*/ - for (i = 0; i < DSAF_COMM_CHN; i++) + for (i = 0; i < DSAF_COMM_CHN; i++) { hns_dsaf_pfc_en_cfg(dsaf_dev, i, 0); + hns_dsaf_set_pfc_pause(dsaf_dev, i, is_ver1, is_ver1); + } /*msk and clr exception irqs */ for (i = 0; i < DSAF_COMM_CHN; i++) { @@ -1264,6 +1340,9 @@ static int hns_dsaf_init(struct dsaf_device *dsaf_dev) u32 i; int ret; + if (HNS_DSAF_IS_DEBUG(dsaf_dev)) + return 0; + ret = hns_dsaf_init_hw(dsaf_dev); if (ret) return ret; @@ -2013,6 +2092,8 @@ void hns_dsaf_update_stats(struct dsaf_device *dsaf_dev, u32 node_num) { struct dsaf_hw_stats *hw_stats = &dsaf_dev->hw_stats[node_num]; + bool is_ver1 = AE_IS_VER1(dsaf_dev->dsaf_ver); + u32 reg_tmp; hw_stats->pad_drop += dsaf_read_dev(dsaf_dev, DSAF_INODE_PAD_DISCARD_NUM_0_REG + 0x80 * (u64)node_num); @@ -2022,8 +2103,12 @@ void hns_dsaf_update_stats(struct dsaf_device *dsaf_dev, u32 node_num) DSAF_INODE_FINAL_IN_PKT_NUM_0_REG + 0x80 * (u64)node_num); hw_stats->rx_pkt_id += dsaf_read_dev(dsaf_dev, DSAF_INODE_SBM_PID_NUM_0_REG + 0x80 * (u64)node_num); - hw_stats->rx_pause_frame += dsaf_read_dev(dsaf_dev, - DSAF_INODE_FINAL_IN_PAUSE_NUM_0_REG + 0x80 * (u64)node_num); + + reg_tmp = is_ver1 ? DSAF_INODE_FINAL_IN_PAUSE_NUM_0_REG : + DSAFV2_INODE_FINAL_IN_PAUSE_NUM_0_REG; + hw_stats->rx_pause_frame += + dsaf_read_dev(dsaf_dev, reg_tmp + 0x80 * (u64)node_num); + hw_stats->release_buf_num += dsaf_read_dev(dsaf_dev, DSAF_INODE_SBM_RELS_NUM_0_REG + 0x80 * (u64)node_num); hw_stats->sbm_drop += dsaf_read_dev(dsaf_dev, @@ -2056,6 +2141,8 @@ void hns_dsaf_get_regs(struct dsaf_device *ddev, u32 port, void *data) u32 i = 0; u32 j; u32 *p = data; + u32 reg_tmp; + bool is_ver1 = AE_IS_VER1(ddev->dsaf_ver); /* dsaf common registers */ p[0] = dsaf_read_dev(ddev, DSAF_SRAM_INIT_OVER_0_REG); @@ -2120,8 +2207,9 @@ void hns_dsaf_get_regs(struct dsaf_device *ddev, u32 port, void *data) DSAF_INODE_FINAL_IN_PKT_NUM_0_REG + j * 0x80); p[190 + i] = dsaf_read_dev(ddev, DSAF_INODE_SBM_PID_NUM_0_REG + j * 0x80); - p[193 + i] = dsaf_read_dev(ddev, - DSAF_INODE_FINAL_IN_PAUSE_NUM_0_REG + j * 0x80); + reg_tmp = is_ver1 ? DSAF_INODE_FINAL_IN_PAUSE_NUM_0_REG : + DSAFV2_INODE_FINAL_IN_PAUSE_NUM_0_REG; + p[193 + i] = dsaf_read_dev(ddev, reg_tmp + j * 0x80); p[196 + i] = dsaf_read_dev(ddev, DSAF_INODE_SBM_RELS_NUM_0_REG + j * 0x80); p[199 + i] = dsaf_read_dev(ddev, @@ -2368,8 +2456,11 @@ void hns_dsaf_get_regs(struct dsaf_device *ddev, u32 port, void *data) p[496] = dsaf_read_dev(ddev, DSAF_NETPORT_CTRL_SIG_0_REG + port * 0x4); p[497] = dsaf_read_dev(ddev, DSAF_XGE_CTRL_SIG_CFG_0_REG + port * 0x4); + if (!is_ver1) + p[498] = dsaf_read_dev(ddev, DSAF_PAUSE_CFG_REG + port * 0x4); + /* mark end of dsaf regs */ - for (i = 498; i < 504; i++) + for (i = 499; i < 504; i++) p[i] = 0xdddddddd; } diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h index 5fea226efaf3..f0502ba0a677 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h @@ -41,6 +41,7 @@ struct hns_mac_cb; #define DSAF_STATIC_NUM 28 #define DSAF_STATS_READ(p, offset) (*((u64 *)((u8 *)(p) + (offset)))) +#define HNS_DSAF_IS_DEBUG(dev) (dev->dsaf_mode == DSAF_MODE_DISABLE_SP) enum hal_dsaf_mode { HRD_DSAF_NO_DSAF_MODE = 0x0, @@ -117,6 +118,7 @@ enum dsaf_mode { DSAF_MODE_ENABLE_32VM, /**< en DSAF-mode, support 32 VM */ DSAF_MODE_ENABLE_128VM, /**< en DSAF-mode, support 128 VM */ DSAF_MODE_ENABLE, /**< before is enable DSAF mode*/ + DSAF_MODE_DISABLE_SP, /* <non-dsaf, single port mode */ DSAF_MODE_DISABLE_FIX, /**< non-dasf, fixed to queue*/ DSAF_MODE_DISABLE_2PORT_8VM, /**< non-dasf, 2port 8VM */ DSAF_MODE_DISABLE_2PORT_16VM, /**< non-dasf, 2port 16VM */ @@ -275,10 +277,12 @@ struct dsaf_device { u8 __iomem *sds_base; u8 __iomem *ppe_base; u8 __iomem *io_base; - u8 __iomem *cpld_base; + struct regmap *sub_ctrl; + phys_addr_t ppe_paddr; u32 desc_num; /* desc num per queue*/ u32 buf_size; /* ring buffer size */ + u32 reset_offset; /* reset field offset in sub sysctrl */ int buf_size_type; /* ring buffer size-type */ enum dsaf_mode dsaf_mode; /* dsaf mode */ enum hal_dsaf_mode dsaf_en; @@ -287,7 +291,7 @@ struct dsaf_device { struct ppe_common_cb *ppe_common[DSAF_COMM_DEV_NUM]; struct rcb_common_cb *rcb_common[DSAF_COMM_DEV_NUM]; - struct hns_mac_cb *mac_cb; + struct hns_mac_cb *mac_cb[DSAF_MAX_PORT_NUM]; struct dsaf_hw_stats hw_stats[DSAF_NODE_NUM]; struct dsaf_int_stat int_stat; @@ -359,14 +363,6 @@ static inline void hns_dsaf_tbl_line_addr_cfg(struct dsaf_device *dsaf_dev, tab_line_addr); } -static inline int hns_dsaf_get_comm_idx_by_port(int port) -{ - if ((port < DSAF_COMM_CHN) || (port == DSAF_MAX_PORT_NUM_PER_CHIP)) - return 0; - else - return (port - DSAF_COMM_CHN + 1); -} - static inline struct hnae_vf_cb *hns_ae_get_vf_cb( struct hnae_handle *handle) { @@ -417,6 +413,11 @@ void hns_dsaf_get_strings(int stringset, u8 *data, int port); void hns_dsaf_get_regs(struct dsaf_device *ddev, u32 port, void *data); int hns_dsaf_get_regs_count(void); void hns_dsaf_set_promisc_mode(struct dsaf_device *dsaf_dev, u32 en); + +void hns_dsaf_get_rx_mac_pause_en(struct dsaf_device *dsaf_dev, int mac_id, + u32 *en); +int hns_dsaf_set_rx_mac_pause_en(struct dsaf_device *dsaf_dev, int mac_id, + u32 en); void hns_dsaf_set_inner_lb(struct dsaf_device *dsaf_dev, u32 mac_id, u32 en); #endif /* __HNS_DSAF_MAIN_H__ */ diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c index e69b02287c44..a837bb9e3839 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c @@ -7,10 +7,30 @@ * (at your option) any later version. */ -#include "hns_dsaf_misc.h" #include "hns_dsaf_mac.h" -#include "hns_dsaf_reg.h" +#include "hns_dsaf_misc.h" #include "hns_dsaf_ppe.h" +#include "hns_dsaf_reg.h" + +static void dsaf_write_sub(struct dsaf_device *dsaf_dev, u32 reg, u32 val) +{ + if (dsaf_dev->sub_ctrl) + dsaf_write_syscon(dsaf_dev->sub_ctrl, reg, val); + else + dsaf_write_reg(dsaf_dev->sc_base, reg, val); +} + +static u32 dsaf_read_sub(struct dsaf_device *dsaf_dev, u32 reg) +{ + u32 ret; + + if (dsaf_dev->sub_ctrl) + ret = dsaf_read_syscon(dsaf_dev->sub_ctrl, reg); + else + ret = dsaf_read_reg(dsaf_dev->sc_base, reg); + + return ret; +} void hns_cpld_set_led(struct hns_mac_cb *mac_cb, int link_status, u16 speed, int data) @@ -22,8 +42,8 @@ void hns_cpld_set_led(struct hns_mac_cb *mac_cb, int link_status, pr_err("sfp_led_opt mac_dev is null!\n"); return; } - if (!mac_cb->cpld_vaddr) { - dev_err(mac_cb->dev, "mac_id=%d, cpld_vaddr is null !\n", + if (!mac_cb->cpld_ctrl) { + dev_err(mac_cb->dev, "mac_id=%d, cpld syscon is null !\n", mac_cb->mac_id); return; } @@ -40,21 +60,24 @@ void hns_cpld_set_led(struct hns_mac_cb *mac_cb, int link_status, dsaf_set_bit(value, DSAF_LED_DATA_B, data); if (value != mac_cb->cpld_led_value) { - dsaf_write_b(mac_cb->cpld_vaddr, value); + dsaf_write_syscon(mac_cb->cpld_ctrl, + mac_cb->cpld_ctrl_reg, value); mac_cb->cpld_led_value = value; } } else { - dsaf_write_b(mac_cb->cpld_vaddr, CPLD_LED_DEFAULT_VALUE); + dsaf_write_syscon(mac_cb->cpld_ctrl, mac_cb->cpld_ctrl_reg, + CPLD_LED_DEFAULT_VALUE); mac_cb->cpld_led_value = CPLD_LED_DEFAULT_VALUE; } } void cpld_led_reset(struct hns_mac_cb *mac_cb) { - if (!mac_cb || !mac_cb->cpld_vaddr) + if (!mac_cb || !mac_cb->cpld_ctrl) return; - dsaf_write_b(mac_cb->cpld_vaddr, CPLD_LED_DEFAULT_VALUE); + dsaf_write_syscon(mac_cb->cpld_ctrl, mac_cb->cpld_ctrl_reg, + CPLD_LED_DEFAULT_VALUE); mac_cb->cpld_led_value = CPLD_LED_DEFAULT_VALUE; } @@ -63,15 +86,19 @@ int cpld_set_led_id(struct hns_mac_cb *mac_cb, { switch (status) { case HNAE_LED_ACTIVE: - mac_cb->cpld_led_value = dsaf_read_b(mac_cb->cpld_vaddr); + mac_cb->cpld_led_value = + dsaf_read_syscon(mac_cb->cpld_ctrl, + mac_cb->cpld_ctrl_reg); dsaf_set_bit(mac_cb->cpld_led_value, DSAF_LED_ANCHOR_B, CPLD_LED_ON_VALUE); - dsaf_write_b(mac_cb->cpld_vaddr, mac_cb->cpld_led_value); + dsaf_write_syscon(mac_cb->cpld_ctrl, mac_cb->cpld_ctrl_reg, + mac_cb->cpld_led_value); return 2; case HNAE_LED_INACTIVE: dsaf_set_bit(mac_cb->cpld_led_value, DSAF_LED_ANCHOR_B, CPLD_LED_DEFAULT_VALUE); - dsaf_write_b(mac_cb->cpld_vaddr, mac_cb->cpld_led_value); + dsaf_write_syscon(mac_cb->cpld_ctrl, mac_cb->cpld_ctrl_reg, + mac_cb->cpld_led_value); break; default: break; @@ -95,10 +122,8 @@ void hns_dsaf_rst(struct dsaf_device *dsaf_dev, u32 val) nt_reg_addr = DSAF_SUB_SC_NT_RESET_DREQ_REG; } - dsaf_write_reg(dsaf_dev->sc_base, xbar_reg_addr, - RESET_REQ_OR_DREQ); - dsaf_write_reg(dsaf_dev->sc_base, nt_reg_addr, - RESET_REQ_OR_DREQ); + dsaf_write_sub(dsaf_dev, xbar_reg_addr, RESET_REQ_OR_DREQ); + dsaf_write_sub(dsaf_dev, nt_reg_addr, RESET_REQ_OR_DREQ); } void hns_dsaf_xge_srst_by_port(struct dsaf_device *dsaf_dev, u32 port, u32 val) @@ -110,14 +135,14 @@ void hns_dsaf_xge_srst_by_port(struct dsaf_device *dsaf_dev, u32 port, u32 val) return; reg_val |= RESET_REQ_OR_DREQ; - reg_val |= 0x2082082 << port; + reg_val |= 0x2082082 << dsaf_dev->mac_cb[port]->port_rst_off; if (val == 0) reg_addr = DSAF_SUB_SC_XGE_RESET_REQ_REG; else reg_addr = DSAF_SUB_SC_XGE_RESET_DREQ_REG; - dsaf_write_reg(dsaf_dev->sc_base, reg_addr, reg_val); + dsaf_write_sub(dsaf_dev, reg_addr, reg_val); } void hns_dsaf_xge_core_srst_by_port(struct dsaf_device *dsaf_dev, @@ -129,68 +154,63 @@ void hns_dsaf_xge_core_srst_by_port(struct dsaf_device *dsaf_dev, if (port >= DSAF_XGE_NUM) return; - reg_val |= XGMAC_TRX_CORE_SRST_M << port; + reg_val |= XGMAC_TRX_CORE_SRST_M + << dsaf_dev->mac_cb[port]->port_rst_off; if (val == 0) reg_addr = DSAF_SUB_SC_XGE_RESET_REQ_REG; else reg_addr = DSAF_SUB_SC_XGE_RESET_DREQ_REG; - dsaf_write_reg(dsaf_dev->sc_base, reg_addr, reg_val); + dsaf_write_sub(dsaf_dev, reg_addr, reg_val); } void hns_dsaf_ge_srst_by_port(struct dsaf_device *dsaf_dev, u32 port, u32 val) { u32 reg_val_1; u32 reg_val_2; + u32 port_rst_off; if (port >= DSAF_GE_NUM) return; - if (port < DSAF_SERVICE_NW_NUM) { + if (!HNS_DSAF_IS_DEBUG(dsaf_dev)) { reg_val_1 = 0x1 << port; + port_rst_off = dsaf_dev->mac_cb[port]->port_rst_off; /* there is difference between V1 and V2 in register.*/ if (AE_IS_VER1(dsaf_dev->dsaf_ver)) - reg_val_2 = 0x1041041 << port; + reg_val_2 = 0x1041041 << port_rst_off; else - reg_val_2 = 0x2082082 << port; + reg_val_2 = 0x2082082 << port_rst_off; if (val == 0) { - dsaf_write_reg(dsaf_dev->sc_base, - DSAF_SUB_SC_GE_RESET_REQ1_REG, + dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_REQ1_REG, reg_val_1); - dsaf_write_reg(dsaf_dev->sc_base, - DSAF_SUB_SC_GE_RESET_REQ0_REG, + dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_REQ0_REG, reg_val_2); } else { - dsaf_write_reg(dsaf_dev->sc_base, - DSAF_SUB_SC_GE_RESET_DREQ0_REG, + dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_DREQ0_REG, reg_val_2); - dsaf_write_reg(dsaf_dev->sc_base, - DSAF_SUB_SC_GE_RESET_DREQ1_REG, + dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_DREQ1_REG, reg_val_1); } } else { - reg_val_1 = 0x15540 << (port - 6); - reg_val_2 = 0x100 << (port - 6); + reg_val_1 = 0x15540 << dsaf_dev->reset_offset; + reg_val_2 = 0x100 << dsaf_dev->reset_offset; if (val == 0) { - dsaf_write_reg(dsaf_dev->sc_base, - DSAF_SUB_SC_GE_RESET_REQ1_REG, + dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_REQ1_REG, reg_val_1); - dsaf_write_reg(dsaf_dev->sc_base, - DSAF_SUB_SC_PPE_RESET_REQ_REG, + dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_PPE_RESET_REQ_REG, reg_val_2); } else { - dsaf_write_reg(dsaf_dev->sc_base, - DSAF_SUB_SC_GE_RESET_DREQ1_REG, + dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_DREQ1_REG, reg_val_1); - dsaf_write_reg(dsaf_dev->sc_base, - DSAF_SUB_SC_PPE_RESET_DREQ_REG, + dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_PPE_RESET_DREQ_REG, reg_val_2); } } @@ -201,24 +221,23 @@ void hns_ppe_srst_by_port(struct dsaf_device *dsaf_dev, u32 port, u32 val) u32 reg_val = 0; u32 reg_addr; - reg_val |= RESET_REQ_OR_DREQ << port; + reg_val |= RESET_REQ_OR_DREQ << dsaf_dev->mac_cb[port]->port_rst_off; if (val == 0) reg_addr = DSAF_SUB_SC_PPE_RESET_REQ_REG; else reg_addr = DSAF_SUB_SC_PPE_RESET_DREQ_REG; - dsaf_write_reg(dsaf_dev->sc_base, reg_addr, reg_val); + dsaf_write_sub(dsaf_dev, reg_addr, reg_val); } void hns_ppe_com_srst(struct ppe_common_cb *ppe_common, u32 val) { - int comm_index = ppe_common->comm_index; struct dsaf_device *dsaf_dev = ppe_common->dsaf_dev; u32 reg_val; u32 reg_addr; - if (comm_index == HNS_DSAF_COMM_SERVICE_NW_IDX) { + if (!HNS_DSAF_IS_DEBUG(dsaf_dev)) { reg_val = RESET_REQ_OR_DREQ; if (val == 0) reg_addr = DSAF_SUB_SC_RCB_PPE_COM_RESET_REQ_REG; @@ -226,7 +245,7 @@ void hns_ppe_com_srst(struct ppe_common_cb *ppe_common, u32 val) reg_addr = DSAF_SUB_SC_RCB_PPE_COM_RESET_DREQ_REG; } else { - reg_val = 0x100 << (comm_index - 1); + reg_val = 0x100 << dsaf_dev->reset_offset; if (val == 0) reg_addr = DSAF_SUB_SC_PPE_RESET_REQ_REG; @@ -234,7 +253,7 @@ void hns_ppe_com_srst(struct ppe_common_cb *ppe_common, u32 val) reg_addr = DSAF_SUB_SC_PPE_RESET_DREQ_REG; } - dsaf_write_reg(dsaf_dev->sc_base, reg_addr, reg_val); + dsaf_write_sub(dsaf_dev, reg_addr, reg_val); } /** @@ -246,36 +265,45 @@ phy_interface_t hns_mac_get_phy_if(struct hns_mac_cb *mac_cb) { u32 mode; u32 reg; - u32 shift; bool is_ver1 = AE_IS_VER1(mac_cb->dsaf_dev->dsaf_ver); - void __iomem *sys_ctl_vaddr = mac_cb->sys_ctl_vaddr; int mac_id = mac_cb->mac_id; - phy_interface_t phy_if = PHY_INTERFACE_MODE_NA; + phy_interface_t phy_if; - if (is_ver1 && (mac_id >= 6 && mac_id <= 7)) { - phy_if = PHY_INTERFACE_MODE_SGMII; - } else if (mac_id >= 0 && mac_id <= 3) { - reg = is_ver1 ? HNS_MAC_HILINK4_REG : HNS_MAC_HILINK4V2_REG; - mode = dsaf_read_reg(sys_ctl_vaddr, reg); - /* mac_id 0, 1, 2, 3 ---> hilink4 lane 0, 1, 2, 3 */ - shift = is_ver1 ? 0 : mac_id; - if (dsaf_get_bit(mode, shift)) - phy_if = PHY_INTERFACE_MODE_XGMII; + if (is_ver1) { + if (HNS_DSAF_IS_DEBUG(mac_cb->dsaf_dev)) + return PHY_INTERFACE_MODE_SGMII; + + if (mac_id >= 0 && mac_id <= 3) + reg = HNS_MAC_HILINK4_REG; else - phy_if = PHY_INTERFACE_MODE_SGMII; - } else if (mac_id >= 4 && mac_id <= 7) { - reg = is_ver1 ? HNS_MAC_HILINK3_REG : HNS_MAC_HILINK3V2_REG; - mode = dsaf_read_reg(sys_ctl_vaddr, reg); - /* mac_id 4, 5, 6, 7 ---> hilink3 lane 2, 3, 0, 1 */ - shift = is_ver1 ? 0 : mac_id <= 5 ? mac_id - 2 : mac_id - 6; - if (dsaf_get_bit(mode, shift)) - phy_if = PHY_INTERFACE_MODE_XGMII; + reg = HNS_MAC_HILINK3_REG; + } else{ + if (!HNS_DSAF_IS_DEBUG(mac_cb->dsaf_dev) && mac_id <= 3) + reg = HNS_MAC_HILINK4V2_REG; else - phy_if = PHY_INTERFACE_MODE_SGMII; + reg = HNS_MAC_HILINK3V2_REG; } + + mode = dsaf_read_sub(mac_cb->dsaf_dev, reg); + if (dsaf_get_bit(mode, mac_cb->port_mode_off)) + phy_if = PHY_INTERFACE_MODE_XGMII; + else + phy_if = PHY_INTERFACE_MODE_SGMII; + return phy_if; } +int hns_mac_get_sfp_prsnt(struct hns_mac_cb *mac_cb, int *sfp_prsnt) +{ + if (!mac_cb->cpld_ctrl) + return -ENODEV; + + *sfp_prsnt = !dsaf_read_syscon(mac_cb->cpld_ctrl, mac_cb->cpld_ctrl_reg + + MAC_SFP_PORT_OFFSET); + + return 0; +} + /** * hns_mac_config_sds_loopback - set loop back for serdes * @mac_cb: mac control block @@ -312,7 +340,14 @@ int hns_mac_config_sds_loopback(struct hns_mac_cb *mac_cb, u8 en) pr_info("no sfp in this eth\n"); } - dsaf_set_reg_field(base_addr, reg_offset, 1ull << 10, 10, !!en); + if (mac_cb->serdes_ctrl) { + u32 origin = dsaf_read_syscon(mac_cb->serdes_ctrl, reg_offset); + + dsaf_set_field(origin, 1ull << 10, 10, !!en); + dsaf_write_syscon(mac_cb->serdes_ctrl, reg_offset, origin); + } else { + dsaf_set_reg_field(base_addr, reg_offset, 1ull << 10, 10, !!en); + } return 0; } diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c index 5b7ae5ff43e8..8cd151a5245e 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c @@ -61,22 +61,10 @@ void hns_ppe_set_indir_table(struct hns_ppe_cb *ppe_cb, } } -static void __iomem *hns_ppe_common_get_ioaddr( - struct ppe_common_cb *ppe_common) +static void __iomem * +hns_ppe_common_get_ioaddr(struct ppe_common_cb *ppe_common) { - void __iomem *base_addr; - - int idx = ppe_common->comm_index; - - if (idx == HNS_DSAF_COMM_SERVICE_NW_IDX) - base_addr = ppe_common->dsaf_dev->ppe_base - + PPE_COMMON_REG_OFFSET; - else - base_addr = ppe_common->dsaf_dev->sds_base - + (idx - 1) * HNS_DSAF_DEBUG_NW_REG_OFFSET - + PPE_COMMON_REG_OFFSET; - - return base_addr; + return ppe_common->dsaf_dev->ppe_base + PPE_COMMON_REG_OFFSET; } /** @@ -90,7 +78,7 @@ int hns_ppe_common_get_cfg(struct dsaf_device *dsaf_dev, int comm_index) struct ppe_common_cb *ppe_common; int ppe_num; - if (comm_index == HNS_DSAF_COMM_SERVICE_NW_IDX) + if (!HNS_DSAF_IS_DEBUG(dsaf_dev)) ppe_num = HNS_PPE_SERVICE_NW_ENGINE_NUM; else ppe_num = HNS_PPE_DEBUG_NW_ENGINE_NUM; @@ -103,7 +91,7 @@ int hns_ppe_common_get_cfg(struct dsaf_device *dsaf_dev, int comm_index) ppe_common->ppe_num = ppe_num; ppe_common->dsaf_dev = dsaf_dev; ppe_common->comm_index = comm_index; - if (comm_index == HNS_DSAF_COMM_SERVICE_NW_IDX) + if (!HNS_DSAF_IS_DEBUG(dsaf_dev)) ppe_common->ppe_mode = PPE_COMMON_MODE_SERVICE; else ppe_common->ppe_mode = PPE_COMMON_MODE_DEBUG; @@ -124,32 +112,8 @@ void hns_ppe_common_free_cfg(struct dsaf_device *dsaf_dev, u32 comm_index) static void __iomem *hns_ppe_get_iobase(struct ppe_common_cb *ppe_common, int ppe_idx) { - void __iomem *base_addr; - int common_idx = ppe_common->comm_index; - - if (ppe_common->ppe_mode == PPE_COMMON_MODE_SERVICE) { - base_addr = ppe_common->dsaf_dev->ppe_base + - ppe_idx * PPE_REG_OFFSET; - - } else { - base_addr = ppe_common->dsaf_dev->sds_base + - (common_idx - 1) * HNS_DSAF_DEBUG_NW_REG_OFFSET; - } - - return base_addr; -} - -static int hns_ppe_get_port(struct ppe_common_cb *ppe_common, int idx) -{ - int port; - - if (ppe_common->ppe_mode == PPE_COMMON_MODE_SERVICE) - port = idx; - else - port = HNS_PPE_SERVICE_NW_ENGINE_NUM - + ppe_common->comm_index - 1; - return port; + return ppe_common->dsaf_dev->ppe_base + ppe_idx * PPE_REG_OFFSET; } static void hns_ppe_get_cfg(struct ppe_common_cb *ppe_common) @@ -164,7 +128,6 @@ static void hns_ppe_get_cfg(struct ppe_common_cb *ppe_common) ppe_cb->next = NULL; ppe_cb->ppe_common_cb = ppe_common; ppe_cb->index = i; - ppe_cb->port = hns_ppe_get_port(ppe_common, i); ppe_cb->io_base = hns_ppe_get_iobase(ppe_common, i); ppe_cb->virq = 0; } @@ -318,7 +281,7 @@ static void hns_ppe_exc_irq_en(struct hns_ppe_cb *ppe_cb, int en) static void hns_ppe_init_hw(struct hns_ppe_cb *ppe_cb) { struct ppe_common_cb *ppe_common_cb = ppe_cb->ppe_common_cb; - u32 port = ppe_cb->port; + u32 port = ppe_cb->index; struct dsaf_device *dsaf_dev = ppe_common_cb->dsaf_dev; int i; @@ -332,10 +295,12 @@ static void hns_ppe_init_hw(struct hns_ppe_cb *ppe_cb) /* clr and msk except irq*/ hns_ppe_exc_irq_en(ppe_cb, 0); - if (ppe_common_cb->ppe_mode == PPE_COMMON_MODE_DEBUG) + if (ppe_common_cb->ppe_mode == PPE_COMMON_MODE_DEBUG) { hns_ppe_set_port_mode(ppe_cb, PPE_MODE_GE); - else + dsaf_write_dev(ppe_cb, PPE_CFG_PAUSE_IDLE_CNT_REG, 0); + } else { hns_ppe_set_port_mode(ppe_cb, PPE_MODE_XGE); + } hns_ppe_checksum_hw(ppe_cb, 0xffffffff); hns_ppe_cnt_clr_ce(ppe_cb); @@ -375,7 +340,8 @@ void hns_ppe_uninit_ex(struct ppe_common_cb *ppe_common) u32 i; for (i = 0; i < ppe_common->ppe_num; i++) { - hns_ppe_uninit_hw(&ppe_common->ppe_cb[i]); + if (ppe_common->dsaf_dev->mac_cb[i]) + hns_ppe_uninit_hw(&ppe_common->ppe_cb[i]); memset(&ppe_common->ppe_cb[i], 0, sizeof(struct hns_ppe_cb)); } } @@ -408,8 +374,11 @@ void hns_ppe_reset_common(struct dsaf_device *dsaf_dev, u8 ppe_common_index) if (ret) return; - for (i = 0; i < ppe_common->ppe_num; i++) - hns_ppe_init_hw(&ppe_common->ppe_cb[i]); + for (i = 0; i < ppe_common->ppe_num; i++) { + /* We only need to initiate ppe when the port exists */ + if (dsaf_dev->mac_cb[i]) + hns_ppe_init_hw(&ppe_common->ppe_cb[i]); + } ret = hns_rcb_common_init_hw(dsaf_dev->rcb_common[ppe_common_index]); if (ret) diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.h b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.h index e9c0ec2fa0dd..9d8e643e8aa6 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.h +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.h @@ -80,7 +80,6 @@ struct hns_ppe_cb { struct hns_ppe_hw_stats hw_stats; u8 index; /* index in a ppe common device */ - u8 port; /* port id in dsaf */ void __iomem *io_base; int virq; u32 rss_indir_table[HNS_PPEV2_RSS_IND_TBL_SIZE]; /*shadow indir tab */ diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c index 28ee26e5c478..4ef6d23d998e 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c @@ -270,7 +270,7 @@ static void hns_rcb_set_port_timeout( static int hns_rcb_common_get_port_num(struct rcb_common_cb *rcb_common) { - if (rcb_common->comm_index == HNS_DSAF_COMM_SERVICE_NW_IDX) + if (!HNS_DSAF_IS_DEBUG(rcb_common->dsaf_dev)) return HNS_RCB_SERVICE_NW_ENGINE_NUM; else return HNS_RCB_DEBUG_NW_ENGINE_NUM; @@ -430,36 +430,20 @@ static void hns_rcb_ring_pair_get_cfg(struct ring_pair_cb *ring_pair_cb) static int hns_rcb_get_port_in_comm( struct rcb_common_cb *rcb_common, int ring_idx) { - int comm_index = rcb_common->comm_index; - int port; - int q_num; - if (comm_index == HNS_DSAF_COMM_SERVICE_NW_IDX) { - q_num = (int)rcb_common->max_q_per_vf * rcb_common->max_vfn; - port = ring_idx / q_num; - } else { - port = 0; /* config debug-ports port_id_in_comm to 0*/ - } - - return port; + return ring_idx / (rcb_common->max_q_per_vf * rcb_common->max_vfn); } #define SERVICE_RING_IRQ_IDX(v1) \ ((v1) ? HNS_SERVICE_RING_IRQ_IDX : HNSV2_SERVICE_RING_IRQ_IDX) -#define DEBUG_RING_IRQ_IDX(v1) \ - ((v1) ? HNS_DEBUG_RING_IRQ_IDX : HNSV2_DEBUG_RING_IRQ_IDX) -#define DEBUG_RING_IRQ_OFFSET(v1) \ - ((v1) ? HNS_DEBUG_RING_IRQ_OFFSET : HNSV2_DEBUG_RING_IRQ_OFFSET) static int hns_rcb_get_base_irq_idx(struct rcb_common_cb *rcb_common) { - int comm_index = rcb_common->comm_index; bool is_ver1 = AE_IS_VER1(rcb_common->dsaf_dev->dsaf_ver); - if (comm_index == HNS_DSAF_COMM_SERVICE_NW_IDX) + if (!HNS_DSAF_IS_DEBUG(rcb_common->dsaf_dev)) return SERVICE_RING_IRQ_IDX(is_ver1); else - return DEBUG_RING_IRQ_IDX(is_ver1) + - (comm_index - 1) * DEBUG_RING_IRQ_OFFSET(is_ver1); + return HNS_DEBUG_RING_IRQ_IDX; } #define RCB_COMM_BASE_TO_RING_BASE(base, ringid)\ @@ -549,7 +533,7 @@ int hns_rcb_set_coalesce_usecs( return 0; if (AE_IS_VER1(rcb_common->dsaf_dev->dsaf_ver)) { - if (rcb_common->comm_index == HNS_DSAF_COMM_SERVICE_NW_IDX) { + if (!HNS_DSAF_IS_DEBUG(rcb_common->dsaf_dev)) { dev_err(rcb_common->dsaf_dev->dev, "error: not support coalesce_usecs setting!\n"); return -EINVAL; @@ -601,113 +585,82 @@ int hns_rcb_set_coalesced_frames( *@max_vfn : max vfn number *@max_q_per_vf:max ring number per vm */ -void hns_rcb_get_queue_mode(enum dsaf_mode dsaf_mode, int comm_index, - u16 *max_vfn, u16 *max_q_per_vf) +void hns_rcb_get_queue_mode(enum dsaf_mode dsaf_mode, u16 *max_vfn, + u16 *max_q_per_vf) { - if (comm_index == HNS_DSAF_COMM_SERVICE_NW_IDX) { - switch (dsaf_mode) { - case DSAF_MODE_DISABLE_6PORT_0VM: - *max_vfn = 1; - *max_q_per_vf = 16; - break; - case DSAF_MODE_DISABLE_FIX: - *max_vfn = 1; - *max_q_per_vf = 1; - break; - case DSAF_MODE_DISABLE_2PORT_64VM: - *max_vfn = 64; - *max_q_per_vf = 1; - break; - case DSAF_MODE_DISABLE_6PORT_16VM: - *max_vfn = 16; - *max_q_per_vf = 1; - break; - default: - *max_vfn = 1; - *max_q_per_vf = 16; - break; - } - } else { + switch (dsaf_mode) { + case DSAF_MODE_DISABLE_6PORT_0VM: + *max_vfn = 1; + *max_q_per_vf = 16; + break; + case DSAF_MODE_DISABLE_FIX: + case DSAF_MODE_DISABLE_SP: *max_vfn = 1; *max_q_per_vf = 1; + break; + case DSAF_MODE_DISABLE_2PORT_64VM: + *max_vfn = 64; + *max_q_per_vf = 1; + break; + case DSAF_MODE_DISABLE_6PORT_16VM: + *max_vfn = 16; + *max_q_per_vf = 1; + break; + default: + *max_vfn = 1; + *max_q_per_vf = 16; + break; } } -int hns_rcb_get_ring_num(struct dsaf_device *dsaf_dev, int comm_index) +int hns_rcb_get_ring_num(struct dsaf_device *dsaf_dev) { - if (comm_index == HNS_DSAF_COMM_SERVICE_NW_IDX) { - switch (dsaf_dev->dsaf_mode) { - case DSAF_MODE_ENABLE_FIX: - return 1; - - case DSAF_MODE_DISABLE_FIX: - return 6; - - case DSAF_MODE_ENABLE_0VM: - return 32; - - case DSAF_MODE_DISABLE_6PORT_0VM: - case DSAF_MODE_ENABLE_16VM: - case DSAF_MODE_DISABLE_6PORT_2VM: - case DSAF_MODE_DISABLE_6PORT_16VM: - case DSAF_MODE_DISABLE_6PORT_4VM: - case DSAF_MODE_ENABLE_8VM: - return 96; - - case DSAF_MODE_DISABLE_2PORT_16VM: - case DSAF_MODE_DISABLE_2PORT_8VM: - case DSAF_MODE_ENABLE_32VM: - case DSAF_MODE_DISABLE_2PORT_64VM: - case DSAF_MODE_ENABLE_128VM: - return 128; - - default: - dev_warn(dsaf_dev->dev, - "get ring num fail,use default!dsaf_mode=%d\n", - dsaf_dev->dsaf_mode); - return 128; - } - } else { + switch (dsaf_dev->dsaf_mode) { + case DSAF_MODE_ENABLE_FIX: + case DSAF_MODE_DISABLE_SP: return 1; + + case DSAF_MODE_DISABLE_FIX: + return 6; + + case DSAF_MODE_ENABLE_0VM: + return 32; + + case DSAF_MODE_DISABLE_6PORT_0VM: + case DSAF_MODE_ENABLE_16VM: + case DSAF_MODE_DISABLE_6PORT_2VM: + case DSAF_MODE_DISABLE_6PORT_16VM: + case DSAF_MODE_DISABLE_6PORT_4VM: + case DSAF_MODE_ENABLE_8VM: + return 96; + + case DSAF_MODE_DISABLE_2PORT_16VM: + case DSAF_MODE_DISABLE_2PORT_8VM: + case DSAF_MODE_ENABLE_32VM: + case DSAF_MODE_DISABLE_2PORT_64VM: + case DSAF_MODE_ENABLE_128VM: + return 128; + + default: + dev_warn(dsaf_dev->dev, + "get ring num fail,use default!dsaf_mode=%d\n", + dsaf_dev->dsaf_mode); + return 128; } } -void __iomem *hns_rcb_common_get_vaddr(struct dsaf_device *dsaf_dev, - int comm_index) +void __iomem *hns_rcb_common_get_vaddr(struct rcb_common_cb *rcb_common) { - void __iomem *base_addr; - - if (comm_index == HNS_DSAF_COMM_SERVICE_NW_IDX) - base_addr = dsaf_dev->ppe_base + RCB_COMMON_REG_OFFSET; - else - base_addr = dsaf_dev->sds_base - + (comm_index - 1) * HNS_DSAF_DEBUG_NW_REG_OFFSET - + RCB_COMMON_REG_OFFSET; + struct dsaf_device *dsaf_dev = rcb_common->dsaf_dev; - return base_addr; + return dsaf_dev->ppe_base + RCB_COMMON_REG_OFFSET; } -static phys_addr_t hns_rcb_common_get_paddr(struct dsaf_device *dsaf_dev, - int comm_index) +static phys_addr_t hns_rcb_common_get_paddr(struct rcb_common_cb *rcb_common) { - struct device_node *np = dsaf_dev->dev->of_node; - phys_addr_t phy_addr; - const __be32 *tmp_addr; - u64 addr_offset = 0; - u64 size = 0; - int index = 0; - - if (comm_index == HNS_DSAF_COMM_SERVICE_NW_IDX) { - index = 2; - addr_offset = RCB_COMMON_REG_OFFSET; - } else { - index = 1; - addr_offset = (comm_index - 1) * HNS_DSAF_DEBUG_NW_REG_OFFSET + - RCB_COMMON_REG_OFFSET; - } - tmp_addr = of_get_address(np, index, &size, NULL); - phy_addr = of_translate_address(np, tmp_addr); - return phy_addr + addr_offset; + struct dsaf_device *dsaf_dev = rcb_common->dsaf_dev; + + return dsaf_dev->ppe_paddr + RCB_COMMON_REG_OFFSET; } int hns_rcb_common_get_cfg(struct dsaf_device *dsaf_dev, @@ -717,7 +670,7 @@ int hns_rcb_common_get_cfg(struct dsaf_device *dsaf_dev, enum dsaf_mode dsaf_mode = dsaf_dev->dsaf_mode; u16 max_vfn; u16 max_q_per_vf; - int ring_num = hns_rcb_get_ring_num(dsaf_dev, comm_index); + int ring_num = hns_rcb_get_ring_num(dsaf_dev); rcb_common = devm_kzalloc(dsaf_dev->dev, sizeof(*rcb_common) + @@ -732,12 +685,12 @@ int hns_rcb_common_get_cfg(struct dsaf_device *dsaf_dev, rcb_common->desc_num = dsaf_dev->desc_num; - hns_rcb_get_queue_mode(dsaf_mode, comm_index, &max_vfn, &max_q_per_vf); + hns_rcb_get_queue_mode(dsaf_mode, &max_vfn, &max_q_per_vf); rcb_common->max_vfn = max_vfn; rcb_common->max_q_per_vf = max_q_per_vf; - rcb_common->io_base = hns_rcb_common_get_vaddr(dsaf_dev, comm_index); - rcb_common->phy_base = hns_rcb_common_get_paddr(dsaf_dev, comm_index); + rcb_common->io_base = hns_rcb_common_get_vaddr(rcb_common); + rcb_common->phy_base = hns_rcb_common_get_paddr(rcb_common); dsaf_dev->rcb_common[comm_index] = rcb_common; return 0; @@ -932,7 +885,7 @@ void hns_rcb_get_common_regs(struct rcb_common_cb *rcb_com, void *data) { u32 *regs = data; bool is_ver1 = AE_IS_VER1(rcb_com->dsaf_dev->dsaf_ver); - bool is_dbg = (rcb_com->comm_index != HNS_DSAF_COMM_SERVICE_NW_IDX); + bool is_dbg = HNS_DSAF_IS_DEBUG(rcb_com->dsaf_dev); u32 reg_tmp; u32 reg_num_tmp; u32 i = 0; diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.h b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.h index eb61014ad615..bd54dac82ee0 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.h +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.h @@ -111,7 +111,7 @@ void hns_rcb_common_free_cfg(struct dsaf_device *dsaf_dev, u32 comm_index); int hns_rcb_common_init_hw(struct rcb_common_cb *rcb_common); void hns_rcb_start(struct hnae_queue *q, u32 val); void hns_rcb_get_cfg(struct rcb_common_cb *rcb_common); -void hns_rcb_get_queue_mode(enum dsaf_mode dsaf_mode, int comm_index, +void hns_rcb_get_queue_mode(enum dsaf_mode dsaf_mode, u16 *max_vfn, u16 *max_q_per_vf); void hns_rcb_common_init_commit_hw(struct rcb_common_cb *rcb_common); diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h index 7d7204f45e78..7c3b5103d151 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h @@ -10,25 +10,20 @@ #ifndef _DSAF_REG_H_ #define _DSAF_REG_H_ -#define HNS_DEBUG_RING_IRQ_IDX 55 -#define HNS_SERVICE_RING_IRQ_IDX 59 -#define HNS_DEBUG_RING_IRQ_OFFSET 2 -#define HNSV2_DEBUG_RING_IRQ_IDX 409 -#define HNSV2_SERVICE_RING_IRQ_IDX 25 -#define HNSV2_DEBUG_RING_IRQ_OFFSET 9 - -#define DSAF_MAX_PORT_NUM_PER_CHIP 8 -#define DSAF_SERVICE_PORT_NUM_PER_DSAF 6 -#define DSAF_MAX_VM_NUM 128 - -#define DSAF_COMM_DEV_NUM 3 -#define DSAF_PPE_INODE_BASE 6 -#define HNS_DSAF_COMM_SERVICE_NW_IDX 0 +#include <linux/regmap.h> +#define HNS_DEBUG_RING_IRQ_IDX 0 +#define HNS_SERVICE_RING_IRQ_IDX 59 +#define HNSV2_SERVICE_RING_IRQ_IDX 25 + +#define DSAF_MAX_PORT_NUM 6 +#define DSAF_MAX_VM_NUM 128 + +#define DSAF_COMM_DEV_NUM 1 +#define DSAF_PPE_INODE_BASE 6 #define DSAF_DEBUG_NW_NUM 2 #define DSAF_SERVICE_NW_NUM 6 #define DSAF_COMM_CHN DSAF_SERVICE_NW_NUM #define DSAF_GE_NUM ((DSAF_SERVICE_NW_NUM) + (DSAF_DEBUG_NW_NUM)) -#define DSAF_PORT_NUM ((DSAF_SERVICE_NW_NUM) + (DSAF_DEBUG_NW_NUM)) #define DSAF_XGE_NUM DSAF_SERVICE_NW_NUM #define DSAF_PORT_TYPE_NUM 3 #define DSAF_NODE_NUM 18 @@ -137,6 +132,7 @@ #define DSAF_PPE_INT_STS_0_REG 0x1E0 #define DSAF_ROCEE_INT_STS_0_REG 0x200 #define DSAFV2_SERDES_LBK_0_REG 0x220 +#define DSAF_PAUSE_CFG_REG 0x240 #define DSAF_PPE_QID_CFG_0_REG 0x300 #define DSAF_SW_PORT_TYPE_0_REG 0x320 #define DSAF_STP_PORT_TYPE_0_REG 0x340 @@ -155,6 +151,7 @@ #define DSAF_INODE_FINAL_IN_PKT_NUM_0_REG 0x1030 #define DSAF_INODE_SBM_PID_NUM_0_REG 0x1038 #define DSAF_INODE_FINAL_IN_PAUSE_NUM_0_REG 0x103C +#define DSAFV2_INODE_FINAL_IN_PAUSE_NUM_0_REG 0x1024 #define DSAF_INODE_SBM_RELS_NUM_0_REG 0x104C #define DSAF_INODE_SBM_DROP_NUM_0_REG 0x1050 #define DSAF_INODE_CRC_FALSE_NUM_0_REG 0x1054 @@ -711,6 +708,10 @@ #define DSAF_PFC_UNINT_CNT_M ((1ULL << 9) - 1) #define DSAF_PFC_UNINT_CNT_S 0 +#define DSAF_MAC_PAUSE_RX_EN_B 2 +#define DSAF_PFC_PAUSE_RX_EN_B 1 +#define DSAF_PFC_PAUSE_TX_EN_B 0 + #define DSAF_PPE_QID_CFG_M 0xFF #define DSAF_PPE_QID_CFG_S 0 @@ -988,6 +989,19 @@ static inline u32 dsaf_read_reg(u8 __iomem *base, u32 reg) return readl(reg_addr + reg); } +static inline void dsaf_write_syscon(struct regmap *base, u32 reg, u32 value) +{ + regmap_write(base, reg, value); +} + +static inline u32 dsaf_read_syscon(struct regmap *base, u32 reg) +{ + unsigned int val; + + regmap_read(base, reg, &val); + return val; +} + #define dsaf_read_dev(a, reg) \ dsaf_read_reg((a)->io_base, (reg)) diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.c b/drivers/net/ethernet/hisilicon/hns/hns_enet.c index 687204b780b0..e621636e69b9 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_enet.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c @@ -1275,7 +1275,7 @@ void hns_nic_net_reinit(struct net_device *netdev) { struct hns_nic_priv *priv = netdev_priv(netdev); - priv->netdev->trans_start = jiffies; + netif_trans_update(priv->netdev); while (test_and_set_bit(NIC_STATE_REINITING, &priv->state)) usleep_range(1000, 2000); @@ -1376,7 +1376,7 @@ static netdev_tx_t hns_nic_net_xmit(struct sk_buff *skb, ret = hns_nic_net_xmit_hw(ndev, skb, &tx_ring_data(priv, skb->queue_mapping)); if (ret == NETDEV_TX_OK) { - ndev->trans_start = jiffies; + netif_trans_update(ndev); ndev->stats.tx_bytes += skb->len; ndev->stats.tx_packets++; } @@ -1648,7 +1648,7 @@ static void hns_nic_reset_subtask(struct hns_nic_priv *priv) rtnl_lock(); /* put off any impending NetWatchDogTimeout */ - priv->netdev->trans_start = jiffies; + netif_trans_update(priv->netdev); if (type == HNAE_PORT_DEBUG) { hns_nic_net_reinit(priv->netdev); @@ -1873,6 +1873,7 @@ static int hns_nic_dev_probe(struct platform_device *pdev) struct net_device *ndev; struct hns_nic_priv *priv; struct device_node *node = dev->of_node; + u32 port_id; int ret; ndev = alloc_etherdev_mq(sizeof(struct hns_nic_priv), NIC_MAX_Q_PER_VF); @@ -1896,10 +1897,18 @@ static int hns_nic_dev_probe(struct platform_device *pdev) dev_err(dev, "not find ae-handle\n"); goto out_read_prop_fail; } - - ret = of_property_read_u32(node, "port-id", &priv->port_id); - if (ret) - goto out_read_prop_fail; + /* try to find port-idx-in-ae first */ + ret = of_property_read_u32(node, "port-idx-in-ae", &port_id); + if (ret) { + /* only for old code compatible */ + ret = of_property_read_u32(node, "port-id", &port_id); + if (ret) + goto out_read_prop_fail; + /* for old dts, we need to caculate the port offset */ + port_id = port_id < HNS_SRV_OFFSET ? port_id + HNS_DEBUG_OFFSET + : port_id - HNS_SRV_OFFSET; + } + priv->port_id = port_id; hns_init_mac_addr(ndev); diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.h b/drivers/net/ethernet/hisilicon/hns/hns_enet.h index c68ab3d34fc2..337efa582bac 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_enet.h +++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.h @@ -18,6 +18,9 @@ #include "hnae.h" +#define HNS_DEBUG_OFFSET 6 +#define HNS_SRV_OFFSET 2 + enum hns_nic_state { NIC_STATE_TESTING = 0, NIC_STATE_RESETTING, |