Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1665287 > unrolled thread
| Started by | Salil Mehta <salil.mehta@huawei.com> |
|---|---|
| First post | 2017-06-14 01:20 +0200 |
| Last post | 2017-06-18 17:00 +0200 |
| Articles | 7 — 2 participants |
Back to article view | Back to linux.kernel
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
[PATCH V2 net-next 2/8] net: hns3: Add support of the HNAE3 framework Salil Mehta <salil.mehta@huawei.com> - 2017-06-14 01:20 +0200
Re: [PATCH V2 net-next 2/8] net: hns3: Add support of the HNAE3 framework Andrew Lunn <andrew@lunn.ch> - 2017-06-14 03:40 +0200
RE: [PATCH V2 net-next 2/8] net: hns3: Add support of the HNAE3 framework Salil Mehta <salil.mehta@huawei.com> - 2017-06-17 13:20 +0200
Re: [PATCH V2 net-next 2/8] net: hns3: Add support of the HNAE3 framework Andrew Lunn <andrew@lunn.ch> - 2017-06-14 03:40 +0200
RE: [PATCH V2 net-next 2/8] net: hns3: Add support of the HNAE3 framework Salil Mehta <salil.mehta@huawei.com> - 2017-06-17 13:20 +0200
Re: [PATCH V2 net-next 2/8] net: hns3: Add support of the HNAE3 framework Andrew Lunn <andrew@lunn.ch> - 2017-06-17 14:20 +0200
Re: [PATCH V2 net-next 2/8] net: hns3: Add support of the HNAE3 framework Andrew Lunn <andrew@lunn.ch> - 2017-06-18 17:00 +0200
| From | Salil Mehta <salil.mehta@huawei.com> |
|---|---|
| Date | 2017-06-14 01:20 +0200 |
| Subject | [PATCH V2 net-next 2/8] net: hns3: Add support of the HNAE3 framework |
| Message-ID | <tS3gn-5Od-43@gated-at.bofh.it> |
This patch adds the support of the HNAE3 (Hisilicon Network
Acceleration Engine 3) framework support to the HNS3 driver.
Framework facilitates clients like ENET(HNS3 Ethernet Driver), RoCE
and user-space Ethernet drivers (like ODP etc.) to register with HNAE3
devices and their associated operations.
Signed-off-by: Daode Huang <huangdaode@hisilicon.com>
Signed-off-by: lipeng <lipeng321@huawei.com>
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
Signed-off-by: Yisen Zhuang <yisen.zhuang@huawei.com>
---
drivers/net/ethernet/hisilicon/hns3/hnae3.c | 305 +++++++++++++++++++
drivers/net/ethernet/hisilicon/hns3/hnae3.h | 449 ++++++++++++++++++++++++++++
2 files changed, 754 insertions(+)
create mode 100644 drivers/net/ethernet/hisilicon/hns3/hnae3.c
create mode 100644 drivers/net/ethernet/hisilicon/hns3/hnae3.h
diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.c b/drivers/net/ethernet/hisilicon/hns3/hnae3.c
new file mode 100644
index 0000000..f133e1d
--- /dev/null
+++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.c
@@ -0,0 +1,305 @@
+/*
+ * Copyright (c) 2016-2017 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/slab.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+
+#include "hnae3.h"
+
+static LIST_HEAD(hnae3_ae_algo_list);
+static LIST_HEAD(hnae3_client_list);
+static LIST_HEAD(hnae3_ae_dev_list);
+
+static DEFINE_SPINLOCK(hnae3_list_ae_algo_lock);
+static DEFINE_SPINLOCK(hnae3_list_client_lock);
+static DEFINE_SPINLOCK(hnae3_list_ae_dev_lock);
+
+static void hnae3_list_add(spinlock_t *lock, struct list_head *node,
+ struct list_head *head)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(lock, flags);
+ list_add_tail_rcu(node, head);
+ spin_unlock_irqrestore(lock, flags);
+}
+
+static void hnae3_list_del(spinlock_t *lock, struct list_head *node)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(lock, flags);
+ list_del_rcu(node);
+ spin_unlock_irqrestore(lock, flags);
+}
+
+static bool hnae3_client_match(enum hnae3_client_type client_type,
+ enum hnae3_dev_type dev_type)
+{
+ if (dev_type == HNAE3_DEV_KNIC) {
+ switch (client_type) {
+ case HNAE3_CLIENT_KNIC:
+ case HNAE3_CLIENT_ROCE:
+ return true;
+ default:
+ return false;
+ }
+ } else if (dev_type == HNAE3_DEV_UNIC) {
+ switch (client_type) {
+ case HNAE3_CLIENT_UNIC:
+ return true;
+ default:
+ return false;
+ }
+ } else {
+ return false;
+ }
+}
+
+int hnae3_register_client(struct hnae3_client *client)
+{
+ struct hnae3_client *client_tmp;
+ struct hnae3_ae_dev *ae_dev;
+ int ret;
+
+ /* One system should only have one client for every type */
+ list_for_each_entry(client_tmp, &hnae3_client_list, node) {
+ if (client_tmp->type == client->type)
+ return 0;
+ }
+
+ hnae3_list_add(&hnae3_list_client_lock, &client->node,
+ &hnae3_client_list);
+
+ /* Check if there are matched ae_dev */
+ list_for_each_entry(ae_dev, &hnae3_ae_dev_list, node) {
+ if (hnae3_client_match(client->type, ae_dev->dev_type) &&
+ hnae_get_bit(ae_dev->flag, HNAE3_DEV_INITED_B)) {
+ if (ae_dev->ops && ae_dev->ops->register_client) {
+ ret = ae_dev->ops->register_client(client,
+ ae_dev);
+ if (ret) {
+ dev_err(&ae_dev->pdev->dev,
+ "init ae_dev error.\n");
+ return ret;
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(hnae3_register_client);
+
+void hnae3_unregister_client(struct hnae3_client *client)
+{
+ struct hnae3_ae_dev *ae_dev;
+
+ /* Check if there are matched ae_dev */
+ list_for_each_entry(ae_dev, &hnae3_ae_dev_list, node) {
+ if (hnae3_client_match(client->type, ae_dev->dev_type) &&
+ hnae_get_bit(ae_dev->flag, HNAE3_DEV_INITED_B))
+ if (ae_dev->ops && ae_dev->ops->unregister_client)
+ ae_dev->ops->unregister_client(client, ae_dev);
+ }
+ hnae3_list_del(&hnae3_list_client_lock, &client->node);
+}
+EXPORT_SYMBOL(hnae3_unregister_client);
+
+/* hnae_ae_register - register a AE engine to hnae framework
+ * @hdev: the hnae ae engine device
+ * @owner: the module who provides this dev
+ * NOTE: the duplicated name will not be checked
+ */
+int hnae3_register_ae_algo(struct hnae3_ae_algo *ae_algo)
+{
+ struct hnae3_ae_dev *ae_dev;
+ struct hnae3_client *client;
+ const struct pci_device_id *id;
+ int ret;
+
+ hnae3_list_add(&hnae3_list_ae_algo_lock, &ae_algo->node,
+ &hnae3_ae_algo_list);
+
+ /* Check if there are matched ae_dev */
+ list_for_each_entry(ae_dev, &hnae3_ae_dev_list, node) {
+ id = pci_match_id(ae_algo->pdev_id_table, ae_dev->pdev);
+ if (!id)
+ continue;
+
+ /* ae_dev init should set flag */
+ ae_dev->ops = ae_algo->ops;
+ ret = ae_algo->ops->init_ae_dev(ae_dev);
+ if (!ret) {
+ hnae_set_bit(ae_dev->flag, HNAE3_DEV_INITED_B, 1);
+ } else {
+ dev_err(&ae_dev->pdev->dev, "init ae_dev error.\n");
+ return ret;
+ }
+
+ list_for_each_entry(client, &hnae3_client_list, node) {
+ if (hnae3_client_match(client->type,
+ ae_dev->dev_type) &&
+ hnae_get_bit(ae_dev->flag, HNAE3_DEV_INITED_B)) {
+ if (ae_dev->ops &&
+ ae_dev->ops->register_client) {
+ ret = ae_dev->ops->register_client(
+ client, ae_dev);
+ if (ret) {
+ dev_err(&ae_dev->pdev->dev,
+ "init ae_dev error.\n");
+ return ret;
+ }
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(hnae3_register_ae_algo);
+
+/* hnae_ae_unregister - unregisters a HNAE AE engine
+ * @cdev: the device to unregister
+ */
+void hnae3_unregister_ae_algo(struct hnae3_ae_algo *ae_algo)
+{
+ struct hnae3_ae_dev *ae_dev;
+ struct hnae3_client *client;
+ const struct pci_device_id *id;
+
+ /* Check if there are matched ae_dev */
+ list_for_each_entry(ae_dev, &hnae3_ae_dev_list, node) {
+ id = pci_match_id(ae_algo->pdev_id_table, ae_dev->pdev);
+ if (!id)
+ continue;
+
+ /* Check if there are matched client */
+ list_for_each_entry(client, &hnae3_client_list, node) {
+ if (hnae3_client_match(client->type,
+ ae_dev->dev_type) &&
+ hnae_get_bit(ae_dev->flag, HNAE3_DEV_INITED_B)) {
+ hnae3_unregister_client(client);
+ continue;
+ }
+ }
+
+ ae_algo->ops->uninit_ae_dev(ae_dev);
+ hnae_set_bit(ae_dev->flag, HNAE3_DEV_INITED_B, 0);
+ }
+
+ hnae3_list_del(&hnae3_list_ae_algo_lock, &ae_algo->node);
+}
+EXPORT_SYMBOL(hnae3_unregister_ae_algo);
+
+/* hnae_ae_register - register a AE engine to hnae framework
+ * @hdev: the hnae ae engine device
+ * @owner: the module who provides this dev
+ * NOTE: the duplicated name will not be checked
+ */
+int hnae3_register_ae_dev(struct hnae3_ae_dev *ae_dev)
+{
+ struct hnae3_ae_algo *ae_algo;
+ struct hnae3_client *client;
+ const struct pci_device_id *id;
+ int ret;
+
+ hnae3_list_add(&hnae3_list_ae_dev_lock, &ae_dev->node,
+ &hnae3_ae_dev_list);
+
+ /* Check if there are matched ae_algo */
+ list_for_each_entry(ae_algo, &hnae3_ae_algo_list, node) {
+ id = pci_match_id(ae_algo->pdev_id_table, ae_dev->pdev);
+ if (!id)
+ continue;
+
+ ae_dev->ops = ae_algo->ops;
+
+ /* ae_dev init should set flag */
+ ret = ae_dev->ops->init_ae_dev(ae_dev);
+ if (!ret) {
+ hnae_set_bit(ae_dev->flag, HNAE3_DEV_INITED_B, 1);
+ break;
+ }
+
+ dev_err(&ae_dev->pdev->dev, "init ae_dev error.\n");
+ return ret;
+ }
+
+ if (!ae_dev->ops)
+ return 0;
+
+ list_for_each_entry(client, &hnae3_client_list, node) {
+ if (hnae3_client_match(client->type, ae_dev->dev_type) &&
+ hnae_get_bit(ae_dev->flag, HNAE3_DEV_INITED_B)) {
+ if (ae_dev->ops && ae_dev->ops->register_client) {
+ ret = ae_dev->ops->register_client(client,
+ ae_dev);
+ if (ret) {
+ dev_err(&ae_dev->pdev->dev,
+ "init ae_dev error.\n");
+ return ret;
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(hnae3_register_ae_dev);
+
+/* hnae_ae_unregister - unregisters a HNAE AE engine
+ * @cdev: the device to unregister
+ */
+void hnae3_unregister_ae_dev(struct hnae3_ae_dev *ae_dev)
+{
+ struct hnae3_ae_algo *ae_algo;
+ struct hnae3_client *client;
+ const struct pci_device_id *id;
+
+ /* Check if there are matched ae_algo */
+ list_for_each_entry(ae_algo, &hnae3_ae_algo_list, node) {
+ id = pci_match_id(ae_algo->pdev_id_table, ae_dev->pdev);
+ if (!id)
+ continue;
+
+ /* Check if there are matched client */
+ list_for_each_entry(client, &hnae3_client_list, node) {
+ if (hnae3_client_match(client->type,
+ ae_dev->dev_type) &&
+ hnae_get_bit(ae_dev->flag, HNAE3_DEV_INITED_B)) {
+ hnae3_unregister_client(client);
+ continue;
+ }
+ }
+
+ ae_algo->ops->uninit_ae_dev(ae_dev);
+ hnae_set_bit(ae_dev->flag, HNAE3_DEV_INITED_B, 0);
+ }
+
+ hnae3_list_del(&hnae3_list_ae_dev_lock, &ae_dev->node);
+}
+EXPORT_SYMBOL(hnae3_unregister_ae_dev);
+
+static int __init hnae3_init(void)
+{
+ return 0;
+}
+
+static void __exit hnae3_exit(void)
+{
+}
+
+subsys_initcall(hnae3_init);
+module_exit(hnae3_exit);
+
+MODULE_AUTHOR("Huawei Tech. Co., Ltd.");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("HNAE3(Hisilicon Network Acceleration Engine) Framework");
diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
new file mode 100644
index 0000000..2575f30
--- /dev/null
+++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
@@ -0,0 +1,449 @@
+/*
+ * Copyright (c) 2016-2017 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 __HNAE_H
+#define __HNAE_H
+
+/* Names used in this framework:
+ * ae handle (handle):
+ * a set of queues provided by AE
+ * ring buffer queue (rbq):
+ * the channel between upper layer and the AE, can do tx and rx
+ * ring:
+ * a tx or rx channel within a rbq
+ * ring description (desc):
+ * an element in the ring with packet information
+ * buffer:
+ * a memory region referred by desc with the full packet payload
+ *
+ * "num" means a static number set as a parameter, "count" mean a dynamic
+ * number set while running
+ * "cb" means control block
+ */
+
+#include <linux/acpi.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/pci.h>
+#include <linux/types.h>
+
+#define HNAE_DRIVER_VERSION "1.0"
+#define HNAE_DRIVER_NAME "hns3"
+#define HNAE_COPYRIGHT "Copyright(c) 2017 Huawei Corporation."
+#define HNAE_DRIVER_STRING "Hisilicon Network Subsystem Driver"
+#define HNAE_DEFAULT_DEVICE_DESCR "Hisilicon Network Subsystem"
+
+/* Device IDs */
+#define HISILICON 0x19E5
+#define HNAE3_DEV_ID_GE 0xA220
+#define HNAE3_DEV_ID_25GE 0xA221
+#define HNAE3_DEV_ID_25GE_RDMA 0xA222
+#define HNAE3_DEV_ID_25GE_RDMA_MACSEC 0xA223
+#define HNAE3_DEV_ID_50GE_RDMA 0xA224
+#define HNAE3_DEV_ID_50GE_RDMA_MACSEC 0xA225
+#define HNAE3_DEV_ID_100G_RDMA_MACSEC 0xA226
+#define HNAE3_DEV_ID_100G_VF 0xA22E
+#define HNAE3_DEV_ID_100G_RDMA_DCB_PFC_VF 0xA22F
+
+#define HNAE3_CLASS_NAME_SIZE 16
+
+#define HNAE3_DEV_INITED_B 0x0
+#define HNAE_DEV_SUPPORT_ROCE_B 0x1
+
+#define ring_ptr_move_fw(ring, p) \
+ ((ring)->p = ((ring)->p + 1) % (ring)->desc_num)
+#define ring_ptr_move_bw(ring, p) \
+ ((ring)->p = ((ring)->p - 1 + (ring)->desc_num) % (ring)->desc_num)
+
+enum hns_desc_type {
+ DESC_TYPE_SKB,
+ DESC_TYPE_PAGE,
+};
+
+struct hnae3_handle;
+
+struct hnae3_queue {
+ void __iomem *io_base;
+ struct hnae3_ae_algo *ae_algo;
+ struct hnae3_handle *handle;
+ int tqp_index; /* index in a handle */
+ u32 buf_size; /* size for hnae_desc->addr, preset by AE */
+ u16 desc_num; /* total number of desc */
+};
+
+/*hnae3 loop mode*/
+enum hnae3_loop {
+ HNAE3_MAC_INTER_LOOP_MAC,
+ HNAE3_MAC_INTER_LOOP_SERDES,
+ HNAE3_MAC_INTER_LOOP_PHY,
+ HNAE3_MAC_LOOP_NONE,
+};
+
+enum hnae3_client_type {
+ HNAE3_CLIENT_KNIC,
+ HNAE3_CLIENT_UNIC,
+ HNAE3_CLIENT_ROCE,
+};
+
+enum hnae3_dev_type {
+ HNAE3_DEV_KNIC,
+ HNAE3_DEV_UNIC,
+};
+
+/* mac media type */
+enum hnae3_media_type {
+ HNAE3_MEDIA_TYPE_UNKNOWN,
+ HNAE3_MEDIA_TYPE_FIBER,
+ HNAE3_MEDIA_TYPE_COPPER,
+ HNAE3_MEDIA_TYPE_BACKPLANE,
+};
+
+struct hnae3_vector_info {
+ u8 __iomem *io_addr;
+ int vector;
+};
+
+#define HNAE3_RING_TYPE_B 0
+#define HNAE3_RING_TYPE_TX 0
+#define HNAE3_RING_TYPE_RX 1
+
+struct hnae3_ring_chain_node {
+ struct hnae3_ring_chain_node *next;
+ u32 tqp_index;
+ u32 flag;
+};
+
+#define HNAE3_IS_TX_RING(node) \
+ (((node)->flag & (1 << HNAE3_RING_TYPE_B)) == HNAE3_RING_TYPE_TX)
+
+struct hnae3_client_ops {
+ int (*init_instance)(struct hnae3_handle *handle);
+ void (*uninit_instance)(struct hnae3_handle *handle, bool reset);
+ void (*link_status_change)(struct hnae3_handle *handle, bool state);
+};
+
+#define HNAE3_CLIENT_NAME_LENGTH 16
+struct hnae3_client {
+ char name[HNAE3_CLIENT_NAME_LENGTH];
+ u16 version;
+ unsigned long state;
+ enum hnae3_client_type type;
+ const struct hnae3_client_ops *ops;
+ struct list_head node;
+};
+
+struct hnae3_ae_dev {
+ struct pci_dev *pdev;
+ struct hnae3_ae_ops *ops;
+ struct list_head node;
+ u32 flag;
+ enum hnae3_dev_type dev_type;
+ void *priv;
+};
+
+/* This struct defines the operation on the handle.
+ *
+ * init_ae_dev(): (mandatory)
+ * Get PF configure from pci_dev and initialize PF hardware
+ * uninit_ae_dev()
+ * Disable PF device and release PF resource
+ * register_client
+ * Register client to ae_dev
+ * unregister_client()
+ * Unregister client from ae_dev
+ * start()
+ * Enable the hardware
+ * stop()
+ * Disable the hardware
+ * get_status()
+ * Get the carrier state of the back channel of the handle, 1 for ok, 0 for
+ * non-ok
+ * get_ksettings_an_result()
+ * Get negotiation status,speed and duplex
+ * update_speed_duplex_h()
+ * Update hardware speed and duplex
+ * get_media_type()
+ * Get media type of MAC
+ * adjust_link()
+ * Adjust link status
+ * set_loopback()
+ * Set loopback
+ * set_promisc_mode
+ * Set promisc mode
+ * set_mtu()
+ * set mtu
+ * get_pauseparam()
+ * get tx and rx of pause frame use
+ * set_pauseparam()
+ * set tx and rx of pause frame use
+ * set_autoneg()
+ * set auto autonegotiation of pause frame use
+ * get_autoneg()
+ * get auto autonegotiation of pause frame use
+ * get_coalesce_usecs()
+ * get usecs to delay a TX interrupt after a packet is sent
+ * get_rx_max_coalesced_frames()
+ * get Maximum number of packets to be sent before a TX interrupt.
+ * set_coalesce_usecs()
+ * set usecs to delay a TX interrupt after a packet is sent
+ * set_coalesce_frames()
+ * set Maximum number of packets to be sent before a TX interrupt.
+ * get_mac_addr()
+ * get mac address
+ * set_mac_addr()
+ * set mac address
+ * add_uc_addr
+ * Add unicast addr to mac table
+ * rm_uc_addr
+ * Remove unicast addr from mac table
+ * set_mc_addr()
+ * Set multicast address
+ * add_mc_addr
+ * Add multicast address to mac table
+ * rm_mc_addr
+ * Remove multicast address from mac table
+ * update_stats()
+ * Update Old network device statistics
+ * get_ethtool_stats()
+ * Get ethtool network device statistics
+ * get_strings()
+ * Get a set of strings that describe the requested objects
+ * get_sset_count()
+ * Get number of strings that @get_strings will write
+ * update_led_status()
+ * Update the led status
+ * set_led_id()
+ * Set led id
+ * get_regs()
+ * Get regs dump
+ * get_regs_len()
+ * Get the len of the regs dump
+ * get_rss_key_size()
+ * Get rss key size
+ * get_rss_indir_size()
+ * Get rss indirection table size
+ * get_rss()
+ * Get rss table
+ * set_rss()
+ * Set rss table
+ * get_tc_size()
+ * Get tc size of handle
+ * get_vector()
+ * Get vector number and vector infomation
+ * map_ring_to_vector()
+ * Map rings to vector
+ * unmap_ring_from_vector()
+ * Unmap rings from vector
+ * add_tunnel_udp()
+ * Add tunnel information to hardware
+ * del_tunnel_udp()
+ * Delete tunnel information from hardware
+ * reset_queue()
+ * Reset queue
+ * get_fw_version()
+ * Get firmware version
+ * get_mdix_mode()
+ * Get media typr of phy
+ * set_vlan_filter()
+ * Set vlan filter config of Ports
+ * set_vf_vlan_filter()
+ * Set vlan filter config of vf
+ */
+struct hnae3_ae_ops {
+ int (*init_ae_dev)(struct hnae3_ae_dev *ae_dev);
+ void (*uninit_ae_dev)(struct hnae3_ae_dev *ae_dev);
+
+ int (*register_client)(struct hnae3_client *client,
+ struct hnae3_ae_dev *ae_dev);
+ void (*unregister_client)(struct hnae3_client *client,
+ struct hnae3_ae_dev *ae_dev);
+ int (*start)(struct hnae3_handle *handle);
+ void (*stop)(struct hnae3_handle *handle);
+ int (*get_status)(struct hnae3_handle *handle);
+ void (*get_ksettings_an_result)(struct hnae3_handle *handle,
+ u8 *auto_neg, u32 *speed, u8 *duplex);
+
+ int (*update_speed_duplex_h)(struct hnae3_handle *handle);
+ int (*cfg_mac_speed_dup_h)(struct hnae3_handle *handle, int speed,
+ u8 duplex);
+
+ void (*get_media_type)(struct hnae3_handle *handle, u8 *media_type);
+ void (*adjust_link)(struct hnae3_handle *handle, int speed, int duplex);
+ int (*set_loopback)(struct hnae3_handle *handle,
+ enum hnae3_loop loop_mode, bool en);
+
+ void (*set_promisc_mode)(struct hnae3_handle *handle, u32 en);
+ int (*set_mtu)(struct hnae3_handle *handle, int new_mtu);
+
+ void (*get_pauseparam)(struct hnae3_handle *handle,
+ u32 *auto_neg, u32 *rx_en, u32 *tx_en);
+ int (*set_pauseparam)(struct hnae3_handle *handle,
+ u32 auto_neg, u32 rx_en, u32 tx_en);
+
+ int (*set_autoneg)(struct hnae3_handle *handle, bool enable);
+ int (*get_autoneg)(struct hnae3_handle *handle);
+
+ void (*get_coalesce_usecs)(struct hnae3_handle *handle,
+ u32 *tx_usecs, u32 *rx_usecs);
+ void (*get_rx_max_coalesced_frames)(struct hnae3_handle *handle,
+ u32 *tx_frames, u32 *rx_frames);
+ int (*set_coalesce_usecs)(struct hnae3_handle *handle, u32 timeout);
+ int (*set_coalesce_frames)(struct hnae3_handle *handle,
+ u32 coalesce_frames);
+ void (*get_coalesce_range)(struct hnae3_handle *handle,
+ u32 *tx_frames_low, u32 *rx_frames_low,
+ u32 *tx_frames_high, u32 *rx_frames_high,
+ u32 *tx_usecs_low, u32 *rx_usecs_low,
+ u32 *tx_usecs_high, u32 *rx_usecs_high);
+
+ void (*get_mac_addr)(struct hnae3_handle *handle, u8 *p);
+ int (*set_mac_addr)(struct hnae3_handle *handle, void *p);
+ int (*add_uc_addr)(struct hnae3_handle *handle,
+ const unsigned char *addr);
+ int (*rm_uc_addr)(struct hnae3_handle *handle,
+ const unsigned char *addr);
+ int (*set_mc_addr)(struct hnae3_handle *handle, void *addr);
+ int (*add_mc_addr)(struct hnae3_handle *handle,
+ const unsigned char *addr);
+ int (*rm_mc_addr)(struct hnae3_handle *handle,
+ const unsigned char *addr);
+
+ void (*set_tso_stats)(struct hnae3_handle *handle, int enable);
+ void (*update_stats)(struct hnae3_handle *handle,
+ struct net_device_stats *net_stats);
+ void (*get_stats)(struct hnae3_handle *handle, u64 *data);
+
+ void (*get_strings)(struct hnae3_handle *handle,
+ u32 stringset, u8 *data);
+ int (*get_sset_count)(struct hnae3_handle *handle, int stringset);
+
+ void (*get_regs)(struct hnae3_handle *handle, void *data);
+ int (*get_regs_len)(struct hnae3_handle *handle);
+
+ u32 (*get_rss_key_size)(struct hnae3_handle *handle);
+ u32 (*get_rss_indir_size)(struct hnae3_handle *handle);
+ int (*get_rss)(struct hnae3_handle *handle, u32 *indir, u8 *key,
+ u8 *hfunc);
+ int (*set_rss)(struct hnae3_handle *handle, const u32 *indir,
+ const u8 *key, const u8 hfunc);
+
+ int (*get_tc_size)(struct hnae3_handle *handle);
+
+ int (*get_vector)(struct hnae3_handle *handle, u16 vector_num,
+ struct hnae3_vector_info *vector_info);
+ int (*map_ring_to_vector)(struct hnae3_handle *handle,
+ int vector_num,
+ struct hnae3_ring_chain_node *vr_chain);
+ int (*unmap_ring_from_vector)(struct hnae3_handle *handle,
+ int vector_num,
+ struct hnae3_ring_chain_node *vr_chain);
+
+ int (*add_tunnel_udp)(struct hnae3_handle *handle, u16 port_num);
+ int (*del_tunnel_udp)(struct hnae3_handle *handle, u16 port_num);
+
+ void (*reset_queue)(struct hnae3_handle *handle, u16 queue_id);
+ u32 (*get_fw_version)(struct hnae3_handle *handle);
+ void (*get_mdix_mode)(struct hnae3_handle *handle,
+ u8 *tp_mdix_ctrl, u8 *tp_mdix);
+
+ int (*set_vlan_filter)(struct hnae3_handle *handle, __be16 proto,
+ u16 vlan_id, bool is_kill);
+ int (*set_vf_vlan_filter)(struct hnae3_handle *handle, int vfid,
+ u16 vlan, u8 qos, __be16 proto);
+};
+
+struct hnae3_ae_algo {
+ struct hnae3_ae_ops *ops;
+ struct list_head node;
+ char name[HNAE3_CLASS_NAME_SIZE];
+ const struct pci_device_id *pdev_id_table;
+};
+
+#define HNAE3_INT_NAME_LEN (IFNAMSIZ + 16)
+#define HNAE3_ITR_COUNTDOWN_START 100
+
+struct hnae3_tc_info {
+ u16 tqp_offset; /* TQP offset from base TQP */
+ u16 tqp_count; /* Total TQPs */
+ u8 up; /* user priority */
+ u8 tc; /* TC index */
+ bool enable; /* If this TC is enable or not */
+};
+
+#define HNAE3_MAX_TC 8
+struct hnae3_knic_private_info {
+ struct net_device *netdev; /* Set by KNIC client when init instance */
+ u16 rss_size; /* Allocated RSS queues */
+ u16 rx_buf_len;
+ u16 num_desc;
+
+ u8 num_tc; /* Total number of enabled TCs */
+ struct hnae3_tc_info tc_info[HNAE3_MAX_TC]; /* Idx of array is HW TC */
+
+ u16 num_tqps; /* total number of TQPs in this handle */
+ struct hnae3_queue **tqp; /* array base of all TQPs in this instance */
+};
+
+struct hnae3_roce_private_info {
+ void __iomem *roce_io_base;
+ struct net_device *netdev;
+ int base_vector;
+ int num_vectors;
+};
+
+struct hnae3_unic_private_info {
+ u16 rx_buf_len;
+ u16 num_desc;
+ u16 num_tqps; /* total number of tqps in this handle */
+ struct hnae3_queue **tqp; /* array base of all TQPs of this instance */
+};
+
+#define HNAE3_SUPPORT_MAC_LOOPBACK 1
+#define HNAE3_SUPPORT_PHY_LOOPBACK 2
+#define HNAE3_SUPPORT_SERDES_LOOPBACK 4
+
+struct hnae3_handle {
+ struct hnae3_client *client;
+ struct pci_dev *pdev;
+ void *priv;
+ struct hnae3_ae_algo *ae_algo; /* the class who provides this handle */
+ u64 flags; /* Indicate the capabilities for this handle*/
+
+ union {
+ struct hnae3_knic_private_info kinfo;
+ struct hnae3_unic_private_info uinfo;
+ struct hnae3_roce_private_info rinfo;
+ };
+
+ u32 numa_node_mask; /* for multi-chip support */
+};
+
+#define hnae_set_field(origin, mask, shift, val) \
+ do { \
+ (origin) &= (~(mask)); \
+ (origin) |= ((val) << (shift)) & (mask); \
+ } while (0)
+#define hnae_get_field(origin, mask, shift) (((origin) & (mask)) >> (shift))
+
+#define hnae_set_bit(origin, shift, val) \
+ hnae_set_field((origin), (0x1 << (shift)), (shift), (val))
+#define hnae_get_bit(origin, shift) \
+ hnae_get_field((origin), (0x1 << (shift)), (shift))
+
+int hnae3_register_ae_dev(struct hnae3_ae_dev *ae_dev);
+void hnae3_unregister_ae_dev(struct hnae3_ae_dev *ae_dev);
+
+void hnae3_unregister_ae_algo(struct hnae3_ae_algo *ae_algo);
+int hnae3_register_ae_algo(struct hnae3_ae_algo *ae_algo);
+
+void hnae3_unregister_client(struct hnae3_client *client);
+int hnae3_register_client(struct hnae3_client *client);
+#endif
--
2.7.4
[toc] | [next] | [standalone]
| From | Andrew Lunn <andrew@lunn.ch> |
|---|---|
| Date | 2017-06-14 03:40 +0200 |
| Subject | Re: [PATCH V2 net-next 2/8] net: hns3: Add support of the HNAE3 framework |
| Message-ID | <tS5rP-757-1@gated-at.bofh.it> |
| In reply to | #1665287 |
On Wed, Jun 14, 2017 at 12:10:29AM +0100, Salil Mehta wrote:
> This patch adds the support of the HNAE3 (Hisilicon Network
> Acceleration Engine 3) framework support to the HNS3 driver.
>
> Framework facilitates clients like ENET(HNS3 Ethernet Driver), RoCE
> and user-space Ethernet drivers (like ODP etc.) to register with HNAE3
> devices and their associated operations.
>
> Signed-off-by: Daode Huang <huangdaode@hisilicon.com>
> Signed-off-by: lipeng <lipeng321@huawei.com>
> Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
> Signed-off-by: Yisen Zhuang <yisen.zhuang@huawei.com>
> ---
> drivers/net/ethernet/hisilicon/hns3/hnae3.c | 305 +++++++++++++++++++
> drivers/net/ethernet/hisilicon/hns3/hnae3.h | 449 ++++++++++++++++++++++++++++
> 2 files changed, 754 insertions(+)
> create mode 100644 drivers/net/ethernet/hisilicon/hns3/hnae3.c
> create mode 100644 drivers/net/ethernet/hisilicon/hns3/hnae3.h
>
> diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.c b/drivers/net/ethernet/hisilicon/hns3/hnae3.c
> new file mode 100644
> index 0000000..f133e1d
> --- /dev/null
> +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.c
> @@ -0,0 +1,305 @@
> +/*
> + * Copyright (c) 2016-2017 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/slab.h>
> +#include <linux/list.h>
> +#include <linux/spinlock.h>
> +
> +#include "hnae3.h"
> +
> +static LIST_HEAD(hnae3_ae_algo_list);
> +static LIST_HEAD(hnae3_client_list);
> +static LIST_HEAD(hnae3_ae_dev_list);
> +
> +static DEFINE_SPINLOCK(hnae3_list_ae_algo_lock);
> +static DEFINE_SPINLOCK(hnae3_list_client_lock);
> +static DEFINE_SPINLOCK(hnae3_list_ae_dev_lock);
> +
> +static void hnae3_list_add(spinlock_t *lock, struct list_head *node,
> + struct list_head *head)
> +{
> + unsigned long flags;
> +
> + spin_lock_irqsave(lock, flags);
> + list_add_tail_rcu(node, head);
> + spin_unlock_irqrestore(lock, flags);
> +}
> +
> +static void hnae3_list_del(spinlock_t *lock, struct list_head *node)
> +{
> + unsigned long flags;
> +
> + spin_lock_irqsave(lock, flags);
> + list_del_rcu(node);
> + spin_unlock_irqrestore(lock, flags);
> +}
You have these two _rcu operations here, and no others. I don't see
any rcu_read_lock(), or call_rcu(), etc.
I'm not an RCU expert, but this looks odd to me.
Andrew
[toc] | [prev] | [next] | [standalone]
| From | Salil Mehta <salil.mehta@huawei.com> |
|---|---|
| Date | 2017-06-17 13:20 +0200 |
| Subject | RE: [PATCH V2 net-next 2/8] net: hns3: Add support of the HNAE3 framework |
| Message-ID | <tTjVL-6mI-9@gated-at.bofh.it> |
| In reply to | #1665357 |
Hi Andrew,
> -----Original Message-----
> From: Andrew Lunn [mailto:andrew@lunn.ch]
> Sent: Wednesday, June 14, 2017 2:32 AM
> To: Salil Mehta
> Cc: davem@davemloft.net; Zhuangyuzeng (Yisen); huangdaode; lipeng (Y);
> mehta.salil.lnk@gmail.com; netdev@vger.kernel.org; linux-
> kernel@vger.kernel.org; Linuxarm
> Subject: Re: [PATCH V2 net-next 2/8] net: hns3: Add support of the
> HNAE3 framework
>
> On Wed, Jun 14, 2017 at 12:10:29AM +0100, Salil Mehta wrote:
> > This patch adds the support of the HNAE3 (Hisilicon Network
> > Acceleration Engine 3) framework support to the HNS3 driver.
> >
> > Framework facilitates clients like ENET(HNS3 Ethernet Driver), RoCE
> > and user-space Ethernet drivers (like ODP etc.) to register with
> HNAE3
> > devices and their associated operations.
> >
> > Signed-off-by: Daode Huang <huangdaode@hisilicon.com>
> > Signed-off-by: lipeng <lipeng321@huawei.com>
> > Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
> > Signed-off-by: Yisen Zhuang <yisen.zhuang@huawei.com>
> > ---
> > drivers/net/ethernet/hisilicon/hns3/hnae3.c | 305
> +++++++++++++++++++
> > drivers/net/ethernet/hisilicon/hns3/hnae3.h | 449
> ++++++++++++++++++++++++++++
> > 2 files changed, 754 insertions(+)
> > create mode 100644 drivers/net/ethernet/hisilicon/hns3/hnae3.c
> > create mode 100644 drivers/net/ethernet/hisilicon/hns3/hnae3.h
> >
> > diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.c
> b/drivers/net/ethernet/hisilicon/hns3/hnae3.c
> > new file mode 100644
> > index 0000000..f133e1d
> > --- /dev/null
> > +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.c
> > @@ -0,0 +1,305 @@
> > +/*
> > + * Copyright (c) 2016-2017 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/slab.h>
> > +#include <linux/list.h>
> > +#include <linux/spinlock.h>
> > +
> > +#include "hnae3.h"
> > +
> > +static LIST_HEAD(hnae3_ae_algo_list);
> > +static LIST_HEAD(hnae3_client_list);
> > +static LIST_HEAD(hnae3_ae_dev_list);
> > +
> > +static DEFINE_SPINLOCK(hnae3_list_ae_algo_lock);
> > +static DEFINE_SPINLOCK(hnae3_list_client_lock);
> > +static DEFINE_SPINLOCK(hnae3_list_ae_dev_lock);
> > +
> > +static void hnae3_list_add(spinlock_t *lock, struct list_head *node,
> > + struct list_head *head)
> > +{
> > + unsigned long flags;
> > +
> > + spin_lock_irqsave(lock, flags);
> > + list_add_tail_rcu(node, head);
> > + spin_unlock_irqrestore(lock, flags);
> > +}
> > +
> > +static void hnae3_list_del(spinlock_t *lock, struct list_head *node)
> > +{
> > + unsigned long flags;
> > +
> > + spin_lock_irqsave(lock, flags);
> > + list_del_rcu(node);
> > + spin_unlock_irqrestore(lock, flags);
> > +}
>
>
> You have these two _rcu operations here, and no others. I don't see
> any rcu_read_lock(), or call_rcu(), etc.
>
> I'm not an RCU expert, but this looks odd to me.
>
> Andrew
Thanks for identifying this. I think we would be okay here even without
rcu version. Will change this.
Thanks
Salil
[toc] | [prev] | [next] | [standalone]
| From | Andrew Lunn <andrew@lunn.ch> |
|---|---|
| Date | 2017-06-14 03:40 +0200 |
| Subject | Re: [PATCH V2 net-next 2/8] net: hns3: Add support of the HNAE3 framework |
| Message-ID | <tS5rQ-757-3@gated-at.bofh.it> |
| In reply to | #1665287 |
On Wed, Jun 14, 2017 at 12:10:29AM +0100, Salil Mehta wrote:
> +static int __init hnae3_init(void)
> +{
> + return 0;
> +}
> +
..
> +subsys_initcall(hnae3_init);
And the point of this is?
Andrew
[toc] | [prev] | [next] | [standalone]
| From | Salil Mehta <salil.mehta@huawei.com> |
|---|---|
| Date | 2017-06-17 13:20 +0200 |
| Subject | RE: [PATCH V2 net-next 2/8] net: hns3: Add support of the HNAE3 framework |
| Message-ID | <tTjVL-6mI-3@gated-at.bofh.it> |
| In reply to | #1665358 |
Hi Andrew,
> -----Original Message-----
> From: Andrew Lunn [mailto:andrew@lunn.ch]
> Sent: Wednesday, June 14, 2017 2:38 AM
> To: Salil Mehta
> Cc: davem@davemloft.net; Zhuangyuzeng (Yisen); huangdaode; lipeng (Y);
> mehta.salil.lnk@gmail.com; netdev@vger.kernel.org; linux-
> kernel@vger.kernel.org; Linuxarm
> Subject: Re: [PATCH V2 net-next 2/8] net: hns3: Add support of the
> HNAE3 framework
>
> On Wed, Jun 14, 2017 at 12:10:29AM +0100, Salil Mehta wrote:
> > +static int __init hnae3_init(void)
> > +{
> > + return 0;
> > +}
> > +
>
> ..
>
> > +subsys_initcall(hnae3_init);
>
> And the point of this is?
>
> Andrew
This looks weird but not sure how we could have made sure HNAE is available before other
2 drivers could have loaded. Changing into module_init() means two other modules (dependent
upon hnae) if loaded first will experience load time linking problems. Do you think this
is okay?
Thanks
Salil
[toc] | [prev] | [next] | [standalone]
| From | Andrew Lunn <andrew@lunn.ch> |
|---|---|
| Date | 2017-06-17 14:20 +0200 |
| Subject | Re: [PATCH V2 net-next 2/8] net: hns3: Add support of the HNAE3 framework |
| Message-ID | <tTkRP-6Ya-1@gated-at.bofh.it> |
| In reply to | #1668226 |
> > > +subsys_initcall(hnae3_init); > > > > And the point of this is? > > > > Andrew > This looks weird but not sure how we could have made sure HNAE is available before other > 2 drivers could have loaded. Changing into module_init() means two other modules (dependent > upon hnae) if loaded first will experience load time linking problems. Do you think this > is okay? Often the best way to decide if something is sensible is to see if lots of other drivers do the same. Can you point to other drivers doing this? depmod/modprobe will actually sort this out for you. depmod looks at the symbols exported and required for each module and builds a dependency tree. When you modprobe a driver, it looks at the dependency tree, and loads any drivers needed in order to fulfil the dependencies. Andrew
[toc] | [prev] | [next] | [standalone]
| From | Andrew Lunn <andrew@lunn.ch> |
|---|---|
| Date | 2017-06-18 17:00 +0200 |
| Subject | Re: [PATCH V2 net-next 2/8] net: hns3: Add support of the HNAE3 framework |
| Message-ID | <tTJQe-6t2-15@gated-at.bofh.it> |
| In reply to | #1665287 |
On Wed, Jun 14, 2017 at 12:10:29AM +0100, Salil Mehta wrote:
> This patch adds the support of the HNAE3 (Hisilicon Network
> Acceleration Engine 3) framework support to the HNS3 driver.
>
> Framework facilitates clients like ENET(HNS3 Ethernet Driver), RoCE
> and user-space Ethernet drivers (like ODP etc.) to register with HNAE3
> devices and their associated operations.
checkpatch throws out one warning in this file
CHECK: Comparison to NULL could be written "pos"
#3508: FILE: drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.h:572:
+ for (pos = (head).ring; pos != NULL; pos = pos->next)
This one seems valid. Not all checkpatch warnings are.
Andrew
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web