linux/drivers/net/ethernet/broadcom/b44.c

/* b44.c: Broadcom 44xx/47xx Fast Ethernet device driver.
 *
 * Copyright (C) 2002 David S. Miller ([email protected])
 * Copyright (C) 2004 Pekka Pietikainen ([email protected])
 * Copyright (C) 2004 Florian Schirmer ([email protected])
 * Copyright (C) 2006 Felix Fietkau ([email protected])
 * Copyright (C) 2006 Broadcom Corporation.
 * Copyright (C) 2007 Michael Buesch <[email protected]>
 * Copyright (C) 2013 Hauke Mehrtens <[email protected]>
 *
 * Distribute under GPL.
 */

#define pr_fmt(fmt)

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/types.h>
#include <linux/netdevice.h>
#include <linux/ethtool.h>
#include <linux/mii.h>
#include <linux/if_ether.h>
#include <linux/if_vlan.h>
#include <linux/etherdevice.h>
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/dma-mapping.h>
#include <linux/ssb/ssb.h>
#include <linux/slab.h>
#include <linux/phy.h>

#include <linux/uaccess.h>
#include <asm/io.h>
#include <asm/irq.h>


#include "b44.h"

#define DRV_MODULE_NAME
#define DRV_DESCRIPTION

#define B44_DEF_MSG_ENABLE

/* length of time before we decide the hardware is borked,
 * and dev->tx_timeout() should be called to fix the problem
 */
#define B44_TX_TIMEOUT

/* hardware minimum and maximum for a single frame's data payload */
#define B44_MIN_MTU
#define B44_MAX_MTU

#define B44_RX_RING_SIZE
#define B44_DEF_RX_RING_PENDING
#define B44_RX_RING_BYTES
#define B44_TX_RING_SIZE
#define B44_DEF_TX_RING_PENDING
#define B44_TX_RING_BYTES

#define TX_RING_GAP(BP)
#define TX_BUFFS_AVAIL(BP)
#define NEXT_TX(N)

#define RX_PKT_OFFSET
#define RX_PKT_BUF_SZ

/* minimum number of free TX descriptors required to wake up TX process */
#define B44_TX_WAKEUP_THRESH

/* b44 internal pattern match filter info */
#define B44_PATTERN_BASE
#define B44_PATTERN_SIZE
#define B44_PMASK_BASE
#define B44_PMASK_SIZE
#define B44_MAX_PATTERNS
#define B44_ETHIPV6UDP_HLEN
#define B44_ETHIPV4UDP_HLEN

MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_LICENSE();

static int b44_debug =;	/* -1 == use B44_DEF_MSG_ENABLE as value */
module_param(b44_debug, int, 0);
MODULE_PARM_DESC();


#ifdef CONFIG_B44_PCI
static const struct pci_device_id b44_pci_tbl[] =;
MODULE_DEVICE_TABLE(pci, b44_pci_tbl);

static struct pci_driver b44_pci_driver =;
#endif /* CONFIG_B44_PCI */

static const struct ssb_device_id b44_ssb_tbl[] =;
MODULE_DEVICE_TABLE(ssb, b44_ssb_tbl);

static void b44_halt(struct b44 *);
static void b44_init_rings(struct b44 *);

#define B44_FULL_RESET
#define B44_FULL_RESET_SKIP_PHY
#define B44_PARTIAL_RESET
#define B44_CHIP_RESET_FULL
#define B44_CHIP_RESET_PARTIAL

static void b44_init_hw(struct b44 *, int);

static int dma_desc_sync_size;
static int instance;

static const char b44_gstrings[][ETH_GSTRING_LEN] =;

static inline void b44_sync_dma_desc_for_device(struct ssb_device *sdev,
						dma_addr_t dma_base,
						unsigned long offset,
						enum dma_data_direction dir)
{}

static inline void b44_sync_dma_desc_for_cpu(struct ssb_device *sdev,
					     dma_addr_t dma_base,
					     unsigned long offset,
					     enum dma_data_direction dir)
{}

static inline unsigned long br32(const struct b44 *bp, unsigned long reg)
{}

static inline void bw32(const struct b44 *bp,
			unsigned long reg, unsigned long val)
{}

static int b44_wait_bit(struct b44 *bp, unsigned long reg,
			u32 bit, unsigned long timeout, const int clear)
{}

static inline void __b44_cam_write(struct b44 *bp,
				   const unsigned char *data, int index)
{}

static inline void __b44_disable_ints(struct b44 *bp)
{}

