Skip to content

Commit

Permalink
Merge branch 'hip06-soc'
Browse files Browse the repository at this point in the history
Salil Mehta says:

====================
net:hns: Add support of Hip06 SoC to the Hislicon Network Subsystem

This PATCH V7 addresses the TAB formatting comments by
Sergei Shtylyov. Missing TABs at some other palces have
also been corrected.

PATCH V6:
This addresses the review comments provided by
David Miller over the existing use of ENABLE/DISABLE
hash defines with the code. These hash defines are doing
a similar job as implicit type bool would do. So these are
kind of duplicate and are redundant.

PATCH V5:
This PATCH addresses the review comments by Yuval Mintz
 <Yuval.Mintz@qlogic.com>. This rework of comments are basically
 related to:
 1) styling of the code,
 2) RSS default Key initiailization related code
 3) redundant code removal

PATCH V4:
This addresses the review comment provided by
Sergei Shtylyov. The changelog of every patch has also
been modified.

PATCH V3:
 Addresses the review comment floated by David Miller

PATCH V2:
1) Bug Fixes and Clean-up: Internally identified
2) Addresses internal review comments by Kenneth Lee and
   by Huang Daode
3) Addresses the review comment from "Yisen.Zhuang(Zhuangyuzeng)"
4) Adds fix from Fengguang Wu for an error generated from
   "kbuild test robot" from Intel
5) Ethtool support for TSO set option from Lisheng

PATCH V1:
Adds initial support of Hip06 SoC with below changes:
This patch-set adds support of new Hisilicon Hip06 SoC to the existing
(already part of net-next) HNS ethernet driver for Hip05 SoC. Hip06 is
a multi-core SoC and is a derivative of Hip05 SoC with lots of new
hardware featres supported like RSS, TSO, hardware VLAN assist etc.

The changes in the driver are mainly due to following:
 1) changes in the DMA descriptor provided by the Hip06 ethernet
    hardware. These changes need to co-exist with already present
    Hip05 DMA descriptor and its operating functions. The decision
    to choose the correct type of DMA descriptor is taken dynamically
    depending upon the version of the hardware (i.e. V1/hip05 or
    V2/hip06, see already existing hisilicon-hns-nic.txt binding file
    for the detailed description version and naming).
 2) To support new features added to the Hip06 ethernet hardware:
    a. RSS (Receive Side Scaling)
    b. TSO (TCP Segment Offload)
    c. Hardware VLAN support (currently we are initializing hardware
       to not assist in stripping the vlan tag at hardware level.
       Proper support of this feature and ethtool would come after
       these patches have been accepted)

Kindly note that, this patchset has been based on latest net-next.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Dec 4, 2015
2 parents ce3ea1c + 8044f97 commit 43dd7a8
Show file tree
Hide file tree
Showing 15 changed files with 1,127 additions and 256 deletions.
58 changes: 52 additions & 6 deletions drivers/net/ethernet/hisilicon/hns/hnae.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
#include <linux/phy.h>
#include <linux/types.h>

