Skip to content

Commit

Permalink
net: wangxun: Move MAC address handling to libwx
Browse files Browse the repository at this point in the history
For setting MAC address, both txgbe and ngbe drivers have the same handling
flow with different parameters. Move the same codes to libwx.

Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  • Loading branch information
Jiawen Wu authored and Jakub Kicinski committed Jan 7, 2023
1 parent 92710fe commit 79625f4
Show file tree
Hide file tree
Showing 7 changed files with 151 additions and 212 deletions.
116 changes: 111 additions & 5 deletions drivers/net/ethernet/wangxun/libwx/wx_hw.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
/* Copyright (c) 2015 - 2022 Beijing WangXun Technology Co., Ltd. */

#include <linux/etherdevice.h>
#include <linux/netdevice.h>
#include <linux/if_ether.h>
#include <linux/iopoll.h>
#include <linux/pci.h>
Expand Down Expand Up @@ -536,8 +537,8 @@ EXPORT_SYMBOL(wx_get_mac_addr);
*
* Puts an ethernet address into a receive address register.
**/
int wx_set_rar(struct wx_hw *wxhw, u32 index, u8 *addr, u64 pools,
u32 enable_addr)
static int wx_set_rar(struct wx_hw *wxhw, u32 index, u8 *addr, u64 pools,
u32 enable_addr)
{
u32 rar_entries = wxhw->mac.num_rar_entries;
u32 rar_low, rar_high;
Expand Down Expand Up @@ -581,7 +582,6 @@ int wx_set_rar(struct wx_hw *wxhw, u32 index, u8 *addr, u64 pools,

return 0;
}
EXPORT_SYMBOL(wx_set_rar);

/**
* wx_clear_rar - Remove Rx address register
Expand All @@ -590,7 +590,7 @@ EXPORT_SYMBOL(wx_set_rar);
*
* Clears an ethernet address from a receive address register.
**/
int wx_clear_rar(struct wx_hw *wxhw, u32 index)
static int wx_clear_rar(struct wx_hw *wxhw, u32 index)
{
u32 rar_entries = wxhw->mac.num_rar_entries;

Expand Down Expand Up @@ -618,7 +618,6 @@ int wx_clear_rar(struct wx_hw *wxhw, u32 index)

return 0;
}
EXPORT_SYMBOL(wx_clear_rar);

/**
* wx_clear_vmdq - Disassociate a VMDq pool index from a rx address
Expand Down Expand Up @@ -722,6 +721,105 @@ void wx_init_rx_addrs(struct wx_hw *wxhw)
}
EXPORT_SYMBOL(wx_init_rx_addrs);

static void wx_sync_mac_table(struct wx_hw *wxhw)
{
int i;

for (i = 0; i < wxhw->mac.num_rar_entries; i++) {
if (wxhw->mac_table[i].state & WX_MAC_STATE_MODIFIED) {
if (wxhw->mac_table[i].state & WX_MAC_STATE_IN_USE) {
wx_set_rar(wxhw, i,
wxhw->mac_table[i].addr,
wxhw->mac_table[i].pools,
WX_PSR_MAC_SWC_AD_H_AV);
} else {
wx_clear_rar(wxhw, i);
}
wxhw->mac_table[i].state &= ~(WX_MAC_STATE_MODIFIED);
}
}
}

/* this function destroys the first RAR entry */
void wx_mac_set_default_filter(struct wx_hw *wxhw, u8 *addr)
{
memcpy(&wxhw->mac_table[0].addr, addr, ETH_ALEN);
wxhw->mac_table[0].pools = 1ULL;
wxhw->mac_table[0].state = (WX_MAC_STATE_DEFAULT | WX_MAC_STATE_IN_USE);
wx_set_rar(wxhw, 0, wxhw->mac_table[0].addr,
wxhw->mac_table[0].pools,
WX_PSR_MAC_SWC_AD_H_AV);
}
EXPORT_SYMBOL(wx_mac_set_default_filter);

void wx_flush_sw_mac_table(struct wx_hw *wxhw)
{
u32 i;

for (i = 0; i < wxhw->mac.num_rar_entries; i++) {
if (!(wxhw->mac_table[i].state & WX_MAC_STATE_IN_USE))
continue;

wxhw->mac_table[i].state |= WX_MAC_STATE_MODIFIED;
wxhw->mac_table[i].state &= ~WX_MAC_STATE_IN_USE;
memset(wxhw->mac_table[i].addr, 0, ETH_ALEN);
wxhw->mac_table[i].pools = 0;
}
wx_sync_mac_table(wxhw);
}
EXPORT_SYMBOL(wx_flush_sw_mac_table);

static int wx_del_mac_filter(struct wx_hw *wxhw, u8 *addr, u16 pool)
{
u32 i;

if (is_zero_ether_addr(addr))
return -EINVAL;

/* search table for addr, if found, set to 0 and sync */
for (i = 0; i < wxhw->mac.num_rar_entries; i++) {
if (!ether_addr_equal(addr, wxhw->mac_table[i].addr))
continue;

wxhw->mac_table[i].state |= WX_MAC_STATE_MODIFIED;
wxhw->mac_table[i].pools &= ~(1ULL << pool);
if (!wxhw->mac_table[i].pools) {
wxhw->mac_table[i].state &= ~WX_MAC_STATE_IN_USE;
memset(wxhw->mac_table[i].addr, 0, ETH_ALEN);
}
wx_sync_mac_table(wxhw);
return 0;
}
return -ENOMEM;
}

/**
* wx_set_mac - Change the Ethernet Address of the NIC
* @netdev: network interface device structure
* @p: pointer to an address structure
*
* Returns 0 on success, negative on failure
**/
int wx_set_mac(struct net_device *netdev, void *p)
{
struct wx_hw *wxhw = container_of(&netdev, struct wx_hw, netdev);
struct sockaddr *addr = p;
int retval;

retval = eth_prepare_mac_addr_change(netdev, addr);
if (retval)
return retval;

wx_del_mac_filter(wxhw, wxhw->mac.addr, 0);
eth_hw_addr_set(netdev, addr->sa_data);
memcpy(wxhw->mac.addr, addr->sa_data, netdev->addr_len);

wx_mac_set_default_filter(wxhw, wxhw->mac.addr);

return 0;
}
EXPORT_SYMBOL(wx_set_mac);

void wx_disable_rx(struct wx_hw *wxhw)
{
u32 pfdtxgswc;
Expand Down Expand Up @@ -929,6 +1027,14 @@ int wx_sw_init(struct wx_hw *wxhw)
return err;
}

wxhw->mac_table = kcalloc(wxhw->mac.num_rar_entries,
sizeof(struct wx_mac_addr),
GFP_KERNEL);
if (!wxhw->mac_table) {
wx_err(wxhw, "mac_table allocation failed\n");
return -ENOMEM;
}

return 0;
}
EXPORT_SYMBOL(wx_sw_init);
Expand Down
5 changes: 3 additions & 2 deletions drivers/net/ethernet/wangxun/libwx/wx_hw.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ int wx_read_ee_hostif_buffer(struct wx_hw *wxhw,
int wx_reset_hostif(struct wx_hw *wxhw);
void wx_init_eeprom_params(struct wx_hw *wxhw);
void wx_get_mac_addr(struct wx_hw *wxhw, u8 *mac_addr);
int wx_set_rar(struct wx_hw *wxhw, u32 index, u8 *addr, u64 pools, u32 enable_addr);
int wx_clear_rar(struct wx_hw *wxhw, u32 index);
void wx_init_rx_addrs(struct wx_hw *wxhw);
void wx_mac_set_default_filter(struct wx_hw *wxhw, u8 *addr);
void wx_flush_sw_mac_table(struct wx_hw *wxhw);
int wx_set_mac(struct net_device *netdev, void *p);
void wx_disable_rx(struct wx_hw *wxhw);
int wx_disable_pcie_master(struct wx_hw *wxhw);
int wx_stop_adapter(struct wx_hw *wxhw);
Expand Down
12 changes: 12 additions & 0 deletions drivers/net/ethernet/wangxun/libwx/wx_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,10 @@

#define WX_SW_REGION_PTR 0x1C

#define WX_MAC_STATE_DEFAULT 0x1
#define WX_MAC_STATE_MODIFIED 0x2
#define WX_MAC_STATE_IN_USE 0x4

/* Host Interface Command Structures */
struct wx_hic_hdr {
u8 cmd;
Expand Down Expand Up @@ -284,6 +288,12 @@ struct wx_addr_filter_info {
bool user_set_promisc;
};

struct wx_mac_addr {
u8 addr[ETH_ALEN];
u16 state; /* bitmask */
u64 pools;
};

enum wx_reset_type {
WX_LAN_RESET = 0,
WX_SW_RESET,
Expand All @@ -293,10 +303,12 @@ enum wx_reset_type {
struct wx_hw {
u8 __iomem *hw_addr;
struct pci_dev *pdev;
struct net_device *netdev;
struct wx_bus_info bus;
struct wx_mac_info mac;
struct wx_eeprom_info eeprom;
struct wx_addr_filter_info addr_ctrl;
struct wx_mac_addr *mac_table;
u16 device_id;
u16 vendor_id;
u16 subsystem_device_id;
Expand Down
61 changes: 10 additions & 51 deletions drivers/net/ethernet/wangxun/ngbe/ngbe_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,6 @@ static const struct pci_device_id ngbe_pci_tbl[] = {
{ .device = 0 }
};

static void ngbe_mac_set_default_filter(struct ngbe_adapter *adapter, u8 *addr)
{
memcpy(&adapter->mac_table[0].addr, addr, ETH_ALEN);
adapter->mac_table[0].pools = 1ULL;
adapter->mac_table[0].state = (NGBE_MAC_STATE_DEFAULT |
NGBE_MAC_STATE_IN_USE);
wx_set_rar(&adapter->wxhw, 0, adapter->mac_table[0].addr,
adapter->mac_table[0].pools,
WX_PSR_MAC_SWC_AD_H_AV);
}

/**
* ngbe_init_type_code - Initialize the shared code
* @adapter: pointer to hardware structure
Expand Down Expand Up @@ -152,6 +141,10 @@ static int ngbe_sw_init(struct ngbe_adapter *adapter)
wxhw->hw_addr = adapter->io_addr;
wxhw->pdev = pdev;

wxhw->mac.num_rar_entries = NGBE_RAR_ENTRIES;
wxhw->mac.max_rx_queues = NGBE_MAX_RX_QUEUES;
wxhw->mac.max_tx_queues = NGBE_MAX_TX_QUEUES;

/* PCI config space info */
err = wx_sw_init(wxhw);
if (err < 0) {
Expand All @@ -163,25 +156,13 @@ static int ngbe_sw_init(struct ngbe_adapter *adapter)
/* mac type, phy type , oem type */
ngbe_init_type_code(adapter);

wxhw->mac.max_rx_queues = NGBE_MAX_RX_QUEUES;
wxhw->mac.max_tx_queues = NGBE_MAX_TX_QUEUES;
wxhw->mac.num_rar_entries = NGBE_RAR_ENTRIES;
/* Set common capability flags and settings */
adapter->max_q_vectors = NGBE_MAX_MSIX_VECTORS;

err = wx_get_pcie_msix_counts(wxhw, &msix_count, NGBE_MAX_MSIX_VECTORS);
if (err)
dev_err(&pdev->dev, "Do not support MSI-X\n");
wxhw->mac.max_msix_vectors = msix_count;

adapter->mac_table = kcalloc(wxhw->mac.num_rar_entries,
sizeof(struct ngbe_mac_addr),
GFP_KERNEL);
if (!adapter->mac_table) {
dev_err(&pdev->dev, "mac_table allocation failed: %d\n", err);
return -ENOMEM;
}

if (ngbe_init_rss_key(adapter))
return -ENOMEM;

Expand Down Expand Up @@ -252,30 +233,6 @@ static netdev_tx_t ngbe_xmit_frame(struct sk_buff *skb,
return NETDEV_TX_OK;
}

/**
* ngbe_set_mac - Change the Ethernet Address of the NIC
* @netdev: network interface device structure
* @p: pointer to an address structure
*
* Returns 0 on success, negative on failure
**/
static int ngbe_set_mac(struct net_device *netdev, void *p)
{
struct ngbe_adapter *adapter = netdev_priv(netdev);
struct wx_hw *wxhw = &adapter->wxhw;
struct sockaddr *addr = p;

if (!is_valid_ether_addr(addr->sa_data))
return -EADDRNOTAVAIL;

eth_hw_addr_set(netdev, addr->sa_data);
memcpy(wxhw->mac.addr, addr->sa_data, netdev->addr_len);

ngbe_mac_set_default_filter(adapter, wxhw->mac.addr);

return 0;
}

static void ngbe_dev_shutdown(struct pci_dev *pdev, bool *enable_wake)
{
struct ngbe_adapter *adapter = pci_get_drvdata(pdev);
Expand Down Expand Up @@ -312,7 +269,7 @@ static const struct net_device_ops ngbe_netdev_ops = {
.ndo_stop = ngbe_close,
.ndo_start_xmit = ngbe_xmit_frame,
.ndo_validate_addr = eth_validate_addr,
.ndo_set_mac_address = ngbe_set_mac,
.ndo_set_mac_address = wx_set_mac,
};

/**
Expand Down Expand Up @@ -377,6 +334,7 @@ static int ngbe_probe(struct pci_dev *pdev,
adapter->netdev = netdev;
adapter->pdev = pdev;
wxhw = &adapter->wxhw;
wxhw->netdev = netdev;
adapter->msg_enable = BIT(3) - 1;

adapter->io_addr = devm_ioremap(&pdev->dev,
Expand Down Expand Up @@ -463,7 +421,7 @@ static int ngbe_probe(struct pci_dev *pdev,
}

eth_hw_addr_set(netdev, wxhw->mac.perm_addr);
ngbe_mac_set_default_filter(adapter, wxhw->mac.perm_addr);
wx_mac_set_default_filter(wxhw, wxhw->mac.perm_addr);

err = register_netdev(netdev);
if (err)
Expand All @@ -481,7 +439,7 @@ static int ngbe_probe(struct pci_dev *pdev,
err_register:
wx_control_hw(wxhw, false);
err_free_mac_table:
kfree(adapter->mac_table);
kfree(wxhw->mac_table);
err_pci_release_regions:
pci_disable_pcie_error_reporting(pdev);
pci_release_selected_regions(pdev,
Expand All @@ -503,14 +461,15 @@ static int ngbe_probe(struct pci_dev *pdev,
static void ngbe_remove(struct pci_dev *pdev)
{
struct ngbe_adapter *adapter = pci_get_drvdata(pdev);
struct wx_hw *wxhw = &adapter->wxhw;
struct net_device *netdev;

netdev = adapter->netdev;
unregister_netdev(netdev);
pci_release_selected_regions(pdev,
pci_select_bars(pdev, IORESOURCE_MEM));

kfree(adapter->mac_table);
kfree(wxhw->mac_table);
pci_disable_pcie_error_reporting(pdev);

pci_disable_device(pdev);
Expand Down
11 changes: 0 additions & 11 deletions drivers/net/ethernet/wangxun/ngbe/ngbe_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,10 +110,6 @@
#define NGBE_MAX_RXD 8192
#define NGBE_MIN_RXD 128

#define NGBE_MAC_STATE_DEFAULT 0x1
#define NGBE_MAC_STATE_MODIFIED 0x2
#define NGBE_MAC_STATE_IN_USE 0x4

enum ngbe_phy_type {
ngbe_phy_unknown = 0,
ngbe_phy_none,
Expand Down Expand Up @@ -151,12 +147,6 @@ struct ngbe_phy_info {

};

struct ngbe_mac_addr {
u8 addr[ETH_ALEN];
u16 state; /* bitmask */
u64 pools;
};

/* board specific private data structure */
struct ngbe_adapter {
u8 __iomem *io_addr; /* Mainly for iounmap use */
Expand All @@ -172,7 +162,6 @@ struct ngbe_adapter {
bool ncsi_enabled;
bool gpio_ctrl;

struct ngbe_mac_addr *mac_table;
u16 msg_enable;

/* Tx fast path data */
Expand Down
Loading

0 comments on commit 79625f4

Please sign in to comment.