static void b44_disable_ints(struct b44 *bp)
{}

static void b44_enable_ints(struct b44 *bp)
{}

static int __b44_readphy(struct b44 *bp, int phy_addr, int reg, u32 *val)
{}

static int __b44_writephy(struct b44 *bp, int phy_addr, int reg, u32 val)
{}

static inline int b44_readphy(struct b44 *bp, int reg, u32 *val)
{}

static inline int b44_writephy(struct b44 *bp, int reg, u32 val)
{}

/* miilib interface */
static int b44_mdio_read_mii(struct net_device *dev, int phy_id, int location)
{}

static void b44_mdio_write_mii(struct net_device *dev, int phy_id, int location,
			       int val)
{}

static int b44_mdio_read_phylib(struct mii_bus *bus, int phy_id, int location)
{}

static int b44_mdio_write_phylib(struct mii_bus *bus, int phy_id, int location,
				 u16 val)
{}

static int b44_phy_reset(struct b44 *bp)
{}

static void __b44_set_flow_ctrl(struct b44 *bp, u32 pause_flags)
{}

static void b44_set_flow_ctrl(struct b44 *bp, u32 local, u32 remote)
{}

#ifdef CONFIG_BCM47XX
#include <linux/bcm47xx_nvram.h>
static void b44_wap54g10_workaround(struct b44 *bp)
{
	char buf[20];
	u32 val;
	int err;

	/*
	 * workaround for bad hardware design in Linksys WAP54G v1.0
	 * see https://dev.openwrt.org/ticket/146
	 * check and reset bit "isolate"
	 */
	if (bcm47xx_nvram_getenv("boardnum", buf, sizeof(buf)) < 0)
		return;
	if (simple_strtoul(buf, NULL, 0) == 2) {
		err = __b44_readphy(bp, 0, MII_BMCR, &val);
		if (err)
			goto error;
		if (!(val & BMCR_ISOLATE))
			return;
		val &= ~BMCR_ISOLATE;
		err = __b44_writephy(bp, 0, MII_BMCR, val);
		if (err)
			goto error;
	}
	return;
error:
	pr_warn("PHY: cannot reset MII transceiver isolate bit\n");
}
#else
static inline void b44_wap54g10_workaround(struct b44 *bp)
{}
#endif

static int b44_setup_phy(struct b44 *bp)
{}

static void b44_stats_update(struct b44 *bp)
{}

static void b44_link_report(struct b44 *bp)
{}

static void b44_check_phy(struct b44 *bp)
{}

static void b44_timer(struct timer_list *t)
{}

static void b44_tx(struct b44 *bp)
{}

/* Works like this.  This chip writes a 'struct rx_header" 30 bytes
 * before the DMA address you give it.  So we allocate 30 more bytes
 * for the RX buffer, DMA map all of it, skb_reserve the 30 bytes, then
 * point the chip at 30 bytes past where the rx_header will go.
 */
static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
{}