#define HNAE_DRIVER_VERSION "1.3.0"
#define HNAE_DRIVER_VERSION "2.0"
#define HNAE_DRIVER_NAME "hns"
#define HNAE_COPYRIGHT "Copyright(c) 2015 Huawei Corporation."
#define HNAE_DRIVER_STRING "Hisilicon Network Subsystem Driver"
Expand Down Expand Up @@ -63,6 +63,7 @@ do { \

#define AE_VERSION_1 ('6' << 16 | '6' << 8 | '0')
#define AE_VERSION_2 ('1' << 24 | '6' << 16 | '1' << 8 | '0')
#define AE_IS_VER1(ver) ((ver) == AE_VERSION_1)
#define AE_NAME_SIZE 16

/* some said the RX and TX RCB format should not be the same in the future. But
Expand Down Expand Up @@ -144,23 +145,61 @@ enum hnae_led_state {
#define HNS_RXD_ASID_S 24
#define HNS_RXD_ASID_M (0xff << HNS_RXD_ASID_S)

#define HNSV2_TXD_BUFNUM_S 0
#define HNSV2_TXD_BUFNUM_M (0x7 << HNSV2_TXD_BUFNUM_S)
#define HNSV2_TXD_RI_B 1
#define HNSV2_TXD_L4CS_B 2
#define HNSV2_TXD_L3CS_B 3
#define HNSV2_TXD_FE_B 4
#define HNSV2_TXD_VLD_B 5

#define HNSV2_TXD_TSE_B 0
#define HNSV2_TXD_VLAN_EN_B 1
#define HNSV2_TXD_SNAP_B 2
#define HNSV2_TXD_IPV6_B 3
#define HNSV2_TXD_SCTP_B 4

/* hardware spec ring buffer format */
struct __packed hnae_desc {
__le64 addr;
union {
struct {
__le16 asid_bufnum_pid;
union {
__le16 asid_bufnum_pid;
__le16 asid;
};
__le16 send_size;
__le32 flag_ipoffset;
__le32 reserved_3[4];
union {
__le32 flag_ipoffset;
struct {
__u8 bn_pid;
__u8 ra_ri_cs_fe_vld;
__u8 ip_offset;
__u8 tse_vlan_snap_v6_sctp_nth;
};
};
__le16 mss;
__u8 l4_len;
__u8 reserved1;
__le16 paylen;
__u8 vmid;
__u8 qid;
__le32 reserved2[2];
} tx;

struct {
__le32 ipoff_bnum_pid_flag;
__le16 pkt_len;
__le16 size;
__le32 vlan_pri_asid;
__le32 reserved_2[3];
union {
__le32 vlan_pri_asid;
struct {
__le16 asid;
__le16 vlan_cfi_pri;
};
};
__le32 rss_hash;
__le32 reserved_1[2];
} rx;
};
};
Expand Down Expand Up @@ -435,6 +474,7 @@ struct hnae_ae_ops {
int (*set_mac_addr)(struct hnae_handle *handle, void *p);
int (*set_mc_addr)(struct hnae_handle *handle, void *addr);
int (*set_mtu)(struct hnae_handle *handle, int new_mtu);
void (*set_tso_stats)(struct hnae_handle *handle, int enable);
void (*update_stats)(struct hnae_handle *handle,
struct net_device_stats *net_stats);
void (*get_stats)(struct hnae_handle *handle, u64 *data);
Expand All @@ -446,6 +486,12 @@ struct hnae_ae_ops {
enum hnae_led_state status);
void (*get_regs)(struct hnae_handle *handle, void *data);
int (*get_regs_len)(struct hnae_handle *handle);
u32 (*get_rss_key_size)(struct hnae_handle *handle);
u32 (*get_rss_indir_size)(struct hnae_handle *handle);
int (*get_rss)(struct hnae_handle *handle, u32 *indir, u8 *key,
u8 *hfunc);
int (*set_rss)(struct hnae_handle *handle, const u32 *indir,
const u8 *key, const u8 hfunc);
};

struct hnae_ae_dev {
Expand Down
98 changes: 93 additions & 5 deletions drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ static int hns_ae_set_multicast_one(struct hnae_handle *handle, void *addr)
if (mac_cb->mac_type != HNAE_PORT_SERVICE)
return 0;

ret = hns_mac_set_multi(mac_cb, mac_cb->mac_id, mac_addr, ENABLE);
ret = hns_mac_set_multi(mac_cb, mac_cb->mac_id, mac_addr, true);
if (ret) {
dev_err(handle->owner_dev,
"mac add mul_mac:%pM port%d fail, ret = %#x!\n",
Expand All @@ -261,7 +261,7 @@ static int hns_ae_set_multicast_one(struct hnae_handle *handle, void *addr)
}

ret = hns_mac_set_multi(mac_cb, DSAF_BASE_INNER_PORT_NUM,
mac_addr, ENABLE);
mac_addr, true);
if (ret)
dev_err(handle->owner_dev,
"mac add mul_mac:%pM port%d fail, ret = %#x!\n",
Expand All @@ -277,12 +277,19 @@ static int hns_ae_set_mtu(struct hnae_handle *handle, int new_mtu)
return hns_mac_set_mtu(mac_cb, new_mtu);
}

static void hns_ae_set_tso_stats(struct hnae_handle *handle, int enable)
{
struct hns_ppe_cb *ppe_cb = hns_get_ppe_cb(handle);

hns_ppe_set_tso_enable(ppe_cb, enable);
}

static int hns_ae_start(struct hnae_handle *handle)
{
int ret;
struct hns_mac_cb *mac_cb = hns_get_mac_cb(handle);

ret = hns_mac_vm_config_bc_en(mac_cb, 0, ENABLE);
ret = hns_mac_vm_config_bc_en(mac_cb, 0, true);
if (ret)
return ret;

Expand All @@ -309,7 +316,7 @@ void hns_ae_stop(struct hnae_handle *handle)

hns_ae_ring_enable_all(handle, 0);

(void)hns_mac_vm_config_bc_en(mac_cb, 0, DISABLE);
(void)hns_mac_vm_config_bc_en(mac_cb, 0, false);
}

static void hns_ae_reset(struct hnae_handle *handle)
Expand Down Expand Up @@ -338,8 +345,27 @@ void hns_ae_toggle_ring_irq(struct hnae_ring *ring, u32 mask)
hns_rcb_int_ctrl_hw(ring->q, flag, mask);
}

static void hns_aev2_toggle_ring_irq(struct hnae_ring *ring, u32 mask)
{
u32 flag;

if (is_tx_ring(ring))
flag = RCB_INT_FLAG_TX;
else
flag = RCB_INT_FLAG_RX;

hns_rcbv2_int_ctrl_hw(ring->q, flag, mask);
}

static void hns_ae_toggle_queue_status(struct hnae_queue *queue, u32 val)
{
struct dsaf_device *dsaf_dev = hns_ae_get_dsaf_dev(queue->dev);

if (AE_IS_VER1(dsaf_dev->dsaf_ver))
hns_rcb_int_clr_hw(queue, RCB_INT_FLAG_TX | RCB_INT_FLAG_RX);
else
hns_rcbv2_int_clr_hw(queue, RCB_INT_FLAG_TX | RCB_INT_FLAG_RX);

hns_rcb_start(queue, val);
}

Expand Down Expand Up @@ -730,6 +756,53 @@ int hns_ae_get_regs_len(struct hnae_handle *handle)
return total_num;
}

