Skip to content

Commit

Permalink
Merge branch 'hns3-next'
Browse files Browse the repository at this point in the history
Huazhong Tan says:

====================
hns3: provide new interfaces & bugfixes & code optimization

This patchset provides some reset interfaces for RAS & RoCE, also
some bugfixes and optimization related to reset.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Nov 7, 2018
2 parents 7c588c7 + 8b0195a commit 6a02d1f
Show file tree
Hide file tree
Showing 12 changed files with 544 additions and 180 deletions.
17 changes: 14 additions & 3 deletions drivers/net/ethernet/hisilicon/hns3/hnae3.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ struct hnae3_client_ops {
int (*setup_tc)(struct hnae3_handle *handle, u8 tc);
int (*reset_notify)(struct hnae3_handle *handle,
enum hnae3_reset_notify_type type);
enum hnae3_reset_type (*process_hw_error)(struct hnae3_handle *handle);
};

#define HNAE3_CLIENT_NAME_LENGTH 16
Expand Down Expand Up @@ -403,6 +404,8 @@ struct hnae3_ae_ops {
u16 vlan, u8 qos, __be16 proto);
int (*enable_hw_strip_rxvtag)(struct hnae3_handle *handle, bool enable);
void (*reset_event)(struct pci_dev *pdev, struct hnae3_handle *handle);
void (*set_default_reset_request)(struct hnae3_ae_dev *ae_dev,
enum hnae3_reset_type rst_type);
void (*get_channels)(struct hnae3_handle *handle,
struct ethtool_channels *ch);
void (*get_tqps_and_rss_info)(struct hnae3_handle *h,
Expand Down Expand Up @@ -430,6 +433,9 @@ struct hnae3_ae_ops {
int (*restore_fd_rules)(struct hnae3_handle *handle);
void (*enable_fd)(struct hnae3_handle *handle, bool enable);
pci_ers_result_t (*process_hw_error)(struct hnae3_ae_dev *ae_dev);
bool (*get_hw_reset_stat)(struct hnae3_handle *handle);
bool (*ae_dev_resetting)(struct hnae3_handle *handle);
unsigned long (*ae_dev_reset_cnt)(struct hnae3_handle *handle);
};

struct hnae3_dcb_ops {
Expand Down Expand Up @@ -488,6 +494,14 @@ struct hnae3_roce_private_info {
void __iomem *roce_io_base;
int base_vector;
int num_vectors;

/* The below attributes defined for RoCE client, hnae3 gives
* initial values to them, and RoCE client can modify and use
* them.
*/
unsigned long reset_state;
unsigned long instance_state;
unsigned long state;
};

struct hnae3_unic_private_info {
Expand Down Expand Up @@ -520,9 +534,6 @@ struct hnae3_handle {
struct hnae3_ae_algo *ae_algo; /* the class who provides this handle */
u64 flags; /* Indicate the capabilities for this handle*/

unsigned long last_reset_time;
enum hnae3_reset_type reset_level;

union {
struct net_device *netdev; /* first member */
struct hnae3_knic_private_info kinfo;
Expand Down
12 changes: 12 additions & 0 deletions drivers/net/ethernet/hisilicon/hns3/hns3_dcbnl.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ int hns3_dcbnl_ieee_getets(struct net_device *ndev, struct ieee_ets *ets)
{
struct hnae3_handle *h = hns3_get_handle(ndev);

if (hns3_nic_resetting(ndev))
return -EBUSY;

if (h->kinfo.dcb_ops->ieee_getets)
return h->kinfo.dcb_ops->ieee_getets(h, ets);

Expand All @@ -20,6 +23,9 @@ int hns3_dcbnl_ieee_setets(struct net_device *ndev, struct ieee_ets *ets)
{
struct hnae3_handle *h = hns3_get_handle(ndev);

if (hns3_nic_resetting(ndev))
return -EBUSY;

if (h->kinfo.dcb_ops->ieee_setets)
return h->kinfo.dcb_ops->ieee_setets(h, ets);

Expand All @@ -31,6 +37,9 @@ int hns3_dcbnl_ieee_getpfc(struct net_device *ndev, struct ieee_pfc *pfc)
{
struct hnae3_handle *h = hns3_get_handle(ndev);

if (hns3_nic_resetting(ndev))
return -EBUSY;

if (h->kinfo.dcb_ops->ieee_getpfc)
return h->kinfo.dcb_ops->ieee_getpfc(h, pfc);

Expand All @@ -42,6 +51,9 @@ int hns3_dcbnl_ieee_setpfc(struct net_device *ndev, struct ieee_pfc *pfc)
{
struct hnae3_handle *h = hns3_get_handle(ndev);

if (hns3_nic_resetting(ndev))
return -EBUSY;

if (h->kinfo.dcb_ops->ieee_setpfc)
return h->kinfo.dcb_ops->ieee_setpfc(h, pfc);

Expand Down
91 changes: 69 additions & 22 deletions drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,24 @@ static u16 hns3_get_max_available_channels(struct hnae3_handle *h)
return min_t(u16, rss_size, max_rss_size);
}

static void hns3_tqp_enable(struct hnae3_queue *tqp)
{
u32 rcb_reg;

rcb_reg = hns3_read_dev(tqp, HNS3_RING_EN_REG);
rcb_reg |= BIT(HNS3_RING_EN_B);
hns3_write_dev(tqp, HNS3_RING_EN_REG, rcb_reg);
}

static void hns3_tqp_disable(struct hnae3_queue *tqp)
{
u32 rcb_reg;

rcb_reg = hns3_read_dev(tqp, HNS3_RING_EN_REG);
rcb_reg &= ~BIT(HNS3_RING_EN_B);
hns3_write_dev(tqp, HNS3_RING_EN_REG, rcb_reg);
}

static int hns3_nic_net_up(struct net_device *netdev)
{
struct hns3_nic_priv *priv = netdev_priv(netdev);
Expand All @@ -334,6 +352,10 @@ static int hns3_nic_net_up(struct net_device *netdev)
for (i = 0; i < priv->vector_num; i++)
hns3_vector_enable(&priv->tqp_vector[i]);

/* enable rcb */
for (j = 0; j < h->kinfo.num_tqps; j++)
hns3_tqp_enable(h->kinfo.tqp[j]);

/* start the ae_dev */
ret = h->ae_algo->ops->start ? h->ae_algo->ops->start(h) : 0;
if (ret)
Expand All @@ -344,6 +366,9 @@ static int hns3_nic_net_up(struct net_device *netdev)
return 0;

out_start_err:
while (j--)
hns3_tqp_disable(h->kinfo.tqp[j]);

for (j = i - 1; j >= 0; j--)
hns3_vector_disable(&priv->tqp_vector[j]);

Expand All @@ -354,11 +379,13 @@ static int hns3_nic_net_up(struct net_device *netdev)

static int hns3_nic_net_open(struct net_device *netdev)
{
struct hns3_nic_priv *priv = netdev_priv(netdev);
struct hnae3_handle *h = hns3_get_handle(netdev);
struct hnae3_knic_private_info *kinfo;
int i, ret;

if (hns3_nic_resetting(netdev))
return -EBUSY;

netif_carrier_off(netdev);

ret = hns3_nic_set_real_num_queue(netdev);
Expand All @@ -378,13 +405,13 @@ static int hns3_nic_net_open(struct net_device *netdev)
kinfo->prio_tc[i]);
}

priv->ae_handle->last_reset_time = jiffies;
return 0;
}

static void hns3_nic_net_down(struct net_device *netdev)
{
struct hns3_nic_priv *priv = netdev_priv(netdev);
struct hnae3_handle *h = hns3_get_handle(netdev);
const struct hnae3_ae_ops *ops;
int i;

Expand All @@ -395,6 +422,10 @@ static void hns3_nic_net_down(struct net_device *netdev)
for (i = 0; i < priv->vector_num; i++)
hns3_vector_disable(&priv->tqp_vector[i]);

/* disable rcb */
for (i = 0; i < h->kinfo.num_tqps; i++)
hns3_tqp_disable(h->kinfo.tqp[i]);

/* stop ae_dev */
ops = priv->ae_handle->ae_algo->ops;
if (ops->stop)
Expand Down Expand Up @@ -1615,10 +1646,9 @@ static void hns3_nic_net_timeout(struct net_device *ndev)

priv->tx_timeout_count++;

if (time_before(jiffies, (h->last_reset_time + ndev->watchdog_timeo)))
return;

/* request the reset */
/* request the reset, and let the hclge to determine
* which reset level should be done
*/
if (h->ae_algo->ops->reset_event)
h->ae_algo->ops->reset_event(h->pdev, h);
}
Expand Down Expand Up @@ -3337,7 +3367,6 @@ static int hns3_client_init(struct hnae3_handle *handle)
priv->dev = &pdev->dev;
priv->netdev = netdev;
priv->ae_handle = handle;
priv->ae_handle->last_reset_time = jiffies;
priv->tx_timeout_count = 0;

handle->kinfo.netdev = netdev;
Expand All @@ -3357,11 +3386,6 @@ static int hns3_client_init(struct hnae3_handle *handle)
/* Carrier off reporting is important to ethtool even BEFORE open */
netif_carrier_off(netdev);

if (handle->flags & HNAE3_SUPPORT_VF)
handle->reset_level = HNAE3_VF_RESET;
else
handle->reset_level = HNAE3_FUNC_RESET;

ret = hns3_get_ring_config(priv);
if (ret) {
ret = -ENOMEM;
Expand Down Expand Up @@ -3397,6 +3421,8 @@ static int hns3_client_init(struct hnae3_handle *handle)
/* MTU range: (ETH_MIN_MTU(kernel default) - 9706) */
netdev->max_mtu = HNS3_MAX_MTU - (ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN);

set_bit(HNS3_NIC_STATE_INITED, &priv->state);

return ret;

out_reg_netdev_fail:
Expand All @@ -3423,6 +3449,11 @@ static void hns3_client_uninit(struct hnae3_handle *handle, bool reset)
if (netdev->reg_state != NETREG_UNINITIALIZED)
unregister_netdev(netdev);

if (!test_and_clear_bit(HNS3_NIC_STATE_INITED, &priv->state)) {
netdev_warn(netdev, "already uninitialized\n");
goto out_netdev_free;
}

hns3_del_all_fd_rules(netdev, true);

hns3_force_clear_all_rx_ring(handle);
Expand All @@ -3443,6 +3474,7 @@ static void hns3_client_uninit(struct hnae3_handle *handle, bool reset)

priv->ring_data = NULL;

out_netdev_free:
free_netdev(netdev);
}

Expand Down Expand Up @@ -3708,8 +3740,22 @@ static void hns3_restore_coal(struct hns3_nic_priv *priv)

static int hns3_reset_notify_down_enet(struct hnae3_handle *handle)
{
struct hnae3_ae_dev *ae_dev = pci_get_drvdata(handle->pdev);
struct hnae3_knic_private_info *kinfo = &handle->kinfo;
struct net_device *ndev = kinfo->netdev;
struct hns3_nic_priv *priv = netdev_priv(ndev);

if (test_and_set_bit(HNS3_NIC_STATE_RESETTING, &priv->state))
return 0;

/* it is cumbersome for hardware to pick-and-choose entries for deletion
* from table space. Hence, for function reset software intervention is
* required to delete the entries
*/
if (hns3_dev_ongoing_func_reset(ae_dev)) {
hns3_remove_hw_addr(ndev);
hns3_del_all_fd_rules(ndev, false);
}

if (!netif_running(ndev))
return 0;
Expand All @@ -3720,6 +3766,7 @@ static int hns3_reset_notify_down_enet(struct hnae3_handle *handle)
static int hns3_reset_notify_up_enet(struct hnae3_handle *handle)
{
struct hnae3_knic_private_info *kinfo = &handle->kinfo;
struct hns3_nic_priv *priv = netdev_priv(kinfo->netdev);
int ret = 0;

if (netif_running(kinfo->netdev)) {
Expand All @@ -3729,9 +3776,10 @@ static int hns3_reset_notify_up_enet(struct hnae3_handle *handle)
"hns net up fail, ret=%d!\n", ret);
return ret;
}
handle->last_reset_time = jiffies;
}

clear_bit(HNS3_NIC_STATE_RESETTING, &priv->state);

return ret;
}

Expand Down Expand Up @@ -3782,16 +3830,22 @@ static int hns3_reset_notify_init_enet(struct hnae3_handle *handle)
priv->ring_data = NULL;
}

set_bit(HNS3_NIC_STATE_INITED, &priv->state);

return ret;
}

static int hns3_reset_notify_uninit_enet(struct hnae3_handle *handle)
{
struct hnae3_ae_dev *ae_dev = pci_get_drvdata(handle->pdev);
struct net_device *netdev = handle->kinfo.netdev;
struct hns3_nic_priv *priv = netdev_priv(netdev);
int ret;

if (!test_bit(HNS3_NIC_STATE_INITED, &priv->state)) {
netdev_warn(netdev, "already uninitialized\n");
return 0;
}

hns3_force_clear_all_rx_ring(handle);

ret = hns3_nic_uninit_vector_data(priv);
Expand All @@ -3806,14 +3860,7 @@ static int hns3_reset_notify_uninit_enet(struct hnae3_handle *handle)
if (ret)
netdev_err(netdev, "uninit ring error\n");

/* it is cumbersome for hardware to pick-and-choose entries for deletion
* from table space. Hence, for function reset software intervention is
* required to delete the entries
*/
if (hns3_dev_ongoing_func_reset(ae_dev)) {
hns3_remove_hw_addr(netdev);
hns3_del_all_fd_rules(netdev, false);
}
clear_bit(HNS3_NIC_STATE_INITED, &priv->state);

return ret;
}
Expand Down
21 changes: 19 additions & 2 deletions drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ extern const char hns3_driver_version[];
enum hns3_nic_state {
HNS3_NIC_STATE_TESTING,
HNS3_NIC_STATE_RESETTING,
HNS3_NIC_STATE_REINITING,
HNS3_NIC_STATE_INITED,
HNS3_NIC_STATE_DOWN,
HNS3_NIC_STATE_DISABLED,
HNS3_NIC_STATE_REMOVING,
Expand Down Expand Up @@ -47,7 +47,7 @@ enum hns3_nic_state {
#define HNS3_RING_PREFETCH_EN_REG 0x0007C
#define HNS3_RING_CFG_VF_NUM_REG 0x00080
#define HNS3_RING_ASID_REG 0x0008C
#define HNS3_RING_RX_VM_REG 0x00090
#define HNS3_RING_EN_REG 0x00090
#define HNS3_RING_T0_BE_RST 0x00094
#define HNS3_RING_COULD_BE_RST 0x00098
#define HNS3_RING_WRR_WEIGHT_REG 0x0009c
Expand Down Expand Up @@ -194,6 +194,8 @@ enum hns3_nic_state {
#define HNS3_VECTOR_RL_OFFSET 0x900
#define HNS3_VECTOR_RL_EN_B 6

#define HNS3_RING_EN_B 0

enum hns3_pkt_l3t_type {
HNS3_L3T_NONE,
HNS3_L3T_IPV6,
Expand Down Expand Up @@ -577,6 +579,11 @@ static inline int is_ring_empty(struct hns3_enet_ring *ring)
return ring->next_to_use == ring->next_to_clean;
}

static inline u32 hns3_read_reg(void __iomem *base, u32 reg)
{
return readl(base + reg);
}

static inline void hns3_write_reg(void __iomem *base, u32 reg, u32 value)
{
u8 __iomem *reg_addr = READ_ONCE(base);
Expand All @@ -589,6 +596,16 @@ static inline bool hns3_dev_ongoing_func_reset(struct hnae3_ae_dev *ae_dev)
return (ae_dev && (ae_dev->reset_type == HNAE3_FUNC_RESET));
}

#define hns3_read_dev(a, reg) \
hns3_read_reg((a)->io_base, (reg))

static inline bool hns3_nic_resetting(struct net_device *netdev)
{
struct hns3_nic_priv *priv = netdev_priv(netdev);

return test_bit(HNS3_NIC_STATE_RESETTING, &priv->state);
}

#define hns3_write_dev(a, reg, value) \
hns3_write_reg((a)->io_base, (reg), (value))

Expand Down
Loading

0 comments on commit 6a02d1f

Please sign in to comment.