static void b44_recycle_rx(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
{}

static int b44_rx(struct b44 *bp, int budget)
{}

static int b44_poll(struct napi_struct *napi, int budget)
{}

static irqreturn_t b44_interrupt(int irq, void *dev_id)
{}

static void b44_tx_timeout(struct net_device *dev, unsigned int txqueue)
{}

static netdev_tx_t b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
{}

static int b44_change_mtu(struct net_device *dev, int new_mtu)
{}

/* Free up pending packets in all rx/tx rings.
 *
 * The chip has been shut down and the driver detached from
 * the networking, so no interrupts or new tx packets will
 * end up in the driver.  bp->lock is not held and we are not
 * in an interrupt context and thus may sleep.
 */
static void b44_free_rings(struct b44 *bp)
{}

/* Initialize tx/rx rings for packet processing.
 *
 * The chip has been shut down and the driver detached from
 * the networking, so no interrupts or new tx packets will
 * end up in the driver.
 */
static void b44_init_rings(struct b44 *bp)
{}

/*
 * Must not be invoked with interrupt sources disabled and
 * the hardware shutdown down.
 */
static void b44_free_consistent(struct b44 *bp)
{}

/*
 * Must not be invoked with interrupt sources disabled and
 * the hardware shutdown down.  Can sleep.
 */
static int b44_alloc_consistent(struct b44 *bp, gfp_t gfp)
{}

/* bp->lock is held. */
static void b44_clear_stats(struct b44 *bp)
{}

/* bp->lock is held. */
static void b44_chip_reset(struct b44 *bp, int reset_kind)
{}

/* bp->lock is held. */
static void b44_halt(struct b44 *bp)
{}

/* bp->lock is held. */
static void __b44_set_mac_addr(struct b44 *bp)
{}

static int b44_set_mac_addr(struct net_device *dev, void *p)
{}

/* Called at device open time to get the chip ready for
 * packet processing.  Invoked with bp->lock held.
 */
static void __b44_set_rx_mode(struct net_device *);
static void b44_init_hw(struct b44 *bp, int reset_kind)
{}

static int b44_open(struct net_device *dev)
{}

#ifdef CONFIG_NET_POLL_CONTROLLER
/*
 * Polling receive - used by netconsole and other diagnostic tools
 * to allow network i/o with interrupts disabled.
 */
static void b44_poll_controller(struct net_device *dev)
{}
#endif

static void bwfilter_table(struct b44 *bp, u8 *pp, u32 bytes, u32 table_offset)
{}

static int b44_magic_pattern(const u8 *macaddr, u8 *ppattern, u8 *pmask,
			     int offset)
{}

/* Setup magic packet patterns in the b44 WOL
 * pattern matching filter.
 */
static void b44_setup_pseudo_magicp(struct b44 *bp)
{}

#ifdef CONFIG_B44_PCI
static void b44_setup_wol_pci(struct b44 *bp)
{}
#else
static inline void b44_setup_wol_pci(struct b44 *bp) { }
#endif /* CONFIG_B44_PCI */

static void b44_setup_wol(struct b44 *bp)
{}

static int b44_close(struct net_device *dev)
{}

static void b44_get_stats64(struct net_device *dev,
			    struct rtnl_link_stats64 *nstat)
{}

static int __b44_load_mcast(struct b44 *bp, struct net_device *dev)
{}

static void __b44_set_rx_mode(struct net_device *dev)
{}

static void b44_set_rx_mode(struct net_device *dev)
{}

static u32 b44_get_msglevel(struct net_device *dev)
{}

static void b44_set_msglevel(struct net_device *dev, u32 value)
{}

static void b44_get_drvinfo (struct net_device *dev, struct ethtool_drvinfo *info)
{}

static int b44_nway_reset(struct net_device *dev)
{}

static int b44_get_link_ksettings(struct net_device *dev,
				  struct ethtool_link_ksettings *cmd)
{}

static int b44_set_link_ksettings(struct net_device *dev,
				  const struct ethtool_link_ksettings *cmd)
{}

static void b44_get_ringparam(struct net_device *dev,
			      struct ethtool_ringparam *ering,
			      struct kernel_ethtool_ringparam *kernel_ering,
			      struct netlink_ext_ack *extack)
{}

static int b44_set_ringparam(struct net_device *dev,
			     struct ethtool_ringparam *ering,
			     struct kernel_ethtool_ringparam *kernel_ering,
			     struct netlink_ext_ack *extack)
{}

static void b44_get_pauseparam(struct net_device *dev,
				struct ethtool_pauseparam *epause)
{}

static int b44_set_pauseparam(struct net_device *dev,
				struct ethtool_pauseparam *epause)
{}

static void b44_get_strings(struct net_device *dev, u32 stringset, u8 *data)
{}

static int b44_get_sset_count(struct net_device *dev, int sset)
{}

static void b44_get_ethtool_stats(struct net_device *dev,
				  struct ethtool_stats *stats, u64 *data)
{}

static void b44_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
{}

static int b44_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
{}

static const struct ethtool_ops b44_ethtool_ops =;

static int b44_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{}

static int b44_get_invariants(struct b44 *bp)
{}

static const struct net_device_ops b44_netdev_ops =;

static void b44_adjust_link(struct net_device *dev)
{}

static int b44_register_phy_one(struct b44 *bp)
{}

static void b44_unregister_phy_one(struct b44 *bp)
{}

static int b44_init_one(struct ssb_device *sdev,
			const struct ssb_device_id *ent)
{}

static void b44_remove_one(struct ssb_device *sdev)
{}

static int b44_suspend(struct ssb_device *sdev, pm_message_t state)
{}

static int b44_resume(struct ssb_device *sdev)
{}

static struct ssb_driver b44_ssb_driver =;

static inline int __init b44_pci_init(void)
{}

static inline void b44_pci_exit(void)
{}

static int __init b44_init(void)
{}

static void __exit b44_cleanup(void)
{}

module_init();
module_exit(b44_cleanup);