提交 511e6bc0 编写于 作者: H huangdaode 提交者: David S. Miller

net: add Hisilicon Network Subsystem DSAF support

DSAF, namely Distributed System Area Fabric, is one of the HNS
acceleration engine implementation. This patch add DSAF driver to the
system.

hns_ae_adapt: the adaptor for registering the driver to HNAE framework
hns_dsaf_mac: MAC cover interface for GE and XGE
hns_dsaf_gmac: GE (10/100/1000G Ethernet) MAC function
hns_dsaf_xgmac: XGE (10000+G Ethernet) MAC function
hns_dsaf_main: the platform device driver for the whole hardware
hns_dsaf_misc: some misc helper function, such as LED support
hns_dsaf_ppe: packet process engine function
hns_dsaf_rcb: ring buffer function
Signed-off-by: Nhuangdaode <huangdaode@hisilicon.com>
Signed-off-by: NYisen Zhuang <Yisen.Zhuang@huawei.com>
Signed-off-by: NKenneth Lee <liguozhu@huawei.com>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 6fe6611f
......@@ -46,4 +46,13 @@ config HNS
is needed by any driver which provides HNS acceleration engine or make
use of the engine
config HNS_DSAF
tristate "Hisilicon HNS DSAF device Support"
select HNS
select HNS_MDIO
---help---
This selects the DSAF (Distributed System Area Frabric) network
acceleration engine support. The engine is used in Hisilicon hip05,
Hi1610 and further ICT SoC
endif # NET_VENDOR_HISILICON
......@@ -3,3 +3,7 @@
#
obj-$(CONFIG_HNS) += hnae.o
obj-$(CONFIG_HNS_DSAF) += hns_dsaf.o
hns_dsaf-objs = hns_ae_adapt.o hns_dsaf_gmac.o hns_dsaf_mac.o hns_dsaf_misc.o \
hns_dsaf_main.o hns_dsaf_ppe.o hns_dsaf_rcb.o hns_dsaf_xgmac.o
此差异已折叠。
此差异已折叠。
/*
* Copyright (c) 2014-2015 Hisilicon Limited.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#ifndef _HNS_GMAC_H
#define _HNS_GMAC_H
#include "hns_dsaf_mac.h"
enum hns_port_mode {
GMAC_10M_MII = 0,
GMAC_100M_MII,
GMAC_1000M_GMII,
GMAC_10M_RGMII,
GMAC_100M_RGMII,
GMAC_1000M_RGMII,
GMAC_10M_SGMII,
GMAC_100M_SGMII,
GMAC_1000M_SGMII,
GMAC_10000M_SGMII /* 10GE */
};
enum hns_gmac_duplex_mdoe {
GMAC_HALF_DUPLEX_MODE = 0,
GMAC_FULL_DUPLEX_MODE
};
struct hns_gmac_port_mode_cfg {
enum hns_port_mode port_mode;
u32 max_frm_size;
u32 short_runts_thr;
u32 pad_enable;
u32 crc_add;
u32 an_enable; /*auto-nego enable */
u32 runt_pkt_en;
u32 strip_pad_en;
};
#define ETH_GMAC_DUMP_NUM 96
#endif /* __HNS_GMAC_H__ */
此差异已折叠。
/*
* Copyright (c) 2014-2015 Hisilicon Limited.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#ifndef _HNS_DSAF_MAC_H
#define _HNS_DSAF_MAC_H
#include <linux/phy.h>
#include <linux/kernel.h>
#include <linux/if_vlan.h>
#include "hns_dsaf_main.h"
struct dsaf_device;
#define MAC_GMAC_SUPPORTED \
(SUPPORTED_10baseT_Half \
| SUPPORTED_10baseT_Full \
| SUPPORTED_100baseT_Half \
| SUPPORTED_100baseT_Full \
| SUPPORTED_Autoneg)
#define MAC_DEFAULT_MTU (ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN + ETH_DATA_LEN)
#define MAC_MAX_MTU 9600
#define MAC_MIN_MTU 68
#define MAC_DEFAULT_PAUSE_TIME 0xff
#define MAC_GMAC_IDX 0
#define MAC_XGMAC_IDX 1
#define ETH_STATIC_REG 1
#define ETH_DUMP_REG 5
/* check mac addr broadcast */
#define MAC_IS_BROADCAST(p) ((*(p) == 0xff) && (*((p) + 1) == 0xff) && \
(*((p) + 2) == 0xff) && (*((p) + 3) == 0xff) && \
(*((p) + 4) == 0xff) && (*((p) + 5) == 0xff))
/* check mac addr is 01-00-5e-xx-xx-xx*/
#define MAC_IS_L3_MULTICAST(p) ((*((p) + 0) == 0x01) && \
(*((p) + 1) == 0x00) && \
(*((p) + 2) == 0x5e))
/*check the mac addr is 0 in all bit*/
#define MAC_IS_ALL_ZEROS(p) ((*(p) == 0) && (*((p) + 1) == 0) && \
(*((p) + 2) == 0) && (*((p) + 3) == 0) && \
(*((p) + 4) == 0) && (*((p) + 5) == 0))
/*check mac addr multicast*/
#define MAC_IS_MULTICAST(p) ((*((u8 *)((p) + 0)) & 0x01) ? (1) : (0))
/**< Number of octets (8-bit bytes) in an ethernet address */
#define MAC_NUM_OCTETS_PER_ADDR 6
struct mac_priv {
void *mac;
};
/* net speed */
enum mac_speed {
MAC_SPEED_10 = 10, /**< 10 Mbps */
MAC_SPEED_100 = 100, /**< 100 Mbps */
MAC_SPEED_1000 = 1000, /**< 1000 Mbps = 1 Gbps */
MAC_SPEED_10000 = 10000 /**< 10000 Mbps = 10 Gbps */
};
/*mac interface keyword */
enum mac_intf {
MAC_IF_NONE = 0x00000000, /**< interface not invalid */
MAC_IF_MII = 0x00010000, /**< MII interface */
MAC_IF_RMII = 0x00020000, /**< RMII interface */
MAC_IF_SMII = 0x00030000, /**< SMII interface */
MAC_IF_GMII = 0x00040000, /**< GMII interface */
MAC_IF_RGMII = 0x00050000, /**< RGMII interface */
MAC_IF_TBI = 0x00060000, /**< TBI interface */
MAC_IF_RTBI = 0x00070000, /**< RTBI interface */
MAC_IF_SGMII = 0x00080000, /**< SGMII interface */
MAC_IF_XGMII = 0x00090000, /**< XGMII interface */
MAC_IF_QSGMII = 0x000a0000 /**< QSGMII interface */
};
/*mac mode */
enum mac_mode {
/**< Invalid Ethernet mode */
MAC_MODE_INVALID = 0,
/**< 10 Mbps MII */
MAC_MODE_MII_10 = (MAC_IF_MII | MAC_SPEED_10),
/**< 100 Mbps MII */
MAC_MODE_MII_100 = (MAC_IF_MII | MAC_SPEED_100),
/**< 10 Mbps RMII */
MAC_MODE_RMII_10 = (MAC_IF_RMII | MAC_SPEED_10),
/**< 100 Mbps RMII */
MAC_MODE_RMII_100 = (MAC_IF_RMII | MAC_SPEED_100),
/**< 10 Mbps SMII */
MAC_MODE_SMII_10 = (MAC_IF_SMII | MAC_SPEED_10),
/**< 100 Mbps SMII */
MAC_MODE_SMII_100 = (MAC_IF_SMII | MAC_SPEED_100),
/**< 1000 Mbps GMII */
MAC_MODE_GMII_1000 = (MAC_IF_GMII | MAC_SPEED_1000),
/**< 10 Mbps RGMII */
MAC_MODE_RGMII_10 = (MAC_IF_RGMII | MAC_SPEED_10),
/**< 100 Mbps RGMII */
MAC_MODE_RGMII_100 = (MAC_IF_RGMII | MAC_SPEED_100),
/**< 1000 Mbps RGMII */
MAC_MODE_RGMII_1000 = (MAC_IF_RGMII | MAC_SPEED_1000),
/**< 1000 Mbps TBI */
MAC_MODE_TBI_1000 = (MAC_IF_TBI | MAC_SPEED_1000),
/**< 1000 Mbps RTBI */
MAC_MODE_RTBI_1000 = (MAC_IF_RTBI | MAC_SPEED_1000),
/**< 10 Mbps SGMII */
MAC_MODE_SGMII_10 = (MAC_IF_SGMII | MAC_SPEED_10),
/**< 100 Mbps SGMII */
MAC_MODE_SGMII_100 = (MAC_IF_SGMII | MAC_SPEED_100),
/**< 1000 Mbps SGMII */
MAC_MODE_SGMII_1000 = (MAC_IF_SGMII | MAC_SPEED_1000),
/**< 10000 Mbps XGMII */
MAC_MODE_XGMII_10000 = (MAC_IF_XGMII | MAC_SPEED_10000),
/**< 1000 Mbps QSGMII */
MAC_MODE_QSGMII_1000 = (MAC_IF_QSGMII | MAC_SPEED_1000)
};
/*mac communicate mode*/
enum mac_commom_mode {
MAC_COMM_MODE_NONE = 0, /**< No transmit/receive communication */
MAC_COMM_MODE_RX = 1, /**< Only receive communication */
MAC_COMM_MODE_TX = 2, /**< Only transmit communication */
MAC_COMM_MODE_RX_AND_TX = 3 /**< Both tx and rx communication */
};
/*mac statistics */
struct mac_statistics {
u64 stat_pkts64; /* r-10G tr-DT 64 byte frame counter */
u64 stat_pkts65to127; /* r-10G 65 to 127 byte frame counter */
u64 stat_pkts128to255; /* r-10G 128 to 255 byte frame counter */
u64 stat_pkts256to511; /*r-10G 256 to 511 byte frame counter */
u64 stat_pkts512to1023;/* r-10G 512 to 1023 byte frame counter */
u64 stat_pkts1024to1518; /* r-10G 1024 to 1518 byte frame counter */
u64 stat_pkts1519to1522; /* r-10G 1519 to 1522 byte good frame count*/
/* Total number of packets that were less than 64 octets */
/* long with a wrong CRC.*/
u64 stat_fragments;
/* Total number of packets longer than valid maximum length octets */
u64 stat_jabbers;
/* number of dropped packets due to internal errors of */
/* the MAC Client. */
u64 stat_drop_events;
/* Incremented when frames of correct length but with */
/* CRC error are received.*/
u64 stat_crc_align_errors;
/* Total number of packets that were less than 64 octets */
/* long with a good CRC.*/
u64 stat_undersize_pkts;
u64 stat_oversize_pkts; /**< T,B.D*/
u64 stat_rx_pause; /**< Pause MAC Control received */
u64 stat_tx_pause; /**< Pause MAC Control sent */
u64 in_octets; /**< Total number of byte received. */
u64 in_pkts; /* Total number of packets received.*/
u64 in_mcast_pkts; /* Total number of multicast frame received */
u64 in_bcast_pkts; /* Total number of broadcast frame received */
/* Frames received, but discarded due to */
/* problems within the MAC RX. */
u64 in_discards;
u64 in_errors; /* Number of frames received with error: */
/* - FIFO Overflow Error */
/* - CRC Error */
/* - Frame Too Long Error */
/* - Alignment Error */
u64 out_octets; /*Total number of byte sent. */
u64 out_pkts; /**< Total number of packets sent .*/
u64 out_mcast_pkts; /* Total number of multicast frame sent */
u64 out_bcast_pkts; /* Total number of multicast frame sent */
/* Frames received, but discarded due to problems within */
/* the MAC TX N/A!.*/
u64 out_discards;
u64 out_errors; /*Number of frames transmitted with error: */
/* - FIFO Overflow Error */
/* - FIFO Underflow Error */
/* - Other */
};
/*mac para struct ,mac get param from nic or dsaf when initialize*/
struct mac_params {
char addr[MAC_NUM_OCTETS_PER_ADDR];
void *vaddr; /*virtual address*/
struct device *dev;
u8 mac_id;
/**< Ethernet operation mode (MAC-PHY interface and speed) */
enum mac_mode mac_mode;
};
struct mac_info {
u16 speed;/* The forced speed (lower bits) in */
/* *mbps. Please use */
/* * ethtool_cmd_speed()/_set() to */
/* * access it */
u8 duplex; /* Duplex, half or full */
u8 auto_neg; /* Enable or disable autonegotiation */
enum hnae_loop loop_mode;
u8 tx_pause_en;
u8 tx_pause_time;
u8 rx_pause_en;
u8 pad_and_crc_en;
u8 promiscuous_en;
u8 port_en; /*port enable*/
};
struct mac_entry_idx {
u8 addr[MAC_NUM_OCTETS_PER_ADDR];
u16 vlan_id:12;
u16 valid:1;
u16 qos:3;
};
struct mac_hw_stats {
u64 rx_good_pkts; /* only for xgmac */
u64 rx_good_bytes;
u64 rx_total_pkts; /* only for xgmac */
u64 rx_total_bytes; /* only for xgmac */
u64 rx_bad_bytes; /* only for gmac */
u64 rx_uc_pkts;
u64 rx_mc_pkts;
u64 rx_bc_pkts;
u64 rx_fragment_err; /* only for xgmac */
u64 rx_undersize; /* only for xgmac */
u64 rx_under_min;
u64 rx_minto64; /* only for gmac */
u64 rx_64bytes;
u64 rx_65to127;
u64 rx_128to255;
u64 rx_256to511;
u64 rx_512to1023;
u64 rx_1024to1518;
u64 rx_1519tomax;
u64 rx_1519tomax_good; /* only for xgmac */
u64 rx_oversize;
u64 rx_jabber_err;
u64 rx_fcs_err;
u64 rx_vlan_pkts; /* only for gmac */
u64 rx_data_err; /* only for gmac */
u64 rx_align_err; /* only for gmac */
u64 rx_long_err; /* only for gmac */
u64 rx_pfc_tc0;
u64 rx_pfc_tc1; /* only for xgmac */
u64 rx_pfc_tc2; /* only for xgmac */
u64 rx_pfc_tc3; /* only for xgmac */
u64 rx_pfc_tc4; /* only for xgmac */
u64 rx_pfc_tc5; /* only for xgmac */
u64 rx_pfc_tc6; /* only for xgmac */
u64 rx_pfc_tc7; /* only for xgmac */
u64 rx_unknown_ctrl;
u64 rx_filter_pkts; /* only for gmac */
u64 rx_filter_bytes; /* only for gmac */
u64 rx_fifo_overrun_err;/* only for gmac */
u64 rx_len_err; /* only for gmac */
u64 rx_comma_err; /* only for gmac */
u64 rx_symbol_err; /* only for xgmac */
u64 tx_good_to_sw; /* only for xgmac */
u64 tx_bad_to_sw; /* only for xgmac */
u64 rx_1731_pkts; /* only for xgmac */
u64 tx_good_bytes;
u64 tx_good_pkts; /* only for xgmac */
u64 tx_total_bytes; /* only for xgmac */
u64 tx_total_pkts; /* only for xgmac */
u64 tx_bad_bytes; /* only for gmac */
u64 tx_bad_pkts; /* only for xgmac */
u64 tx_uc_pkts;
u64 tx_mc_pkts;
u64 tx_bc_pkts;
u64 tx_undersize; /* only for xgmac */
u64 tx_fragment_err; /* only for xgmac */
u64 tx_under_min_pkts; /* only for gmac */
u64 tx_64bytes;
u64 tx_65to127;
u64 tx_128to255;
u64 tx_256to511;
u64 tx_512to1023;
u64 tx_1024to1518;
u64 tx_1519tomax;
u64 tx_1519tomax_good; /* only for xgmac */
u64 tx_oversize; /* only for xgmac */
u64 tx_jabber_err;
u64 tx_underrun_err; /* only for gmac */
u64 tx_vlan; /* only for gmac */
u64 tx_crc_err; /* only for gmac */
u64 tx_pfc_tc0;
u64 tx_pfc_tc1; /* only for xgmac */
u64 tx_pfc_tc2; /* only for xgmac */
u64 tx_pfc_tc3; /* only for xgmac */
u64 tx_pfc_tc4; /* only for xgmac */
u64 tx_pfc_tc5; /* only for xgmac */
u64 tx_pfc_tc6; /* only for xgmac */
u64 tx_pfc_tc7; /* only for xgmac */
u64 tx_ctrl; /* only for xgmac */
u64 tx_1731_pkts; /* only for xgmac */
u64 tx_1588_pkts; /* only for xgmac */
u64 rx_good_from_sw; /* only for xgmac */
u64 rx_bad_from_sw; /* only for xgmac */
};
struct hns_mac_cb {
struct device *dev;
struct dsaf_device *dsaf_dev;
struct mac_priv priv;
u8 __iomem *vaddr;
u8 __iomem *cpld_vaddr;
u8 __iomem *sys_ctl_vaddr;
u8 __iomem *serdes_vaddr;
struct mac_entry_idx addr_entry_idx[DSAF_MAX_VM_NUM];
u8 sfp_prsnt;
u8 cpld_led_value;
u8 mac_id;
u8 link;
u8 half_duplex;
u16 speed;
u16 max_speed;
u16 max_frm;
u16 tx_pause_frm_time;
u32 if_support;
u64 txpkt_for_led;
u64 rxpkt_for_led;
enum hnae_port_type mac_type;
phy_interface_t phy_if;
enum hnae_loop loop_mode;
struct device_node *phy_node;
struct mac_hw_stats hw_stats;
};
struct mac_driver {
/*init Mac when init nic or dsaf*/
void (*mac_init)(void *mac_drv);
/*remove mac when remove nic or dsaf*/
void (*mac_free)(void *mac_drv);
/*enable mac when enable nic or dsaf*/
void (*mac_enable)(void *mac_drv, enum mac_commom_mode mode);
/*disable mac when disable nic or dsaf*/
void (*mac_disable)(void *mac_drv, enum mac_commom_mode mode);
/* config mac address*/
void (*set_mac_addr)(void *mac_drv, char *mac_addr);
/*adjust mac mode of port,include speed and duplex*/
int (*adjust_link)(void *mac_drv, enum mac_speed speed,
u32 full_duplex);
/* config autoegotaite mode of port*/
void (*set_an_mode)(void *mac_drv, u8 enable);
/* config loopbank mode */
int (*config_loopback)(void *mac_drv, enum hnae_loop loop_mode,
u8 enable);
/* config mtu*/
void (*config_max_frame_length)(void *mac_drv, u16 newval);
/*config PAD and CRC enable */
void (*config_pad_and_crc)(void *mac_drv, u8 newval);
/* config duplex mode*/
void (*config_half_duplex)(void *mac_drv, u8 newval);
/*config tx pause time,if pause_time is zero,disable tx pause enable*/
void (*set_tx_auto_pause_frames)(void *mac_drv, u16 pause_time);
/*config rx pause enable*/
void (*set_rx_ignore_pause_frames)(void *mac_drv, u32 enable);
/* config rx mode for promiscuous*/
int (*set_promiscuous)(void *mac_drv, u8 enable);
/* get mac id */
void (*mac_get_id)(void *mac_drv, u8 *mac_id);
void (*mac_pausefrm_cfg)(void *mac_drv, u32 rx_en, u32 tx_en);
void (*autoneg_stat)(void *mac_drv, u32 *enable);
int (*set_pause_enable)(void *mac_drv, u32 rx_en, u32 tx_en);
void (*get_pause_enable)(void *mac_drv, u32 *rx_en, u32 *tx_en);
void (*get_link_status)(void *mac_drv, u32 *link_stat);
/* get the imporant regs*/
void (*get_regs)(void *mac_drv, void *data);
int (*get_regs_count)(void);
/* get strings name for ethtool statistic */
void (*get_strings)(u32 stringset, u8 *data);
/* get the number of strings*/
int (*get_sset_count)(int stringset);
/* get the statistic by ethtools*/
void (*get_ethtool_stats)(void *mac_drv, u64 *data);
/* get mac information */
void (*get_info)(void *mac_drv, struct mac_info *mac_info);
void (*update_stats)(void *mac_drv);
enum mac_mode mac_mode;
u8 mac_id;
struct hns_mac_cb *mac_cb;
void __iomem *io_base;
unsigned int mac_en_flg;/*you'd better don't enable mac twice*/
unsigned int virt_dev_num;
struct device *dev;
};
struct mac_stats_string {
char desc[64];
unsigned long offset;
};
#define MAC_MAKE_MODE(interface, speed) (enum mac_mode)((interface) | (speed))
#define MAC_INTERFACE_FROM_MODE(mode) (enum mac_intf)((mode) & 0xFFFF0000)
#define MAC_SPEED_FROM_MODE(mode) (enum mac_speed)((mode) & 0x0000FFFF)
#define MAC_STATS_FIELD_OFF(field) (offsetof(struct mac_hw_stats, field))
static inline struct mac_driver *hns_mac_get_drv(
const struct hns_mac_cb *mac_cb)
{
return (struct mac_driver *)(mac_cb->priv.mac);
}
void *hns_gmac_config(struct hns_mac_cb *mac_cb,
struct mac_params *mac_param);
void *hns_xgmac_config(struct hns_mac_cb *mac_cb,
struct mac_params *mac_param);
int hns_mac_init(struct dsaf_device *dsaf_dev);
void mac_adjust_link(struct net_device *net_dev);
void hns_mac_get_link_status(struct hns_mac_cb *mac_cb, u32 *link_status);
int hns_mac_change_vf_addr(struct hns_mac_cb *mac_cb, u32 vmid, char *addr);
int hns_mac_set_multi(struct hns_mac_cb *mac_cb,
u32 port_num, char *addr, u8 en);
int hns_mac_vm_config_bc_en(struct hns_mac_cb *mac_cb, u32 vm, u8 en);
void hns_mac_start(struct hns_mac_cb *mac_cb);
void hns_mac_stop(struct hns_mac_cb *mac_cb);
int hns_mac_del_mac(struct hns_mac_cb *mac_cb, u32 vfn, char *mac);
void hns_mac_uninit(struct dsaf_device *dsaf_dev);
void hns_mac_adjust_link(struct hns_mac_cb *mac_cb, int speed, int duplex);
void hns_mac_reset(struct hns_mac_cb *mac_cb);
void hns_mac_get_autoneg(struct hns_mac_cb *mac_cb, u32 *auto_neg);
void hns_mac_get_pauseparam(struct hns_mac_cb *mac_cb, u32 *rx_en, u32 *tx_en);
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);
int hns_mac_set_mtu(struct hns_mac_cb *mac_cb, u32 new_mtu);
int hns_mac_get_port_info(struct hns_mac_cb *mac_cb,
u8 *auto_neg, u16 *speed, u8 *duplex);
phy_interface_t hns_mac_get_phy_if(struct hns_mac_cb *mac_cb);
int hns_mac_config_sds_loopback(struct hns_mac_cb *mac_cb, u8 en);
int hns_mac_config_mac_loopback(struct hns_mac_cb *mac_cb,
enum hnae_loop loop, int en);
void hns_mac_update_stats(struct hns_mac_cb *mac_cb);
void hns_mac_get_stats(struct hns_mac_cb *mac_cb, u64 *data);
void hns_mac_get_strings(struct hns_mac_cb *mac_cb, int stringset, u8 *data);
int hns_mac_get_sset_count(struct hns_mac_cb *mac_cb, int stringset);
void hns_mac_get_regs(struct hns_mac_cb *mac_cb, void *data);
int hns_mac_get_regs_count(struct hns_mac_cb *mac_cb);
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);
#endif /* _HNS_DSAF_MAC_H */
此差异已折叠。
/*
* Copyright (c) 2014-2015 Hisilicon Limited.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#ifndef __HNS_DSAF_MAIN_H
#define __HNS_DSAF_MAIN_H
#include "hnae.h"
#include "hns_dsaf_reg.h"
#include "hns_dsaf_mac.h"
struct hns_mac_cb;
#define DSAF_DRV_NAME "hns_dsaf"
#define DSAF_MOD_VERSION "v1.0"
#define ENABLE (0x1)
#define DISABLE (0x0)
#define HNS_DSAF_DEBUG_NW_REG_OFFSET (0x100000)
#define DSAF_BASE_INNER_PORT_NUM (127) /* mac tbl qid*/
#define DSAF_MAX_CHIP_NUM (2) /*max 2 chips */
#define DSAF_DEFAUTL_QUEUE_NUM_PER_PPE (22)
#define HNS_DSAF_MAX_DESC_CNT (1024)
#define HNS_DSAF_MIN_DESC_CNT (16)
#define DSAF_INVALID_ENTRY_IDX (0xffff)
#define DSAF_CFG_READ_CNT (30)
#define DSAF_SRAM_INIT_FINISH_FLAG (0xff)
#define MAC_NUM_OCTETS_PER_ADDR 6
#define DSAF_DUMP_REGS_NUM 504
#define DSAF_STATIC_NUM 28
#define DSAF_STATS_READ(p, offset) (*((u64 *)((u64)(p) + (offset))))
enum hal_dsaf_mode {
HRD_DSAF_NO_DSAF_MODE = 0x0,
HRD_DSAF_MODE = 0x1,
};
enum hal_dsaf_tc_mode {
HRD_DSAF_4TC_MODE = 0X0,
HRD_DSAF_8TC_MODE = 0X1,
};
struct dsaf_vm_def_vlan {
u32 vm_def_vlan_id;
u32 vm_def_vlan_cfi;
u32 vm_def_vlan_pri;
};
struct dsaf_tbl_tcam_data {
u32 tbl_tcam_data_high;
u32 tbl_tcam_data_low;
};
#define DSAF_PORT_MSK_NUM \
((DSAF_TOTAL_QUEUE_NUM + DSAF_SERVICE_NW_NUM - 1) / 32 + 1)
struct dsaf_tbl_tcam_mcast_cfg {
u8 tbl_mcast_old_en;
u8 tbl_mcast_item_vld;
u32 tbl_mcast_port_msk[DSAF_PORT_MSK_NUM];
};
struct dsaf_tbl_tcam_ucast_cfg {
u32 tbl_ucast_old_en;
u32 tbl_ucast_item_vld;
u32 tbl_ucast_mac_discard;
u32 tbl_ucast_dvc;
u32 tbl_ucast_out_port;
};
struct dsaf_tbl_line_cfg {
u32 tbl_line_mac_discard;
u32 tbl_line_dvc;
u32 tbl_line_out_port;
};
enum dsaf_port_rate_mode {
DSAF_PORT_RATE_1000 = 0,
DSAF_PORT_RATE_2500,
DSAF_PORT_RATE_10000
};
enum dsaf_stp_port_type {
DSAF_STP_PORT_TYPE_DISCARD = 0,
DSAF_STP_PORT_TYPE_BLOCK = 1,
DSAF_STP_PORT_TYPE_LISTEN = 2,
DSAF_STP_PORT_TYPE_LEARN = 3,
DSAF_STP_PORT_TYPE_FORWARD = 4
};
enum dsaf_sw_port_type {
DSAF_SW_PORT_TYPE_NON_VLAN = 0,
DSAF_SW_PORT_TYPE_ACCESS = 1,
DSAF_SW_PORT_TYPE_TRUNK = 2,
};
#define DSAF_SUB_BASE_SIZE (0x10000)
/* dsaf mode define */
enum dsaf_mode {
DSAF_MODE_INVALID = 0, /**< Invalid dsaf mode */
DSAF_MODE_ENABLE_FIX, /**< en DSAF-mode, fixed to queue*/
DSAF_MODE_ENABLE_0VM, /**< en DSAF-mode, support 0 VM */
DSAF_MODE_ENABLE_8VM, /**< en DSAF-mode, support 8 VM */
DSAF_MODE_ENABLE_16VM, /**< en DSAF-mode, support 16 VM */
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_FIX, /**< non-dasf, fixed to queue*/
DSAF_MODE_DISABLE_2PORT_8VM, /**< non-dasf, 2port 8VM */
DSAF_MODE_DISABLE_2PORT_16VM, /**< non-dasf, 2port 16VM */
DSAF_MODE_DISABLE_2PORT_64VM, /**< non-dasf, 2port 64VM */
DSAF_MODE_DISABLE_6PORT_0VM, /**< non-dasf, 6port 0VM */
DSAF_MODE_DISABLE_6PORT_2VM, /**< non-dasf, 6port 2VM */
DSAF_MODE_DISABLE_6PORT_4VM, /**< non-dasf, 6port 4VM */
DSAF_MODE_DISABLE_6PORT_16VM, /**< non-dasf, 6port 16VM */
DSAF_MODE_MAX /**< the last one, use as the num */
};
#define DSAF_DEST_PORT_NUM 256 /* DSAF max port num */
#define DSAF_WORD_BIT_CNT 32 /* the num bit of word */
/*mac entry, mc or uc entry*/
struct dsaf_drv_mac_single_dest_entry {
/* mac addr, match the entry*/
u8 addr[MAC_NUM_OCTETS_PER_ADDR];
u16 in_vlan_id; /* value of VlanId */
/* the vld input port num, dsaf-mode fix 0, */
/* non-dasf is the entry whitch port vld*/
u8 in_port_num;
u8 port_num; /*output port num*/
u8 rsv[6];
};
/*only mc entry*/
struct dsaf_drv_mac_multi_dest_entry {
/* mac addr, match the entry*/
u8 addr[MAC_NUM_OCTETS_PER_ADDR];
u16 in_vlan_id;
/* this mac addr output port,*/
/* bit0-bit5 means Port0-Port5(1bit is vld)**/
u32 port_mask[DSAF_DEST_PORT_NUM / DSAF_WORD_BIT_CNT];
/* the vld input port num, dsaf-mode fix 0,*/
/* non-dasf is the entry whitch port vld*/
u8 in_port_num;
u8 rsv[7];
};
struct dsaf_hw_stats {
u64 pad_drop;
u64 man_pkts;
u64 rx_pkts;
u64 rx_pkt_id;
u64 rx_pause_frame;
u64 release_buf_num;
u64 sbm_drop;
u64 crc_false;
u64 bp_drop;
u64 rslt_drop;
u64 local_addr_false;
u64 vlan_drop;
u64 stp_drop;
u64 tx_pkts;
};
struct hnae_vf_cb {
u8 port_index;
struct hns_mac_cb *mac_cb;
struct dsaf_device *dsaf_dev;
struct hnae_handle ae_handle; /* must be the last number */
};
struct dsaf_int_xge_src {
u32 xid_xge_ecc_err_int_src;
u32 xid_xge_fsm_timout_int_src;
u32 sbm_xge_lnk_fsm_timout_int_src;
u32 sbm_xge_lnk_ecc_2bit_int_src;
u32 sbm_xge_mib_req_failed_int_src;
u32 sbm_xge_mib_req_fsm_timout_int_src;
u32 sbm_xge_mib_rels_fsm_timout_int_src;
u32 sbm_xge_sram_ecc_2bit_int_src;
u32 sbm_xge_mib_buf_sum_err_int_src;
u32 sbm_xge_mib_req_extra_int_src;
u32 sbm_xge_mib_rels_extra_int_src;
u32 voq_xge_start_to_over_0_int_src;
u32 voq_xge_start_to_over_1_int_src;
u32 voq_xge_ecc_err_int_src;
};
struct dsaf_int_ppe_src {
u32 xid_ppe_fsm_timout_int_src;
u32 sbm_ppe_lnk_fsm_timout_int_src;
u32 sbm_ppe_lnk_ecc_2bit_int_src;
u32 sbm_ppe_mib_req_failed_int_src;
u32 sbm_ppe_mib_req_fsm_timout_int_src;
u32 sbm_ppe_mib_rels_fsm_timout_int_src;
u32 sbm_ppe_sram_ecc_2bit_int_src;
u32 sbm_ppe_mib_buf_sum_err_int_src;
u32 sbm_ppe_mib_req_extra_int_src;
u32 sbm_ppe_mib_rels_extra_int_src;
u32 voq_ppe_start_to_over_0_int_src;
u32 voq_ppe_ecc_err_int_src;
u32 xod_ppe_fifo_rd_empty_int_src;
u32 xod_ppe_fifo_wr_full_int_src;
};
struct dsaf_int_rocee_src {
u32 xid_rocee_fsm_timout_int_src;
u32 sbm_rocee_lnk_fsm_timout_int_src;
u32 sbm_rocee_lnk_ecc_2bit_int_src;
u32 sbm_rocee_mib_req_failed_int_src;
u32 sbm_rocee_mib_req_fsm_timout_int_src;
u32 sbm_rocee_mib_rels_fsm_timout_int_src;
u32 sbm_rocee_sram_ecc_2bit_int_src;
u32 sbm_rocee_mib_buf_sum_err_int_src;
u32 sbm_rocee_mib_req_extra_int_src;
u32 sbm_rocee_mib_rels_extra_int_src;
u32 voq_rocee_start_to_over_0_int_src;
u32 voq_rocee_ecc_err_int_src;
};
struct dsaf_int_tbl_src {
u32 tbl_da0_mis_src;
u32 tbl_da1_mis_src;
u32 tbl_da2_mis_src;
u32 tbl_da3_mis_src;
u32 tbl_da4_mis_src;
u32 tbl_da5_mis_src;
u32 tbl_da6_mis_src;
u32 tbl_da7_mis_src;
u32 tbl_sa_mis_src;
u32 tbl_old_sech_end_src;
u32 lram_ecc_err1_src;
u32 lram_ecc_err2_src;
u32 tram_ecc_err1_src;
u32 tram_ecc_err2_src;
u32 tbl_ucast_bcast_xge0_src;
u32 tbl_ucast_bcast_xge1_src;
u32 tbl_ucast_bcast_xge2_src;
u32 tbl_ucast_bcast_xge3_src;
u32 tbl_ucast_bcast_xge4_src;
u32 tbl_ucast_bcast_xge5_src;
u32 tbl_ucast_bcast_ppe_src;
u32 tbl_ucast_bcast_rocee_src;
};
struct dsaf_int_stat {
struct dsaf_int_xge_src dsaf_int_xge_stat[DSAF_COMM_CHN];
struct dsaf_int_ppe_src dsaf_int_ppe_stat[DSAF_COMM_CHN];
struct dsaf_int_rocee_src dsaf_int_rocee_stat[DSAF_COMM_CHN];
struct dsaf_int_tbl_src dsaf_int_tbl_stat[1];
};
/* Dsaf device struct define ,and mac -> dsaf */
struct dsaf_device {
struct device *dev;
struct hnae_ae_dev ae_dev;
void *priv;
int virq[DSAF_IRQ_NUM];
u8 __iomem *sc_base;
u8 __iomem *sds_base;
u8 __iomem *ppe_base;
u8 __iomem *io_base;
u8 __iomem *cpld_base;
u32 desc_num; /* desc num per queue*/
u32 buf_size; /* ring buffer size */
int buf_size_type; /* ring buffer size-type */
enum dsaf_mode dsaf_mode; /* dsaf mode */
enum hal_dsaf_mode dsaf_en;
enum hal_dsaf_tc_mode dsaf_tc_mode;
u32 dsaf_ver;
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 dsaf_hw_stats hw_stats[DSAF_NODE_NUM];
struct dsaf_int_stat int_stat;
};
static inline void *hns_dsaf_dev_priv(const struct dsaf_device *dsaf_dev)
{
return (void *)((u64)dsaf_dev + sizeof(*dsaf_dev));
}
struct dsaf_drv_tbl_tcam_key {
union {
struct {
u8 mac_3;
u8 mac_2;
u8 mac_1;
u8 mac_0;
} bits;
u32 val;
} high;
union {
struct {
u32 port:4; /* port id, */
/* dsaf-mode fixed 0, non-dsaf-mode port id*/
u32 vlan:12; /* vlan id */
u32 mac_5:8;
u32 mac_4:8;
} bits;
u32 val;
} low;
};
struct dsaf_drv_soft_mac_tbl {
struct dsaf_drv_tbl_tcam_key tcam_key;
u16 index; /*the entry's index in tcam tab*/
};
struct dsaf_drv_priv {
/* soft tab Mac key, for hardware tab*/
struct dsaf_drv_soft_mac_tbl *soft_mac_tbl;
};
static inline void hns_dsaf_tbl_tcam_addr_cfg(struct dsaf_device *dsaf_dev,
u32 tab_tcam_addr)
{
dsaf_set_dev_field(dsaf_dev, DSAF_TBL_TCAM_ADDR_0_REG,
DSAF_TBL_TCAM_ADDR_M, DSAF_TBL_TCAM_ADDR_S,
tab_tcam_addr);
}
static inline void hns_dsaf_tbl_tcam_load_pul(struct dsaf_device *dsaf_dev)
{
u32 o_tbl_pul;
o_tbl_pul = dsaf_read_dev(dsaf_dev, DSAF_TBL_PUL_0_REG);
dsaf_set_bit(o_tbl_pul, DSAF_TBL_PUL_TCAM_LOAD_S, 1);
dsaf_write_dev(dsaf_dev, DSAF_TBL_PUL_0_REG, o_tbl_pul);
dsaf_set_bit(o_tbl_pul, DSAF_TBL_PUL_TCAM_LOAD_S, 0);
dsaf_write_dev(dsaf_dev, DSAF_TBL_PUL_0_REG, o_tbl_pul);
}
static inline void hns_dsaf_tbl_line_addr_cfg(struct dsaf_device *dsaf_dev,
u32 tab_line_addr)
{
dsaf_set_dev_field(dsaf_dev, DSAF_TBL_LINE_ADDR_0_REG,
DSAF_TBL_LINE_ADDR_M, DSAF_TBL_LINE_ADDR_S,
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)
{
return container_of(handle, struct hnae_vf_cb, ae_handle);
}
int hns_dsaf_set_mac_uc_entry(struct dsaf_device *dsaf_dev,
struct dsaf_drv_mac_single_dest_entry *mac_entry);
int hns_dsaf_set_mac_mc_entry(struct dsaf_device *dsaf_dev,
struct dsaf_drv_mac_multi_dest_entry *mac_entry);
int hns_dsaf_add_mac_mc_port(struct dsaf_device *dsaf_dev,
struct dsaf_drv_mac_single_dest_entry *mac_entry);
int hns_dsaf_del_mac_entry(struct dsaf_device *dsaf_dev, u16 vlan_id,
u8 in_port_num, u8 *addr);
int hns_dsaf_del_mac_mc_port(struct dsaf_device *dsaf_dev,
struct dsaf_drv_mac_single_dest_entry *mac_entry);
int hns_dsaf_get_mac_uc_entry(struct dsaf_device *dsaf_dev,
struct dsaf_drv_mac_single_dest_entry *mac_entry);
int hns_dsaf_get_mac_mc_entry(struct dsaf_device *dsaf_dev,
struct dsaf_drv_mac_multi_dest_entry *mac_entry);
int hns_dsaf_get_mac_entry_by_index(
struct dsaf_device *dsaf_dev,
u16 entry_index,
struct dsaf_drv_mac_multi_dest_entry *mac_entry);
void hns_dsaf_rst(struct dsaf_device *dsaf_dev, u32 val);
void hns_ppe_srst_by_port(struct dsaf_device *dsaf_dev, u32 port, u32 val);
void hns_ppe_com_srst(struct ppe_common_cb *ppe_common, u32 val);
void hns_dsaf_fix_mac_mode(struct hns_mac_cb *mac_cb);
int hns_dsaf_ae_init(struct dsaf_device *dsaf_dev);
void hns_dsaf_ae_uninit(struct dsaf_device *dsaf_dev);
void hns_dsaf_xge_srst_by_port(struct dsaf_device *dsaf_dev, u32 port, u32 val);
void hns_dsaf_ge_srst_by_port(struct dsaf_device *dsaf_dev, u32 port, u32 val);
void hns_dsaf_xge_core_srst_by_port(struct dsaf_device *dsaf_dev,
u32 port, u32 val);
void hns_dsaf_update_stats(struct dsaf_device *dsaf_dev, u32 inode_num);
int hns_dsaf_get_sset_count(int stringset);
void hns_dsaf_get_stats(struct dsaf_device *ddev, u64 *data, int port);
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);
#endif /* __HNS_DSAF_MAIN_H__ */
/*
* Copyright (c) 2014-2015 Hisilicon Limited.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include "hns_dsaf_misc.h"
#include "hns_dsaf_mac.h"
#include "hns_dsaf_reg.h"
#include "hns_dsaf_ppe.h"
void hns_cpld_set_led(struct hns_mac_cb *mac_cb, int link_status,
u16 speed, int data)
{
int speed_reg = 0;
u8 value;
if (!mac_cb) {
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",
mac_cb->mac_id);
return;
}
if (speed == MAC_SPEED_10000)
speed_reg = 1;
value = mac_cb->cpld_led_value;
if (link_status) {
dsaf_set_bit(value, DSAF_LED_LINK_B, link_status);
dsaf_set_field(value, DSAF_LED_SPEED_M,
DSAF_LED_SPEED_S, speed_reg);
dsaf_set_bit(value, DSAF_LED_DATA_B, data);
if (value != mac_cb->cpld_led_value) {
dsaf_write_b(mac_cb->cpld_vaddr, value);
mac_cb->cpld_led_value = value;
}
} else {
dsaf_write_b(mac_cb->cpld_vaddr, 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)
return;
dsaf_write_b(mac_cb->cpld_vaddr, CPLD_LED_DEFAULT_VALUE);
mac_cb->cpld_led_value = CPLD_LED_DEFAULT_VALUE;
}
int cpld_set_led_id(struct hns_mac_cb *mac_cb,
enum hnae_led_state status)
{
switch (status) {
case HNAE_LED_ACTIVE:
mac_cb->cpld_led_value = dsaf_read_b(mac_cb->cpld_vaddr);
return 2;
case HNAE_LED_ON:
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);
break;
case HNAE_LED_OFF:
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);
break;
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);
break;
default:
break;
}
return 0;
}
#define RESET_REQ_OR_DREQ 1
void hns_dsaf_rst(struct dsaf_device *dsaf_dev, u32 val)
{
u32 xbar_reg_addr;
u32 nt_reg_addr;
if (!val) {
xbar_reg_addr = DSAF_SUB_SC_XBAR_RESET_REQ_REG;
nt_reg_addr = DSAF_SUB_SC_NT_RESET_REQ_REG;
} else {
xbar_reg_addr = DSAF_SUB_SC_XBAR_RESET_DREQ_REG;
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);
}
void hns_dsaf_xge_srst_by_port(struct dsaf_device *dsaf_dev, u32 port, u32 val)
{
u32 reg_val = 0;
u32 reg_addr;
if (port >= DSAF_XGE_NUM)
return;
reg_val |= RESET_REQ_OR_DREQ;
reg_val |= 0x2082082 << port;
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);
}
void hns_dsaf_xge_core_srst_by_port(struct dsaf_device *dsaf_dev,
u32 port, u32 val)
{
u32 reg_val = 0;
u32 reg_addr;
if (port >= DSAF_XGE_NUM)
return;
reg_val |= XGMAC_TRX_CORE_SRST_M << port;
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);
}
void hns_dsaf_ge_srst_by_port(struct dsaf_device *dsaf_dev, u32 port, u32 val)
{
u32 reg_val_1;
u32 reg_val_2;
if (port >= DSAF_GE_NUM)
return;
if (port < DSAF_SERVICE_NW_NUM) {
reg_val_1 = 0x1 << port;
reg_val_2 = 0x1041041 << port;
if (val == 0) {
dsaf_write_reg(dsaf_dev->sc_base,
DSAF_SUB_SC_GE_RESET_REQ1_REG,
reg_val_1);
dsaf_write_reg(dsaf_dev->sc_base,
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,
reg_val_2);
dsaf_write_reg(dsaf_dev->sc_base,
DSAF_SUB_SC_GE_RESET_DREQ1_REG,
reg_val_1);
}
} else {
reg_val_1 = 0x15540 << (port - 6);
reg_val_2 = 0x100 << (port - 6);
if (val == 0) {
dsaf_write_reg(dsaf_dev->sc_base,
DSAF_SUB_SC_GE_RESET_REQ1_REG,
reg_val_1);
dsaf_write_reg(dsaf_dev->sc_base,
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,
reg_val_1);
dsaf_write_reg(dsaf_dev->sc_base,
DSAF_SUB_SC_PPE_RESET_DREQ_REG,
reg_val_2);
}
}
}
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;
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);
}
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) {
reg_val = RESET_REQ_OR_DREQ;
if (val == 0)
reg_addr = DSAF_SUB_SC_RCB_PPE_COM_RESET_REQ_REG;
else
reg_addr = DSAF_SUB_SC_RCB_PPE_COM_RESET_DREQ_REG;
} else {
reg_val = 0x100 << (comm_index - 1);
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);
}
/**
* hns_mac_get_sds_mode - get phy ifterface form serdes mode
* @mac_cb: mac control block
* retuen phy interface
*/
phy_interface_t hns_mac_get_phy_if(struct hns_mac_cb *mac_cb)
{
u32 hilink3_mode;
u32 hilink4_mode;
void __iomem *sys_ctl_vaddr = mac_cb->sys_ctl_vaddr;
int dev_id = mac_cb->mac_id;
phy_interface_t phy_if = PHY_INTERFACE_MODE_NA;
hilink3_mode = dsaf_read_reg(sys_ctl_vaddr, HNS_MAC_HILINK3_REG);
hilink4_mode = dsaf_read_reg(sys_ctl_vaddr, HNS_MAC_HILINK4_REG);
if (dev_id >= 0 && dev_id <= 3) {
if (hilink4_mode == 0)
phy_if = PHY_INTERFACE_MODE_SGMII;
else
phy_if = PHY_INTERFACE_MODE_XGMII;
} else if (dev_id >= 4 && dev_id <= 5) {
if (hilink3_mode == 0)
phy_if = PHY_INTERFACE_MODE_SGMII;
else
phy_if = PHY_INTERFACE_MODE_XGMII;
} else {
phy_if = PHY_INTERFACE_MODE_SGMII;
}
dev_dbg(mac_cb->dev,
"hilink3_mode=%d, hilink4_mode=%d dev_id=%d, phy_if=%d\n",
hilink3_mode, hilink4_mode, dev_id, phy_if);
return phy_if;
}
/**
* hns_mac_config_sds_loopback - set loop back for serdes
* @mac_cb: mac control block
* retuen 0 == success
*/
int hns_mac_config_sds_loopback(struct hns_mac_cb *mac_cb, u8 en)
{
/* port 0-3 hilink4 base is serdes_vaddr + 0x00280000
* port 4-7 hilink3 base is serdes_vaddr + 0x00200000
*/
u8 *base_addr = (u8 *)mac_cb->serdes_vaddr +
(mac_cb->mac_id <= 3 ? 0x00280000 : 0x00200000);
const u8 lane_id[] = {
0, /* mac 0 -> lane 0 */
1, /* mac 1 -> lane 1 */
2, /* mac 2 -> lane 2 */
3, /* mac 3 -> lane 3 */
2, /* mac 4 -> lane 2 */
3, /* mac 5 -> lane 3 */
0, /* mac 6 -> lane 0 */
1 /* mac 7 -> lane 1 */
};
#define RX_CSR(lane, reg) ((0x4080 + (reg) * 0x0002 + (lane) * 0x0200) * 2)
u64 reg_offset = RX_CSR(lane_id[mac_cb->mac_id], 0);
int sfp_prsnt;
int ret = hns_mac_get_sfp_prsnt(mac_cb, &sfp_prsnt);
if (!mac_cb->phy_node) {
if (ret)
pr_info("please confirm sfp is present or not\n");
else
if (!sfp_prsnt)
pr_info("no sfp in this eth\n");
}
dsaf_set_reg_field(base_addr, reg_offset, 1ull << 10, 10, !!en);
return 0;
}
/*
* Copyright (c) 2014-2015 Hisilicon Limited.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#ifndef _HNS_DSAF_MISC_H
#define _HNS_DSAF_MISC_H
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/platform_device.h>
#include "hns_dsaf_mac.h"
#define CPLD_ADDR_PORT_OFFSET 0x4
#define HS_LED_ON 0xE
#define HS_LED_OFF 0xF
#define CPLD_LED_ON_VALUE 1
#define CPLD_LED_DEFAULT_VALUE 0
#define MAC_SFP_PORT_OFFSET 0x2
#define DSAF_LED_SPEED_S 0
#define DSAF_LED_SPEED_M (0x3 << DSAF_LED_SPEED_S)
#define DSAF_LED_LINK_B 2
#define DSAF_LED_DATA_B 4
#define DSAF_LED_ANCHOR_B 5
void hns_cpld_set_led(struct hns_mac_cb *mac_cb, int link_status,
u16 speed, int data);
void cpld_led_reset(struct hns_mac_cb *mac_cb);
int cpld_set_led_id(struct hns_mac_cb *mac_cb,
enum hnae_led_state status);
int hns_mac_get_sfp_prsnt(struct hns_mac_cb *mac_cb, int *sfp_prsnt);
#endif
/*
* Copyright (c) 2014-2015 Hisilicon Limited.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include "hns_dsaf_ppe.h"
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;
}
/**
* hns_ppe_common_get_cfg - get ppe common config
* @dsaf_dev: dasf device
* comm_index: common index
* retuen 0 - success , negative --fail
*/
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)
ppe_num = HNS_PPE_SERVICE_NW_ENGINE_NUM;
else
ppe_num = HNS_PPE_DEBUG_NW_ENGINE_NUM;
ppe_common = devm_kzalloc(dsaf_dev->dev, sizeof(*ppe_common) +
ppe_num * sizeof(struct hns_ppe_cb), GFP_KERNEL);
if (!ppe_common)
return -ENOMEM;
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)
ppe_common->ppe_mode = PPE_COMMON_MODE_SERVICE;
else
ppe_common->ppe_mode = PPE_COMMON_MODE_DEBUG;
ppe_common->dev = dsaf_dev->dev;
ppe_common->io_base = hns_ppe_common_get_ioaddr(ppe_common);
dsaf_dev->ppe_common[comm_index] = ppe_common;
return 0;
}
void hns_ppe_common_free_cfg(struct dsaf_device *dsaf_dev, u32 comm_index)
{
dsaf_dev->ppe_common[comm_index] = NULL;
}
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;
}
static void hns_ppe_get_cfg(struct ppe_common_cb *ppe_common)
{
u32 i;
struct hns_ppe_cb *ppe_cb;
u32 ppe_num = ppe_common->ppe_num;
for (i = 0; i < ppe_num; i++) {
ppe_cb = &ppe_common->ppe_cb[i];
ppe_cb->dev = ppe_common->dev;
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;
}
}
static void hns_ppe_cnt_clr_ce(struct hns_ppe_cb *ppe_cb)
{
dsaf_set_dev_bit(ppe_cb, PPE_TNL_0_5_CNT_CLR_CE_REG,
PPE_CNT_CLR_CE_B, 1);
}
/**
* hns_ppe_checksum_hw - set ppe checksum caculate
* @ppe_device: ppe device
* @value: value
*/
static void hns_ppe_checksum_hw(struct hns_ppe_cb *ppe_cb, u32 value)
{
dsaf_set_dev_field(ppe_cb, PPE_CFG_PRO_CHECK_EN_REG,
0xfffffff, 0, value);
}
static void hns_ppe_set_qid_mode(struct ppe_common_cb *ppe_common,
enum ppe_qid_mode qid_mdoe)
{
dsaf_set_dev_field(ppe_common, PPE_COM_CFG_QID_MODE_REG,
PPE_CFG_QID_MODE_CF_QID_MODE_M,
PPE_CFG_QID_MODE_CF_QID_MODE_S, qid_mdoe);
}
/**
* hns_ppe_set_qid - set ppe qid
* @ppe_common: ppe common device
* @qid: queue id
*/
static void hns_ppe_set_qid(struct ppe_common_cb *ppe_common, u32 qid)
{
u32 qid_mod = dsaf_read_dev(ppe_common, PPE_COM_CFG_QID_MODE_REG);
if (!dsaf_get_field(qid_mod, PPE_CFG_QID_MODE_DEF_QID_M,
PPE_CFG_QID_MODE_DEF_QID_S)) {
dsaf_set_field(qid_mod, PPE_CFG_QID_MODE_DEF_QID_M,
PPE_CFG_QID_MODE_DEF_QID_S, qid);
dsaf_write_dev(ppe_common, PPE_COM_CFG_QID_MODE_REG, qid_mod);
}
}
/**
* hns_ppe_set_port_mode - set port mode
* @ppe_device: ppe device
* @mode: port mode
*/
static void hns_ppe_set_port_mode(struct hns_ppe_cb *ppe_cb,
enum ppe_port_mode mode)
{
dsaf_write_dev(ppe_cb, PPE_CFG_XGE_MODE_REG, mode);
}
/**
* hns_ppe_common_init_hw - init ppe common device
* @ppe_common: ppe common device
*
* Return 0 on success, negative on failure
*/
static int hns_ppe_common_init_hw(struct ppe_common_cb *ppe_common)
{
enum ppe_qid_mode qid_mode;
enum dsaf_mode dsaf_mode = ppe_common->dsaf_dev->dsaf_mode;
hns_ppe_com_srst(ppe_common, 0);
mdelay(100);
hns_ppe_com_srst(ppe_common, 1);
mdelay(100);
if (ppe_common->ppe_mode == PPE_COMMON_MODE_SERVICE) {
switch (dsaf_mode) {
case DSAF_MODE_ENABLE_FIX:
case DSAF_MODE_DISABLE_FIX:
qid_mode = PPE_QID_MODE0;
hns_ppe_set_qid(ppe_common, 0);
break;
case DSAF_MODE_ENABLE_0VM:
case DSAF_MODE_DISABLE_2PORT_64VM:
qid_mode = PPE_QID_MODE3;
break;
case DSAF_MODE_ENABLE_8VM:
case DSAF_MODE_DISABLE_2PORT_16VM:
qid_mode = PPE_QID_MODE4;
break;
case DSAF_MODE_ENABLE_16VM:
case DSAF_MODE_DISABLE_6PORT_0VM:
qid_mode = PPE_QID_MODE5;
break;
case DSAF_MODE_ENABLE_32VM:
case DSAF_MODE_DISABLE_6PORT_16VM:
qid_mode = PPE_QID_MODE2;
break;
case DSAF_MODE_ENABLE_128VM:
case DSAF_MODE_DISABLE_6PORT_4VM:
qid_mode = PPE_QID_MODE1;
break;
case DSAF_MODE_DISABLE_2PORT_8VM:
qid_mode = PPE_QID_MODE7;
break;
case DSAF_MODE_DISABLE_6PORT_2VM:
qid_mode = PPE_QID_MODE6;
break;
default:
dev_err(ppe_common->dev,
"get ppe queue mode failed! dsaf_mode=%d\n",
dsaf_mode);
return -EINVAL;
}
hns_ppe_set_qid_mode(ppe_common, qid_mode);
}
dsaf_set_dev_bit(ppe_common, PPE_COM_COMMON_CNT_CLR_CE_REG,
PPE_COMMON_CNT_CLR_CE_B, 1);
return 0;
}
/*clr ppe exception irq*/
static void hns_ppe_exc_irq_en(struct hns_ppe_cb *ppe_cb, int en)
{
u32 clr_vlue = 0xfffffffful;
u32 msk_vlue = en ? 0xfffffffful : 0; /*1 is en, 0 is dis*/
u32 vld_msk = 0;
/*only care bit 0,1,7*/
dsaf_set_bit(vld_msk, 0, 1);
dsaf_set_bit(vld_msk, 1, 1);
dsaf_set_bit(vld_msk, 7, 1);
/*clr sts**/
dsaf_write_dev(ppe_cb, PPE_RINT_REG, clr_vlue);
/*for some reserved bits, so set 0**/
dsaf_write_dev(ppe_cb, PPE_INTEN_REG, msk_vlue & vld_msk);
}
/**
* ppe_init_hw - init ppe
* @ppe_device: ppe device
*/
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;
struct dsaf_device *dsaf_dev = ppe_common_cb->dsaf_dev;
hns_ppe_srst_by_port(dsaf_dev, port, 0);
mdelay(10);
hns_ppe_srst_by_port(dsaf_dev, port, 1);
/* clr and msk except irq*/
hns_ppe_exc_irq_en(ppe_cb, 0);
if (ppe_common_cb->ppe_mode == PPE_COMMON_MODE_DEBUG)
hns_ppe_set_port_mode(ppe_cb, PPE_MODE_GE);
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);
}
/**
* ppe_uninit_hw - uninit ppe
* @ppe_device: ppe device
*/
static void hns_ppe_uninit_hw(struct hns_ppe_cb *ppe_cb)
{
u32 port;
if (ppe_cb->ppe_common_cb) {
port = ppe_cb->index;
hns_ppe_srst_by_port(ppe_cb->ppe_common_cb->dsaf_dev, port, 0);
}
}
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]);
memset(&ppe_common->ppe_cb[i], 0, sizeof(struct hns_ppe_cb));
}
}
void hns_ppe_uninit(struct dsaf_device *dsaf_dev)
{
u32 i;
for (i = 0; i < HNS_PPE_COM_NUM; i++) {
if (dsaf_dev->ppe_common[i])
hns_ppe_uninit_ex(dsaf_dev->ppe_common[i]);
hns_rcb_common_free_cfg(dsaf_dev, i);
hns_ppe_common_free_cfg(dsaf_dev, i);
}
}
/**
* hns_ppe_reset - reinit ppe/rcb hw
* @dsaf_dev: dasf device
* retuen void
*/
void hns_ppe_reset_common(struct dsaf_device *dsaf_dev, u8 ppe_common_index)
{
u32 i;
int ret;
struct ppe_common_cb *ppe_common;
ppe_common = dsaf_dev->ppe_common[ppe_common_index];
ret = hns_ppe_common_init_hw(ppe_common);
if (ret)
return;
ret = hns_rcb_common_init_hw(dsaf_dev->rcb_common[ppe_common_index]);
if (ret)
return;
for (i = 0; i < ppe_common->ppe_num; i++)
hns_ppe_init_hw(&ppe_common->ppe_cb[i]);
hns_rcb_common_init_commit_hw(dsaf_dev->rcb_common[ppe_common_index]);
}
void hns_ppe_update_stats(struct hns_ppe_cb *ppe_cb)
{
struct hns_ppe_hw_stats *hw_stats = &ppe_cb->hw_stats;
hw_stats->rx_pkts_from_sw
+= dsaf_read_dev(ppe_cb, PPE_HIS_RX_SW_PKT_CNT_REG);
hw_stats->rx_pkts
+= dsaf_read_dev(ppe_cb, PPE_HIS_RX_WR_BD_OK_PKT_CNT_REG);
hw_stats->rx_drop_no_bd
+= dsaf_read_dev(ppe_cb, PPE_HIS_RX_PKT_NO_BUF_CNT_REG);
hw_stats->rx_alloc_buf_fail
+= dsaf_read_dev(ppe_cb, PPE_HIS_RX_APP_BUF_FAIL_CNT_REG);
hw_stats->rx_alloc_buf_wait
+= dsaf_read_dev(ppe_cb, PPE_HIS_RX_APP_BUF_WAIT_CNT_REG);
hw_stats->rx_drop_no_buf
+= dsaf_read_dev(ppe_cb, PPE_HIS_RX_PKT_DROP_FUL_CNT_REG);
hw_stats->rx_err_fifo_full
+= dsaf_read_dev(ppe_cb, PPE_HIS_RX_PKT_DROP_PRT_CNT_REG);
hw_stats->tx_bd_form_rcb
+= dsaf_read_dev(ppe_cb, PPE_HIS_TX_BD_CNT_REG);
hw_stats->tx_pkts_from_rcb
+= dsaf_read_dev(ppe_cb, PPE_HIS_TX_PKT_CNT_REG);
hw_stats->tx_pkts
+= dsaf_read_dev(ppe_cb, PPE_HIS_TX_PKT_OK_CNT_REG);
hw_stats->tx_err_fifo_empty
+= dsaf_read_dev(ppe_cb, PPE_HIS_TX_PKT_EPT_CNT_REG);
hw_stats->tx_err_checksum
+= dsaf_read_dev(ppe_cb, PPE_HIS_TX_PKT_CS_FAIL_CNT_REG);
}
int hns_ppe_get_sset_count(int stringset)
{
if (stringset == ETH_SS_STATS)
return ETH_PPE_STATIC_NUM;
return 0;
}
int hns_ppe_get_regs_count(void)
{
return ETH_PPE_DUMP_NUM;
}
/**
* ppe_get_strings - get ppe srting
* @ppe_device: ppe device
* @stringset: string set type
* @data: output string
*/
void hns_ppe_get_strings(struct hns_ppe_cb *ppe_cb, int stringset, u8 *data)
{
char *buff = (char *)data;
int index = ppe_cb->index;
snprintf(buff, ETH_GSTRING_LEN, "ppe%d_rx_sw_pkt", index);
buff = buff + ETH_GSTRING_LEN;
snprintf(buff, ETH_GSTRING_LEN, "ppe%d_rx_pkt_ok", index);
buff = buff + ETH_GSTRING_LEN;
snprintf(buff, ETH_GSTRING_LEN, "ppe%d_rx_drop_pkt_no_bd", index);
buff = buff + ETH_GSTRING_LEN;
snprintf(buff, ETH_GSTRING_LEN, "ppe%d_rx_alloc_buf_fail", index);
buff = buff + ETH_GSTRING_LEN;
snprintf(buff, ETH_GSTRING_LEN, "ppe%d_rx_alloc_buf_wait", index);
buff = buff + ETH_GSTRING_LEN;
snprintf(buff, ETH_GSTRING_LEN, "ppe%d_rx_pkt_drop_no_buf", index);
buff = buff + ETH_GSTRING_LEN;
snprintf(buff, ETH_GSTRING_LEN, "ppe%d_rx_pkt_err_fifo_full", index);
buff = buff + ETH_GSTRING_LEN;
snprintf(buff, ETH_GSTRING_LEN, "ppe%d_tx_bd", index);
buff = buff + ETH_GSTRING_LEN;
snprintf(buff, ETH_GSTRING_LEN, "ppe%d_tx_pkt", index);
buff = buff + ETH_GSTRING_LEN;
snprintf(buff, ETH_GSTRING_LEN, "ppe%d_tx_pkt_ok", index);
buff = buff + ETH_GSTRING_LEN;
snprintf(buff, ETH_GSTRING_LEN, "ppe%d_tx_pkt_err_fifo_empty", index);
buff = buff + ETH_GSTRING_LEN;
snprintf(buff, ETH_GSTRING_LEN, "ppe%d_tx_pkt_err_csum_fail", index);
}
void hns_ppe_get_stats(struct hns_ppe_cb *ppe_cb, u64 *data)
{
u64 *regs_buff = data;
struct hns_ppe_hw_stats *hw_stats = &ppe_cb->hw_stats;
regs_buff[0] = hw_stats->rx_pkts_from_sw;
regs_buff[1] = hw_stats->rx_pkts;
regs_buff[2] = hw_stats->rx_drop_no_bd;
regs_buff[3] = hw_stats->rx_alloc_buf_fail;
regs_buff[4] = hw_stats->rx_alloc_buf_wait;
regs_buff[5] = hw_stats->rx_drop_no_buf;
regs_buff[6] = hw_stats->rx_err_fifo_full;
regs_buff[7] = hw_stats->tx_bd_form_rcb;
regs_buff[8] = hw_stats->tx_pkts_from_rcb;
regs_buff[9] = hw_stats->tx_pkts;
regs_buff[10] = hw_stats->tx_err_fifo_empty;
regs_buff[11] = hw_stats->tx_err_checksum;
}
/**
* hns_ppe_init - init ppe device
* @dsaf_dev: dasf device
* retuen 0 - success , negative --fail
*/
int hns_ppe_init(struct dsaf_device *dsaf_dev)
{
int i, k;
int ret;
for (i = 0; i < HNS_PPE_COM_NUM; i++) {
ret = hns_ppe_common_get_cfg(dsaf_dev, i);
if (ret)
goto get_ppe_cfg_fail;
ret = hns_rcb_common_get_cfg(dsaf_dev, i);
if (ret)
goto get_rcb_cfg_fail;
hns_ppe_get_cfg(dsaf_dev->ppe_common[i]);
hns_rcb_get_cfg(dsaf_dev->rcb_common[i]);
}
for (i = 0; i < HNS_PPE_COM_NUM; i++)
hns_ppe_reset_common(dsaf_dev, i);
return 0;
get_rcb_cfg_fail:
hns_ppe_common_free_cfg(dsaf_dev, i);
get_ppe_cfg_fail:
for (k = i - 1; k >= 0; k--) {
hns_rcb_common_free_cfg(dsaf_dev, k);
hns_ppe_common_free_cfg(dsaf_dev, k);
}
return ret;
}
void hns_ppe_get_regs(struct hns_ppe_cb *ppe_cb, void *data)
{
struct ppe_common_cb *ppe_common = ppe_cb->ppe_common_cb;
u32 *regs = data;
u32 i;
u32 offset;
/* ppe common registers */
regs[0] = dsaf_read_dev(ppe_common, PPE_COM_CFG_QID_MODE_REG);
regs[1] = dsaf_read_dev(ppe_common, PPE_COM_INTEN_REG);
regs[2] = dsaf_read_dev(ppe_common, PPE_COM_RINT_REG);
regs[3] = dsaf_read_dev(ppe_common, PPE_COM_INTSTS_REG);
regs[4] = dsaf_read_dev(ppe_common, PPE_COM_COMMON_CNT_CLR_CE_REG);
for (i = 0; i < DSAF_TOTAL_QUEUE_NUM; i++) {
offset = PPE_COM_HIS_RX_PKT_QID_DROP_CNT_REG + 0x4 * i;
regs[5 + i] = dsaf_read_dev(ppe_common, offset);
offset = PPE_COM_HIS_RX_PKT_QID_OK_CNT_REG + 0x4 * i;
regs[5 + i + DSAF_TOTAL_QUEUE_NUM]
= dsaf_read_dev(ppe_common, offset);
offset = PPE_COM_HIS_TX_PKT_QID_ERR_CNT_REG + 0x4 * i;
regs[5 + i + DSAF_TOTAL_QUEUE_NUM * 2]
= dsaf_read_dev(ppe_common, offset);
offset = PPE_COM_HIS_TX_PKT_QID_OK_CNT_REG + 0x4 * i;
regs[5 + i + DSAF_TOTAL_QUEUE_NUM * 3]
= dsaf_read_dev(ppe_common, offset);
}
/* mark end of ppe regs */
for (i = 521; i < 524; i++)
regs[i] = 0xeeeeeeee;
/* ppe channel registers */
regs[525] = dsaf_read_dev(ppe_cb, PPE_CFG_TX_FIFO_THRSLD_REG);
regs[526] = dsaf_read_dev(ppe_cb, PPE_CFG_RX_FIFO_THRSLD_REG);
regs[527] = dsaf_read_dev(ppe_cb, PPE_CFG_RX_FIFO_PAUSE_THRSLD_REG);
regs[528] = dsaf_read_dev(ppe_cb, PPE_CFG_RX_FIFO_SW_BP_THRSLD_REG);
regs[529] = dsaf_read_dev(ppe_cb, PPE_CFG_PAUSE_IDLE_CNT_REG);
regs[530] = dsaf_read_dev(ppe_cb, PPE_CFG_BUS_CTRL_REG);
regs[531] = dsaf_read_dev(ppe_cb, PPE_CFG_TNL_TO_BE_RST_REG);
regs[532] = dsaf_read_dev(ppe_cb, PPE_CURR_TNL_CAN_RST_REG);
regs[533] = dsaf_read_dev(ppe_cb, PPE_CFG_XGE_MODE_REG);
regs[534] = dsaf_read_dev(ppe_cb, PPE_CFG_MAX_FRAME_LEN_REG);
regs[535] = dsaf_read_dev(ppe_cb, PPE_CFG_RX_PKT_MODE_REG);
regs[536] = dsaf_read_dev(ppe_cb, PPE_CFG_RX_VLAN_TAG_REG);
regs[537] = dsaf_read_dev(ppe_cb, PPE_CFG_TAG_GEN_REG);
regs[538] = dsaf_read_dev(ppe_cb, PPE_CFG_PARSE_TAG_REG);
regs[539] = dsaf_read_dev(ppe_cb, PPE_CFG_PRO_CHECK_EN_REG);
regs[540] = dsaf_read_dev(ppe_cb, PPE_INTEN_REG);
regs[541] = dsaf_read_dev(ppe_cb, PPE_RINT_REG);
regs[542] = dsaf_read_dev(ppe_cb, PPE_INTSTS_REG);
regs[543] = dsaf_read_dev(ppe_cb, PPE_CFG_RX_PKT_INT_REG);
regs[544] = dsaf_read_dev(ppe_cb, PPE_CFG_HEAT_DECT_TIME0_REG);
regs[545] = dsaf_read_dev(ppe_cb, PPE_CFG_HEAT_DECT_TIME1_REG);
/* ppe static */
regs[546] = dsaf_read_dev(ppe_cb, PPE_HIS_RX_SW_PKT_CNT_REG);
regs[547] = dsaf_read_dev(ppe_cb, PPE_HIS_RX_WR_BD_OK_PKT_CNT_REG);
regs[548] = dsaf_read_dev(ppe_cb, PPE_HIS_RX_PKT_NO_BUF_CNT_REG);
regs[549] = dsaf_read_dev(ppe_cb, PPE_HIS_TX_BD_CNT_REG);
regs[550] = dsaf_read_dev(ppe_cb, PPE_HIS_TX_PKT_CNT_REG);
regs[551] = dsaf_read_dev(ppe_cb, PPE_HIS_TX_PKT_OK_CNT_REG);
regs[552] = dsaf_read_dev(ppe_cb, PPE_HIS_TX_PKT_EPT_CNT_REG);
regs[553] = dsaf_read_dev(ppe_cb, PPE_HIS_TX_PKT_CS_FAIL_CNT_REG);
regs[554] = dsaf_read_dev(ppe_cb, PPE_HIS_RX_APP_BUF_FAIL_CNT_REG);
regs[555] = dsaf_read_dev(ppe_cb, PPE_HIS_RX_APP_BUF_WAIT_CNT_REG);
regs[556] = dsaf_read_dev(ppe_cb, PPE_HIS_RX_PKT_DROP_FUL_CNT_REG);
regs[557] = dsaf_read_dev(ppe_cb, PPE_HIS_RX_PKT_DROP_PRT_CNT_REG);
regs[558] = dsaf_read_dev(ppe_cb, PPE_TNL_0_5_CNT_CLR_CE_REG);
regs[559] = dsaf_read_dev(ppe_cb, PPE_CFG_AXI_DBG_REG);
regs[560] = dsaf_read_dev(ppe_cb, PPE_HIS_PRO_ERR_REG);
regs[561] = dsaf_read_dev(ppe_cb, PPE_HIS_TNL_FIFO_ERR_REG);
regs[562] = dsaf_read_dev(ppe_cb, PPE_CURR_CFF_DATA_NUM_REG);
regs[563] = dsaf_read_dev(ppe_cb, PPE_CURR_RX_ST_REG);
regs[564] = dsaf_read_dev(ppe_cb, PPE_CURR_TX_ST_REG);
regs[565] = dsaf_read_dev(ppe_cb, PPE_CURR_RX_FIFO0_REG);
regs[566] = dsaf_read_dev(ppe_cb, PPE_CURR_RX_FIFO1_REG);
regs[567] = dsaf_read_dev(ppe_cb, PPE_CURR_TX_FIFO0_REG);
regs[568] = dsaf_read_dev(ppe_cb, PPE_CURR_TX_FIFO1_REG);
regs[569] = dsaf_read_dev(ppe_cb, PPE_ECO0_REG);
regs[570] = dsaf_read_dev(ppe_cb, PPE_ECO1_REG);
regs[571] = dsaf_read_dev(ppe_cb, PPE_ECO2_REG);
/* mark end of ppe regs */
for (i = 572; i < 576; i++)
regs[i] = 0xeeeeeeee;
}
/*
* Copyright (c) 2014-2015 Hisilicon Limited.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#ifndef _HNS_DSAF_PPE_H
#define _HNS_DSAF_PPE_H
#include <linux/platform_device.h>
#include "hns_dsaf_main.h"
#include "hns_dsaf_mac.h"
#include "hns_dsaf_rcb.h"
#define HNS_PPE_SERVICE_NW_ENGINE_NUM DSAF_COMM_CHN
#define HNS_PPE_DEBUG_NW_ENGINE_NUM 1
#define HNS_PPE_COM_NUM DSAF_COMM_DEV_NUM
#define PPE_COMMON_REG_OFFSET 0x70000
#define PPE_REG_OFFSET 0x10000
#define ETH_PPE_DUMP_NUM 576
#define ETH_PPE_STATIC_NUM 12
enum ppe_qid_mode {
PPE_QID_MODE0 = 0, /* fixed queue id mode */
PPE_QID_MODE1, /* switch:128VM non switch:6Port/4VM/4TC */
PPE_QID_MODE2, /* switch:32VM/4TC non switch:6Port/16VM */
PPE_QID_MODE3, /* switch:4TC/8TAG non switch:2Port/64VM */
PPE_QID_MODE4, /* switch:8VM/16TAG non switch:2Port/16VM/4TC */
PPE_QID_MODE5, /* non switch:6Port/16TAG */
PPE_QID_MODE6, /* non switch:6Port/2VM/8TC */
PPE_QID_MODE7, /* non switch:2Port/8VM/8TC */
};
enum ppe_port_mode {
PPE_MODE_GE = 0,
PPE_MODE_XGE,
};
enum ppe_common_mode {
PPE_COMMON_MODE_DEBUG = 0,
PPE_COMMON_MODE_SERVICE,
PPE_COMMON_MODE_MAX
};
struct hns_ppe_hw_stats {
u64 rx_pkts_from_sw;
u64 rx_pkts;
u64 rx_drop_no_bd;
u64 rx_alloc_buf_fail;
u64 rx_alloc_buf_wait;
u64 rx_drop_no_buf;
u64 rx_err_fifo_full;
u64 tx_bd_form_rcb;
u64 tx_pkts_from_rcb;
u64 tx_pkts;
u64 tx_err_fifo_empty;
u64 tx_err_checksum;
};
struct hns_ppe_cb {
struct device *dev;
struct hns_ppe_cb *next; /* pointer to next ppe device */
struct ppe_common_cb *ppe_common_cb; /* belong to */
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;
};
struct ppe_common_cb {
struct device *dev;
struct dsaf_device *dsaf_dev;
void __iomem *io_base;
enum ppe_common_mode ppe_mode;
u8 comm_index; /*ppe_common index*/
u32 ppe_num;
struct hns_ppe_cb ppe_cb[0];
};
int hns_ppe_init(struct dsaf_device *dsaf_dev);
void hns_ppe_uninit(struct dsaf_device *dsaf_dev);
void hns_ppe_reset_common(struct dsaf_device *dsaf_dev, u8 ppe_common_index);
void hns_ppe_update_stats(struct hns_ppe_cb *ppe_cb);
int hns_ppe_get_sset_count(int stringset);
int hns_ppe_get_regs_count(void);
void hns_ppe_get_regs(struct hns_ppe_cb *ppe_cb, void *data);
void hns_ppe_get_strings(struct hns_ppe_cb *ppe_cb, int stringset, u8 *data);
void hns_ppe_get_stats(struct hns_ppe_cb *ppe_cb, u64 *data);
#endif /* _HNS_DSAF_PPE_H */
此差异已折叠。
/*
* Copyright (c) 2014-2015 Hisilicon Limited.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#ifndef _HNS_DSAF_RCB_H
#define _HNS_DSAF_RCB_H
#include <linux/netdevice.h>
#include <linux/platform_device.h>
#include "hnae.h"
#include "hns_dsaf_main.h"
struct rcb_common_cb;
#define HNS_RCB_IRQ_NUM_PER_QUEUE 2
#define HNS_RCB_IRQ_IDX_TX 0
#define HNS_RCB_IRQ_IDX_RX 1
#define HNS_RCB_TX_REG_OFFSET 0x40
#define HNS_RCB_SERVICE_NW_ENGINE_NUM DSAF_COMM_CHN
#define HNS_RCB_DEBUG_NW_ENGINE_NUM 1
#define HNS_RCB_RING_MAX_BD_PER_PKT 3
#define HNS_RCB_MAX_PKT_SIZE MAC_MAX_MTU
#define HNS_RCB_RING_MAX_PENDING_BD 1024
#define HNS_RCB_RING_MIN_PENDING_BD 16
#define HNS_RCB_REG_OFFSET 0x10000
#define HNS_RCB_MAX_COALESCED_FRAMES 1023
#define HNS_RCB_MIN_COALESCED_FRAMES 1
#define HNS_RCB_DEF_COALESCED_FRAMES 50
#define HNS_RCB_MAX_TIME_OUT 0x500
#define HNS_RCB_COMMON_ENDIAN 1
#define HNS_BD_SIZE_512_TYPE 0
#define HNS_BD_SIZE_1024_TYPE 1
#define HNS_BD_SIZE_2048_TYPE 2
#define HNS_BD_SIZE_4096_TYPE 3
#define HNS_RCB_COMMON_DUMP_REG_NUM 80
#define HNS_RCB_RING_DUMP_REG_NUM 40
#define HNS_RING_STATIC_REG_NUM 28
#define HNS_DUMP_REG_NUM 500
#define HNS_STATIC_REG_NUM 12
enum rcb_int_flag {
RCB_INT_FLAG_TX = 0x1,
RCB_INT_FLAG_RX = (0x1 << 1),
RCB_INT_FLAG_MAX = (0x1 << 2), /*must be the last element */
};
struct hns_ring_hw_stats {
u64 tx_pkts;
u64 ppe_tx_ok_pkts;
u64 ppe_tx_drop_pkts;
u64 rx_pkts;
u64 ppe_rx_ok_pkts;
u64 ppe_rx_drop_pkts;
};
struct ring_pair_cb {
struct rcb_common_cb *rcb_common; /* ring belongs to */
struct device *dev; /*device for DMA mapping */
struct hnae_queue q;
u16 index; /* global index in a rcb common device */
u16 buf_size;
int virq[HNS_RCB_IRQ_NUM_PER_QUEUE];
u8 port_id_in_dsa;
u8 used_by_vf;
struct hns_ring_hw_stats hw_stats;
};
struct rcb_common_cb {
u8 __iomem *io_base;
phys_addr_t phy_base;
struct dsaf_device *dsaf_dev;
u16 max_vfn;
u16 max_q_per_vf;
u8 comm_index;
u32 ring_num;
u32 coalesced_frames; /* frames threshold of rx interrupt */
u32 timeout; /* time threshold of rx interrupt */
u32 desc_num; /* desc num per queue*/
struct ring_pair_cb ring_pair_cb[0];
};
int hns_rcb_buf_size2type(u32 buf_size);
int hns_rcb_common_get_cfg(struct dsaf_device *dsaf_dev, int comm_index);
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_common_init_commit_hw(struct rcb_common_cb *rcb_common);
void hns_rcb_ring_enable_hw(struct hnae_queue *q, u32 val);
void hns_rcb_int_clr_hw(struct hnae_queue *q, u32 flag);
void hns_rcb_int_ctrl_hw(struct hnae_queue *q, u32 flag, u32 enable);
void hns_rcb_init_hw(struct ring_pair_cb *ring);
void hns_rcb_reset_ring_hw(struct hnae_queue *q);
void hns_rcb_wait_fbd_clean(struct hnae_queue **qs, int q_num, u32 flag);
u32 hns_rcb_get_coalesced_frames(struct dsaf_device *dsaf_dev, int comm_index);
u32 hns_rcb_get_coalesce_usecs(struct dsaf_device *dsaf_dev, int comm_index);
void hns_rcb_set_coalesce_usecs(struct dsaf_device *dsaf_dev,
int comm_index, u32 timeout);
int hns_rcb_set_coalesced_frames(struct dsaf_device *dsaf_dev,
int comm_index, u32 coalesce_frames);
void hns_rcb_update_stats(struct hnae_queue *queue);
void hns_rcb_get_stats(struct hnae_queue *queue, u64 *data);
void hns_rcb_get_common_regs(struct rcb_common_cb *rcb_common, void *data);
int hns_rcb_get_ring_sset_count(int stringset);
int hns_rcb_get_common_regs_count(void);
int hns_rcb_get_ring_regs_count(void);
void hns_rcb_get_ring_regs(struct hnae_queue *queue, void *data);
void hns_rcb_get_strings(int stringset, u8 *data, int index);
#endif /* _HNS_DSAF_RCB_H */
此差异已折叠。
此差异已折叠。
/*
* Copyright (c) 2014-2015 Hisilicon Limited.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#ifndef _HNS_XGMAC_H
#define _HNS_XGMAC_H
#define ETH_XGMAC_DUMP_NUM (214)
#endif
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册