static u32 hns_ae_get_rss_key_size(struct hnae_handle *handle)
{
return HNS_PPEV2_RSS_KEY_SIZE;
}

static u32 hns_ae_get_rss_indir_size(struct hnae_handle *handle)
{
return HNS_PPEV2_RSS_IND_TBL_SIZE;
}

static int hns_ae_get_rss(struct hnae_handle *handle, u32 *indir, u8 *key,
u8 *hfunc)
{
struct hns_ppe_cb *ppe_cb = hns_get_ppe_cb(handle);

/* currently we support only one type of hash function i.e. Toep hash */
if (hfunc)
*hfunc = ETH_RSS_HASH_TOP;

/* get the RSS Key required by the user */
if (key)
memcpy(key, ppe_cb->rss_key, HNS_PPEV2_RSS_KEY_SIZE);

/* update the current hash->queue mappings from the shadow RSS table */
memcpy(indir, ppe_cb->rss_indir_table, HNS_PPEV2_RSS_IND_TBL_SIZE);

return 0;
}

static int hns_ae_set_rss(struct hnae_handle *handle, const u32 *indir,
const u8 *key, const u8 hfunc)
{
struct hns_ppe_cb *ppe_cb = hns_get_ppe_cb(handle);

/* set the RSS Hash Key if specififed by the user */
if (key)
hns_ppe_set_rss_key(ppe_cb, (int *)key);

/* update the shadow RSS table with user specified qids */
memcpy(ppe_cb->rss_indir_table, indir, HNS_PPEV2_RSS_IND_TBL_SIZE);

/* now update the hardware */
hns_ppe_set_indir_table(ppe_cb, ppe_cb->rss_indir_table);

return 0;
}

