#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/wait.h>
#include <linux/spinlock.h>
#include <linux/sort.h>
#include <linux/random.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/socket.h>
#include <linux/etherdevice.h>
#include <linux/ethtool.h>
#include <linux/if_ether.h>
#include <linux/if_vlan.h>
#include <linux/if_bridge.h>
#include <linux/bitops.h>
#include <linux/ctype.h>
#include <linux/workqueue.h>
#include <net/switchdev.h>
#include <net/rtnetlink.h>
#include <net/netevent.h>
#include <net/arp.h>
#include <net/fib_rules.h>
#include <net/fib_notifier.h>
#include <linux/io-64-nonatomic-lo-hi.h>
#include "rocker_hw.h"
#include "rocker.h"
#include "rocker_tlv.h"
static const char rocker_driver_name[] = …;
static const struct pci_device_id rocker_pci_id_table[] = …;
struct rocker_wait { … };
static void rocker_wait_reset(struct rocker_wait *wait)
{ … }
static void rocker_wait_init(struct rocker_wait *wait)
{ … }
static struct rocker_wait *rocker_wait_create(void)
{ … }
static void rocker_wait_destroy(struct rocker_wait *wait)
{ … }
static bool rocker_wait_event_timeout(struct rocker_wait *wait,
unsigned long timeout)
{ … }
static void rocker_wait_wake_up(struct rocker_wait *wait)
{ … }
static u32 rocker_msix_vector(const struct rocker *rocker, unsigned int vector)
{ … }
static u32 rocker_msix_tx_vector(const struct rocker_port *rocker_port)
{ … }
static u32 rocker_msix_rx_vector(const struct rocker_port *rocker_port)
{ … }
#define rocker_write32(rocker, reg, val) …
#define rocker_read32(rocker, reg) …
#define rocker_write64(rocker, reg, val) …
#define rocker_read64(rocker, reg) …
static int rocker_reg_test(const struct rocker *rocker)
{ … }
static int rocker_dma_test_one(const struct rocker *rocker,
struct rocker_wait *wait, u32 test_type,
dma_addr_t dma_handle, const unsigned char *buf,
const unsigned char *expect, size_t size)
{ … }
#define ROCKER_TEST_DMA_BUF_SIZE …
#define ROCKER_TEST_DMA_FILL_PATTERN …
static int rocker_dma_test_offset(const struct rocker *rocker,
struct rocker_wait *wait, int offset)
{ … }
static int rocker_dma_test(const struct rocker *rocker,
struct rocker_wait *wait)
{ … }
static irqreturn_t rocker_test_irq_handler(int irq, void *dev_id)
{ … }
static int rocker_basic_hw_test(const struct rocker *rocker)
{ … }
static u32 __pos_inc(u32 pos, size_t limit)
{ … }
static int rocker_desc_err(const struct rocker_desc_info *desc_info)
{ … }
static void rocker_desc_gen_clear(const struct rocker_desc_info *desc_info)
{ … }
static bool rocker_desc_gen(const struct rocker_desc_info *desc_info)
{ … }
static void *
rocker_desc_cookie_ptr_get(const struct rocker_desc_info *desc_info)
{ … }
static void rocker_desc_cookie_ptr_set(const struct rocker_desc_info *desc_info,
void *ptr)
{ … }
static struct rocker_desc_info *
rocker_desc_head_get(const struct rocker_dma_ring_info *info)
{ … }
static void rocker_desc_commit(const struct rocker_desc_info *desc_info)
{ … }
static void rocker_desc_head_set(const struct rocker *rocker,
struct rocker_dma_ring_info *info,
const struct rocker_desc_info *desc_info)
{ … }
static struct rocker_desc_info *
rocker_desc_tail_get(struct rocker_dma_ring_info *info)
{ … }
static void rocker_dma_ring_credits_set(const struct rocker *rocker,
const struct rocker_dma_ring_info *info,
u32 credits)
{ … }
static unsigned long rocker_dma_ring_size_fix(size_t size)
{ … }
static int rocker_dma_ring_create(const struct rocker *rocker,
unsigned int type,
size_t size,
struct rocker_dma_ring_info *info)
{ … }
static void rocker_dma_ring_destroy(const struct rocker *rocker,
const struct rocker_dma_ring_info *info)
{ … }
static void rocker_dma_ring_pass_to_producer(const struct rocker *rocker,
struct rocker_dma_ring_info *info)
{ … }
static int rocker_dma_ring_bufs_alloc(const struct rocker *rocker,
const struct rocker_dma_ring_info *info,
int direction, size_t buf_size)
{ … }
static void rocker_dma_ring_bufs_free(const struct rocker *rocker,
const struct rocker_dma_ring_info *info,
int direction)
{ … }
static int rocker_dma_cmd_ring_wait_alloc(struct rocker_desc_info *desc_info)
{ … }
static void
rocker_dma_cmd_ring_wait_free(const struct rocker_desc_info *desc_info)
{ … }
static int rocker_dma_cmd_ring_waits_alloc(const struct rocker *rocker)
{ … }
static void rocker_dma_cmd_ring_waits_free(const struct rocker *rocker)
{ … }
static int rocker_dma_rings_init(struct rocker *rocker)
{ … }
static void rocker_dma_rings_fini(struct rocker *rocker)
{ … }
static int rocker_dma_rx_ring_skb_map(const struct rocker_port *rocker_port,
struct rocker_desc_info *desc_info,
struct sk_buff *skb, size_t buf_len)
{ … }
static size_t rocker_port_rx_buf_len(const struct rocker_port *rocker_port)
{ … }
static int rocker_dma_rx_ring_skb_alloc(const struct rocker_port *rocker_port,
struct rocker_desc_info *desc_info)
{ … }
static void rocker_dma_rx_ring_skb_unmap(const struct rocker *rocker,
const struct rocker_tlv **attrs)
{ … }
static void rocker_dma_rx_ring_skb_free(const struct rocker *rocker,
const struct rocker_desc_info *desc_info)
{ … }
static int rocker_dma_rx_ring_skbs_alloc(const struct rocker_port *rocker_port)
{ … }
static void rocker_dma_rx_ring_skbs_free(const struct rocker_port *rocker_port)
{ … }
static int rocker_port_dma_rings_init(struct rocker_port *rocker_port)
{ … }
static void rocker_port_dma_rings_fini(struct rocker_port *rocker_port)
{ … }
static void rocker_port_set_enable(const struct rocker_port *rocker_port,
bool enable)
{ … }
static irqreturn_t rocker_cmd_irq_handler(int irq, void *dev_id)
{ … }
static void rocker_port_link_up(const struct rocker_port *rocker_port)
{ … }
static void rocker_port_link_down(const struct rocker_port *rocker_port)
{ … }
static int rocker_event_link_change(const struct rocker *rocker,
const struct rocker_tlv *info)
{ … }
static int rocker_world_port_ev_mac_vlan_seen(struct rocker_port *rocker_port,
const unsigned char *addr,
__be16 vlan_id);
static int rocker_event_mac_vlan_seen(const struct rocker *rocker,
const struct rocker_tlv *info)
{ … }
static int rocker_event_process(const struct rocker *rocker,
const struct rocker_desc_info *desc_info)
{ … }
static irqreturn_t rocker_event_irq_handler(int irq, void *dev_id)
{ … }
static irqreturn_t rocker_tx_irq_handler(int irq, void *dev_id)
{ … }
static irqreturn_t rocker_rx_irq_handler(int irq, void *dev_id)
{ … }
int rocker_cmd_exec(struct rocker_port *rocker_port, bool nowait,
rocker_cmd_prep_cb_t prepare, void *prepare_priv,
rocker_cmd_proc_cb_t process, void *process_priv)
{ … }
static int
rocker_cmd_get_port_settings_prep(const struct rocker_port *rocker_port,
struct rocker_desc_info *desc_info,
void *priv)
{ … }
static int
rocker_cmd_get_port_settings_ethtool_proc(const struct rocker_port *rocker_port,
const struct rocker_desc_info *desc_info,
void *priv)
{ … }
static int
rocker_cmd_get_port_settings_macaddr_proc(const struct rocker_port *rocker_port,
const struct rocker_desc_info *desc_info,
void *priv)
{ … }
static int
rocker_cmd_get_port_settings_mode_proc(const struct rocker_port *rocker_port,
const struct rocker_desc_info *desc_info,
void *priv)
{ … }
struct port_name { … };
static int
rocker_cmd_get_port_settings_phys_name_proc(const struct rocker_port *rocker_port,
const struct rocker_desc_info *desc_info,
void *priv)
{ … }
static int
rocker_cmd_set_port_settings_ethtool_prep(const struct rocker_port *rocker_port,
struct rocker_desc_info *desc_info,
void *priv)
{ … }
static int
rocker_cmd_set_port_settings_macaddr_prep(const struct rocker_port *rocker_port,
struct rocker_desc_info *desc_info,
void *priv)
{ … }
static int
rocker_cmd_set_port_settings_mtu_prep(const struct rocker_port *rocker_port,
struct rocker_desc_info *desc_info,
void *priv)
{ … }
static int
rocker_cmd_set_port_learning_prep(const struct rocker_port *rocker_port,
struct rocker_desc_info *desc_info,
void *priv)
{ … }
static int
rocker_cmd_get_port_settings_ethtool(struct rocker_port *rocker_port,
struct ethtool_link_ksettings *ecmd)
{ … }
static int rocker_cmd_get_port_settings_macaddr(struct rocker_port *rocker_port,
unsigned char *macaddr)
{ … }
static int rocker_cmd_get_port_settings_mode(struct rocker_port *rocker_port,
u8 *p_mode)
{ … }
static int
rocker_cmd_set_port_settings_ethtool(struct rocker_port *rocker_port,
const struct ethtool_link_ksettings *ecmd)
{ … }
static int rocker_cmd_set_port_settings_macaddr(struct rocker_port *rocker_port,
unsigned char *macaddr)
{ … }
static int rocker_cmd_set_port_settings_mtu(struct rocker_port *rocker_port,
int mtu)
{ … }
int rocker_port_set_learning(struct rocker_port *rocker_port,
bool learning)
{ … }
static struct rocker_world_ops *rocker_world_ops[] = …;
#define ROCKER_WORLD_OPS_LEN …
static struct rocker_world_ops *rocker_world_ops_find(u8 mode)
{ … }
static int rocker_world_init(struct rocker *rocker, u8 mode)
{ … }
static void rocker_world_fini(struct rocker *rocker)
{ … }
static int rocker_world_check_init(struct rocker_port *rocker_port)
{ … }
static int rocker_world_port_pre_init(struct rocker_port *rocker_port)
{ … }
static int rocker_world_port_init(struct rocker_port *rocker_port)
{ … }
static void rocker_world_port_fini(struct rocker_port *rocker_port)
{ … }
static void rocker_world_port_post_fini(struct rocker_port *rocker_port)
{ … }
static int rocker_world_port_open(struct rocker_port *rocker_port)
{ … }
static void rocker_world_port_stop(struct rocker_port *rocker_port)
{ … }
static int rocker_world_port_attr_stp_state_set(struct rocker_port *rocker_port,
u8 state)
{ … }
static int
rocker_world_port_attr_bridge_flags_support_get(const struct rocker_port *
rocker_port,
unsigned long *
p_brport_flags_support)
{ … }
static int
rocker_world_port_attr_pre_bridge_flags_set(struct rocker_port *rocker_port,
struct switchdev_brport_flags flags)
{ … }
static int
rocker_world_port_attr_bridge_flags_set(struct rocker_port *rocker_port,
struct switchdev_brport_flags flags)
{ … }
static int
rocker_world_port_attr_bridge_ageing_time_set(struct rocker_port *rocker_port,
u32 ageing_time)
{ … }
static int
rocker_world_port_obj_vlan_add(struct rocker_port *rocker_port,
const struct switchdev_obj_port_vlan *vlan)
{ … }
static int
rocker_world_port_obj_vlan_del(struct rocker_port *rocker_port,
const struct switchdev_obj_port_vlan *vlan)
{ … }
static int
rocker_world_port_fdb_add(struct rocker_port *rocker_port,
struct switchdev_notifier_fdb_info *info)
{ … }
static int
rocker_world_port_fdb_del(struct rocker_port *rocker_port,
struct switchdev_notifier_fdb_info *info)
{ … }
static int rocker_world_port_master_linked(struct rocker_port *rocker_port,
struct net_device *master,
struct netlink_ext_ack *extack)
{ … }
static int rocker_world_port_master_unlinked(struct rocker_port *rocker_port,
struct net_device *master)
{ … }
static int rocker_world_port_neigh_update(struct rocker_port *rocker_port,
struct neighbour *n)
{ … }
static int rocker_world_port_neigh_destroy(struct rocker_port *rocker_port,
struct neighbour *n)
{ … }
static int rocker_world_port_ev_mac_vlan_seen(struct rocker_port *rocker_port,
const unsigned char *addr,
__be16 vlan_id)
{ … }
static int rocker_world_fib4_add(struct rocker *rocker,
const struct fib_entry_notifier_info *fen_info)
{ … }
static int rocker_world_fib4_del(struct rocker *rocker,
const struct fib_entry_notifier_info *fen_info)
{ … }
static void rocker_world_fib4_abort(struct rocker *rocker)
{ … }
static int rocker_port_open(struct net_device *dev)
{ … }
static int rocker_port_stop(struct net_device *dev)
{ … }
static void rocker_tx_desc_frags_unmap(const struct rocker_port *rocker_port,
const struct rocker_desc_info *desc_info)
{ … }
static int rocker_tx_desc_frag_map_put(const struct rocker_port *rocker_port,
struct rocker_desc_info *desc_info,
char *buf, size_t buf_len)
{ … }
static netdev_tx_t rocker_port_xmit(struct sk_buff *skb, struct net_device *dev)
{ … }
static int rocker_port_set_mac_address(struct net_device *dev, void *p)
{ … }
static int rocker_port_change_mtu(struct net_device *dev, int new_mtu)
{ … }
static int rocker_port_get_phys_port_name(struct net_device *dev,
char *buf, size_t len)
{ … }
static void rocker_port_neigh_destroy(struct net_device *dev,
struct neighbour *n)
{ … }
static int rocker_port_get_port_parent_id(struct net_device *dev,
struct netdev_phys_item_id *ppid)
{ … }
static const struct net_device_ops rocker_port_netdev_ops = …;
static int rocker_port_attr_set(struct net_device *dev,
const struct switchdev_attr *attr)
{ … }
static int rocker_port_obj_add(struct net_device *dev,
const struct switchdev_obj *obj)
{ … }
static int rocker_port_obj_del(struct net_device *dev,
const struct switchdev_obj *obj)
{ … }
struct rocker_fib_event_work { … };
static void rocker_router_fib_event_work(struct work_struct *work)
{ … }
static int rocker_router_fib_event(struct notifier_block *nb,
unsigned long event, void *ptr)
{ … }
static int
rocker_port_get_link_ksettings(struct net_device *dev,
struct ethtool_link_ksettings *ecmd)
{ … }
static int
rocker_port_set_link_ksettings(struct net_device *dev,
const struct ethtool_link_ksettings *ecmd)
{ … }
static void rocker_port_get_drvinfo(struct net_device *dev,
struct ethtool_drvinfo *drvinfo)
{ … }
static struct rocker_port_stats { … } rocker_port_stats[] = …;
#define ROCKER_PORT_STATS_LEN …
static void rocker_port_get_strings(struct net_device *netdev, u32 stringset,
u8 *data)
{ … }
static int
rocker_cmd_get_port_stats_prep(const struct rocker_port *rocker_port,
struct rocker_desc_info *desc_info,
void *priv)
{ … }
static int
rocker_cmd_get_port_stats_ethtool_proc(const struct rocker_port *rocker_port,
const struct rocker_desc_info *desc_info,
void *priv)
{ … }
static int rocker_cmd_get_port_stats_ethtool(struct rocker_port *rocker_port,
void *priv)
{ … }
static void rocker_port_get_stats(struct net_device *dev,
struct ethtool_stats *stats, u64 *data)
{ … }
static int rocker_port_get_sset_count(struct net_device *netdev, int sset)
{ … }
static const struct ethtool_ops rocker_port_ethtool_ops = …;
static struct rocker_port *rocker_port_napi_tx_get(struct napi_struct *napi)
{ … }
static int rocker_port_poll_tx(struct napi_struct *napi, int budget)
{ … }
static int rocker_port_rx_proc(const struct rocker *rocker,
const struct rocker_port *rocker_port,
struct rocker_desc_info *desc_info)
{ … }
static struct rocker_port *rocker_port_napi_rx_get(struct napi_struct *napi)
{ … }
static int rocker_port_poll_rx(struct napi_struct *napi, int budget)
{ … }
static void rocker_carrier_init(const struct rocker_port *rocker_port)
{ … }
static void rocker_remove_ports(struct rocker *rocker)
{ … }
static void rocker_port_dev_addr_init(struct rocker_port *rocker_port)
{ … }
#define ROCKER_PORT_MIN_MTU …
#define ROCKER_PORT_MAX_MTU …
static int rocker_probe_port(struct rocker *rocker, unsigned int port_number)
{ … }
static int rocker_probe_ports(struct rocker *rocker)
{ … }
static int rocker_msix_init(struct rocker *rocker)
{ … }
static void rocker_msix_fini(const struct rocker *rocker)
{ … }
static bool rocker_port_dev_check(const struct net_device *dev)
{ … }
static int
rocker_switchdev_port_attr_set_event(struct net_device *netdev,
struct switchdev_notifier_port_attr_info *port_attr_info)
{ … }
struct rocker_switchdev_event_work { … };
static void
rocker_fdb_offload_notify(struct rocker_port *rocker_port,
struct switchdev_notifier_fdb_info *recv_info)
{ … }
static void rocker_switchdev_event_work(struct work_struct *work)
{ … }
static int rocker_switchdev_event(struct notifier_block *unused,
unsigned long event, void *ptr)
{ … }
static int
rocker_switchdev_port_obj_event(unsigned long event, struct net_device *netdev,
struct switchdev_notifier_port_obj_info *port_obj_info)
{ … }
static int rocker_switchdev_blocking_event(struct notifier_block *unused,
unsigned long event, void *ptr)
{ … }
static struct notifier_block rocker_switchdev_notifier = …;
static struct notifier_block rocker_switchdev_blocking_notifier = …;
static int rocker_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{ … }
static void rocker_remove(struct pci_dev *pdev)
{ … }
static struct pci_driver rocker_pci_driver = …;
static bool rocker_port_dev_check_under(const struct net_device *dev,
struct rocker *rocker)
{ … }
struct rocker_walk_data { … };
static int rocker_lower_dev_walk(struct net_device *lower_dev,
struct netdev_nested_priv *priv)
{ … }
struct rocker_port *rocker_port_dev_lower_find(struct net_device *dev,
struct rocker *rocker)
{ … }
static int rocker_netdevice_event(struct notifier_block *unused,
unsigned long event, void *ptr)
{ … }
static struct notifier_block rocker_netdevice_nb __read_mostly = …;
static int rocker_netevent_event(struct notifier_block *unused,
unsigned long event, void *ptr)
{ … }
static struct notifier_block rocker_netevent_nb __read_mostly = …;
static int __init rocker_module_init(void)
{ … }
static void __exit rocker_module_exit(void)
{ … }
module_init(…) …;
module_exit(rocker_module_exit);
MODULE_LICENSE(…) …;
MODULE_AUTHOR(…) …;
MODULE_AUTHOR(…) …;
MODULE_DESCRIPTION(…) …;
MODULE_DEVICE_TABLE(pci, rocker_pci_id_table);