static struct hnae_ae_ops hns_dsaf_ops = {
.get_handle = hns_ae_get_handle,
.put_handle = hns_ae_put_handle,
Expand Down Expand Up @@ -758,19 +831,34 @@ static struct hnae_ae_ops hns_dsaf_ops = {
.set_mc_addr = hns_ae_set_multicast_one,
.set_mtu = hns_ae_set_mtu,
.update_stats = hns_ae_update_stats,
.set_tso_stats = hns_ae_set_tso_stats,
.get_stats = hns_ae_get_stats,
.get_strings = hns_ae_get_strings,
.get_sset_count = hns_ae_get_sset_count,
.update_led_status = hns_ae_update_led_status,
.set_led_id = hns_ae_cpld_set_led_id,
.get_regs = hns_ae_get_regs,
.get_regs_len = hns_ae_get_regs_len
.get_regs_len = hns_ae_get_regs_len,
.get_rss_key_size = hns_ae_get_rss_key_size,
.get_rss_indir_size = hns_ae_get_rss_indir_size,
.get_rss = hns_ae_get_rss,
.set_rss = hns_ae_set_rss
};

int hns_dsaf_ae_init(struct dsaf_device *dsaf_dev)
{
struct hnae_ae_dev *ae_dev = &dsaf_dev->ae_dev;

switch (dsaf_dev->dsaf_ver) {
case AE_VERSION_1:
hns_dsaf_ops.toggle_ring_irq = hns_ae_toggle_ring_irq;
break;
case AE_VERSION_2:
hns_dsaf_ops.toggle_ring_irq = hns_aev2_toggle_ring_irq;
break;
default:
break;
}
ae_dev->ops = &hns_dsaf_ops;
ae_dev->dev = dsaf_dev->dev;

Expand Down
14 changes: 7 additions & 7 deletions drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ int hns_mac_change_vf_addr(struct hns_mac_cb *mac_cb,
}

int hns_mac_set_multi(struct hns_mac_cb *mac_cb,
u32 port_num, char *addr, u8 en)
u32 port_num, char *addr, bool enable)
{
int ret;
struct dsaf_device *dsaf_dev = mac_cb->dsaf_dev;
Expand All @@ -295,7 +295,7 @@ int hns_mac_set_multi(struct hns_mac_cb *mac_cb,
mac_entry.in_port_num = mac_cb->mac_id;
mac_entry.port_num = port_num;

if (en == DISABLE)
if (!enable)
ret = hns_dsaf_del_mac_mc_port(dsaf_dev, &mac_entry);
else
ret = hns_dsaf_add_mac_mc_port(dsaf_dev, &mac_entry);
Expand Down Expand Up @@ -368,7 +368,7 @@ static void hns_mac_param_get(struct mac_params *param,
*retuen 0 - success , negative --fail
*/
static int hns_mac_port_config_bc_en(struct hns_mac_cb *mac_cb,
u32 port_num, u16 vlan_id, u8 en)
u32 port_num, u16 vlan_id, bool enable)
{
int ret;
struct dsaf_device *dsaf_dev = mac_cb->dsaf_dev;
Expand All @@ -386,7 +386,7 @@ static int hns_mac_port_config_bc_en(struct hns_mac_cb *mac_cb,
mac_entry.in_port_num = mac_cb->mac_id;
mac_entry.port_num = port_num;

if (en == DISABLE)
if (!enable)
ret = hns_dsaf_del_mac_mc_port(dsaf_dev, &mac_entry);
else
ret = hns_dsaf_add_mac_mc_port(dsaf_dev, &mac_entry);
Expand All @@ -403,7 +403,7 @@ static int hns_mac_port_config_bc_en(struct hns_mac_cb *mac_cb,
*@en:enable
*retuen 0 - success , negative --fail
*/
int hns_mac_vm_config_bc_en(struct hns_mac_cb *mac_cb, u32 vmid, u8 en)
int hns_mac_vm_config_bc_en(struct hns_mac_cb *mac_cb, u32 vmid, bool enable)
{
int ret;
struct dsaf_device *dsaf_dev = mac_cb->dsaf_dev;
Expand All @@ -427,7 +427,7 @@ int hns_mac_vm_config_bc_en(struct hns_mac_cb *mac_cb, u32 vmid, u8 en)
return ret;
mac_entry.port_num = port_num;

if (en == DISABLE)
if (!enable)
ret = hns_dsaf_del_mac_mc_port(dsaf_dev, &mac_entry);
else
ret = hns_dsaf_add_mac_mc_port(dsaf_dev, &mac_entry);
Expand Down Expand Up @@ -648,7 +648,7 @@ static int hns_mac_init_ex(struct hns_mac_cb *mac_cb)

hns_mac_adjust_link(mac_cb, mac_cb->speed, !mac_cb->half_duplex);

ret = hns_mac_port_config_bc_en(mac_cb, mac_cb->mac_id, 0, ENABLE);
ret = hns_mac_port_config_bc_en(mac_cb, mac_cb->mac_id, 0, true);
if (ret)
goto free_mac_drv;

Expand Down
4 changes: 2 additions & 2 deletions drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h
Original file line number Diff line number Diff line change
Expand Up @@ -425,8 +425,8 @@ 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);
u32 port_num, char *addr, bool enable);
int hns_mac_vm_config_bc_en(struct hns_mac_cb *mac_cb, u32 vm, bool enable);
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);
Expand Down
Loading

0 comments on commit 43dd7a8

Please sign in to comment.