From c08437b4b5c89677a81b543644b2d0a99484d947 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Sat, 12 Jul 2014 08:49:39 +0200 Subject: brcmfmac: introduce feature and quirk handling Introducing a new source module that will be responsible for identifying features and quirks related to the device being handled. Reviewed-by: Hante Meuleman Reviewed-by: Franky (Zhenhui) Lin Reviewed-by: Daniel (Deognyoun) Kim Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index 09dd8c13d84..bf448081d6f 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c @@ -30,6 +30,7 @@ #include "wl_cfg80211.h" #include "fwil.h" #include "fwsignal.h" +#include "feature.h" #include "proto.h" MODULE_AUTHOR("Broadcom Corporation"); @@ -936,6 +937,8 @@ int brcmf_bus_start(struct device *dev) if (ret < 0) goto fail; + brcmf_feat_attach(drvr); + ret = brcmf_fws_init(drvr); if (ret < 0) goto fail; @@ -1073,16 +1076,6 @@ int brcmf_netdev_wait_pend8021x(struct net_device *ndev) return !err; } -/* - * return chip id and rev of the device encoded in u32. - */ -u32 brcmf_get_chip_info(struct brcmf_if *ifp) -{ - struct brcmf_bus *bus = ifp->drvr->bus_if; - - return bus->chip << 4 | bus->chiprev; -} - static void brcmf_driver_register(struct work_struct *work) { #ifdef CONFIG_BRCMFMAC_SDIO -- cgit v1.2.3-70-g09d2 From c835a677331495cf137a7f8a023463afd9f032f8 Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Mon, 14 Jul 2014 16:37:24 +0200 Subject: net: set name_assign_type in alloc_netdev() Extend alloc_netdev{,_mq{,s}}() to take name_assign_type as argument, and convert all users to pass NET_NAME_UNKNOWN. Coccinelle patch: @@ expression sizeof_priv, name, setup, txqs, rxqs, count; @@ ( -alloc_netdev_mqs(sizeof_priv, name, setup, txqs, rxqs) +alloc_netdev_mqs(sizeof_priv, name, NET_NAME_UNKNOWN, setup, txqs, rxqs) | -alloc_netdev_mq(sizeof_priv, name, setup, count) +alloc_netdev_mq(sizeof_priv, name, NET_NAME_UNKNOWN, setup, count) | -alloc_netdev(sizeof_priv, name, setup) +alloc_netdev(sizeof_priv, name, NET_NAME_UNKNOWN, setup) ) v9: move comments here from the wrong commit Signed-off-by: Tom Gundersen Reviewed-by: David Herrmann Signed-off-by: David S. Miller --- drivers/firewire/net.c | 3 ++- drivers/hsi/clients/ssi_protocol.c | 2 +- drivers/infiniband/hw/amso1100/c2_provider.c | 2 +- drivers/infiniband/ulp/ipoib/ipoib_main.c | 4 ++-- drivers/isdn/i4l/isdn_net.c | 3 ++- drivers/media/dvb-core/dvb_net.c | 3 ++- drivers/misc/sgi-xp/xpnet.c | 3 ++- drivers/net/arcnet/arcnet.c | 3 ++- drivers/net/bonding/bond_main.c | 2 +- drivers/net/caif/caif_serial.c | 3 ++- drivers/net/caif/caif_spi.c | 4 ++-- drivers/net/caif/caif_virtio.c | 2 +- drivers/net/can/dev.c | 2 +- drivers/net/can/slcan.c | 2 +- drivers/net/dummy.c | 2 +- drivers/net/eql.c | 3 ++- drivers/net/ethernet/8390/lib8390.c | 2 +- drivers/net/ethernet/tile/tilegx.c | 4 ++-- drivers/net/ethernet/tile/tilepro.c | 3 ++- drivers/net/hamradio/6pack.c | 3 ++- drivers/net/hamradio/baycom_epp.c | 2 +- drivers/net/hamradio/bpqether.c | 4 ++-- drivers/net/hamradio/dmascc.c | 4 ++-- drivers/net/hamradio/hdlcdrv.c | 2 +- drivers/net/hamradio/mkiss.c | 3 ++- drivers/net/hamradio/scc.c | 2 +- drivers/net/hamradio/yam.c | 2 +- drivers/net/ieee802154/fakehard.c | 3 ++- drivers/net/ifb.c | 4 ++-- drivers/net/loopback.c | 2 +- drivers/net/ppp/ppp_generic.c | 3 ++- drivers/net/slip/slip.c | 2 +- drivers/net/tun.c | 3 ++- drivers/net/usb/cdc-phonet.c | 2 +- drivers/net/usb/hso.c | 3 ++- drivers/net/wan/dlci.c | 4 ++-- drivers/net/wan/hdlc.c | 3 ++- drivers/net/wan/hdlc_fr.c | 5 +++-- drivers/net/wan/lapbether.c | 4 ++-- drivers/net/wan/sbni.c | 7 ++++--- drivers/net/wan/sdla.c | 3 ++- drivers/net/wan/x25_asy.c | 4 ++-- drivers/net/wimax/i2400m/usb.c | 2 +- drivers/net/wireless/airo.c | 5 +++-- drivers/net/wireless/ath/ath6kl/cfg80211.c | 2 +- drivers/net/wireless/ath/wil6210/netdev.c | 2 +- drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c | 3 ++- drivers/net/wireless/libertas/main.c | 2 +- drivers/net/wireless/libertas/mesh.c | 2 +- drivers/net/wireless/mac80211_hwsim.c | 3 ++- drivers/net/wireless/mwifiex/cfg80211.c | 3 ++- drivers/net/xen-netback/interface.c | 4 ++-- drivers/s390/net/claw.c | 2 +- drivers/s390/net/ctcm_main.c | 6 ++++-- drivers/s390/net/netiucv.c | 2 +- drivers/s390/net/qeth_l2_main.c | 6 ++++-- drivers/s390/net/qeth_l3_main.c | 3 ++- drivers/staging/cxt1e1/linux.c | 3 ++- drivers/staging/gdm724x/gdm_lte.c | 2 +- drivers/staging/gdm72xx/gdm_wimax.c | 3 ++- drivers/staging/vt6655/wpactl.c | 3 ++- drivers/staging/wlan-ng/p80211netdev.c | 2 +- drivers/tty/n_gsm.c | 5 ++--- drivers/usb/gadget/f_phonet.c | 3 ++- include/linux/netdevice.h | 10 ++++++---- net/802/fc.c | 2 +- net/802/fddi.c | 3 ++- net/802/hippi.c | 3 ++- net/8021q/vlan.c | 3 ++- net/appletalk/dev.c | 3 ++- net/atm/br2684.c | 4 ++-- net/atm/clip.c | 3 ++- net/batman-adv/soft-interface.c | 2 +- net/bluetooth/6lowpan.c | 2 +- net/bluetooth/bnep/core.c | 5 +++-- net/bridge/br_if.c | 2 +- net/core/dev.c | 13 ++++++++----- net/core/rtnetlink.c | 4 ++-- net/dsa/slave.c | 4 ++-- net/ethernet/eth.c | 3 ++- net/ipv4/ip_tunnel.c | 2 +- net/ipv4/ipmr.c | 2 +- net/ipv6/ip6_gre.c | 6 ++++-- net/ipv6/ip6_tunnel.c | 5 +++-- net/ipv6/ip6_vti.c | 4 ++-- net/ipv6/ip6mr.c | 2 +- net/ipv6/sit.c | 4 +++- net/irda/irda_device.c | 3 ++- net/irda/irlan/irlan_eth.c | 2 +- net/l2tp/l2tp_eth.c | 3 ++- net/mac80211/iface.c | 6 +++--- net/mac802154/ieee802154_dev.c | 6 ++++-- net/netrom/af_netrom.c | 2 +- net/openvswitch/vport-internal_dev.c | 3 ++- net/phonet/pep-gprs.c | 2 +- net/rose/af_rose.c | 2 +- net/sched/sch_teql.c | 4 ++-- 97 files changed, 185 insertions(+), 133 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c') diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index c3986452194..2c68da1ceee 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c @@ -1460,7 +1460,8 @@ static int fwnet_probe(struct fw_unit *unit, goto have_dev; } - net = alloc_netdev(sizeof(*dev), "firewire%d", fwnet_init_dev); + net = alloc_netdev(sizeof(*dev), "firewire%d", NET_NAME_UNKNOWN, + fwnet_init_dev); if (net == NULL) { mutex_unlock(&fwnet_device_mutex); return -ENOMEM; diff --git a/drivers/hsi/clients/ssi_protocol.c b/drivers/hsi/clients/ssi_protocol.c index ce4be3738d4..737fa2e0e78 100644 --- a/drivers/hsi/clients/ssi_protocol.c +++ b/drivers/hsi/clients/ssi_protocol.c @@ -1115,7 +1115,7 @@ static int ssi_protocol_probe(struct device *dev) goto out; } - ssi->netdev = alloc_netdev(0, ifname, ssip_pn_setup); + ssi->netdev = alloc_netdev(0, ifname, NET_NAME_UNKNOWN, ssip_pn_setup); if (!ssi->netdev) { dev_err(dev, "No memory for netdev\n"); err = -ENOMEM; diff --git a/drivers/infiniband/hw/amso1100/c2_provider.c b/drivers/infiniband/hw/amso1100/c2_provider.c index 8af33cf1fc4..2d5cbf4363e 100644 --- a/drivers/infiniband/hw/amso1100/c2_provider.c +++ b/drivers/infiniband/hw/amso1100/c2_provider.c @@ -734,7 +734,7 @@ static struct net_device *c2_pseudo_netdev_init(struct c2_dev *c2dev) /* change ethxxx to iwxxx */ strcpy(name, "iw"); strcat(name, &c2dev->netdev->name[3]); - netdev = alloc_netdev(0, name, setup); + netdev = alloc_netdev(0, name, NET_NAME_UNKNOWN, setup); if (!netdev) { printk(KERN_ERR PFX "%s - etherdev alloc failed", __func__); diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index 5786a78ff8b..4e675f4fecc 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c @@ -1394,8 +1394,8 @@ struct ipoib_dev_priv *ipoib_intf_alloc(const char *name) { struct net_device *dev; - dev = alloc_netdev((int) sizeof (struct ipoib_dev_priv), name, - ipoib_setup); + dev = alloc_netdev((int)sizeof(struct ipoib_dev_priv), name, + NET_NAME_UNKNOWN, ipoib_setup); if (!dev) return NULL; diff --git a/drivers/isdn/i4l/isdn_net.c b/drivers/isdn/i4l/isdn_net.c index d9aebbc510c..c2ed6246a38 100644 --- a/drivers/isdn/i4l/isdn_net.c +++ b/drivers/isdn/i4l/isdn_net.c @@ -2588,7 +2588,8 @@ isdn_net_new(char *name, struct net_device *master) printk(KERN_WARNING "isdn_net: Could not allocate net-device\n"); return NULL; } - netdev->dev = alloc_netdev(sizeof(isdn_net_local), name, _isdn_setup); + netdev->dev = alloc_netdev(sizeof(isdn_net_local), name, + NET_NAME_UNKNOWN, _isdn_setup); if (!netdev->dev) { printk(KERN_WARNING "isdn_net: Could not allocate network device\n"); kfree(netdev); diff --git a/drivers/media/dvb-core/dvb_net.c b/drivers/media/dvb-core/dvb_net.c index 8a86b302563..059e6117f22 100644 --- a/drivers/media/dvb-core/dvb_net.c +++ b/drivers/media/dvb-core/dvb_net.c @@ -1276,7 +1276,8 @@ static int dvb_net_add_if(struct dvb_net *dvbnet, u16 pid, u8 feedtype) if ((if_num = get_if(dvbnet)) < 0) return -EINVAL; - net = alloc_netdev(sizeof(struct dvb_net_priv), "dvb", dvb_net_setup); + net = alloc_netdev(sizeof(struct dvb_net_priv), "dvb", + NET_NAME_UNKNOWN, dvb_net_setup); if (!net) return -ENOMEM; diff --git a/drivers/misc/sgi-xp/xpnet.c b/drivers/misc/sgi-xp/xpnet.c index 3fac67a5204..557f9782c53 100644 --- a/drivers/misc/sgi-xp/xpnet.c +++ b/drivers/misc/sgi-xp/xpnet.c @@ -544,7 +544,8 @@ xpnet_init(void) * use ether_setup() to init the majority of our device * structure and then override the necessary pieces. */ - xpnet_device = alloc_netdev(0, XPNET_DEVICE_NAME, ether_setup); + xpnet_device = alloc_netdev(0, XPNET_DEVICE_NAME, NET_NAME_UNKNOWN, + ether_setup); if (xpnet_device == NULL) { kfree(xpnet_broadcast_partitions); return -ENOMEM; diff --git a/drivers/net/arcnet/arcnet.c b/drivers/net/arcnet/arcnet.c index a956053608f..3b790de6c97 100644 --- a/drivers/net/arcnet/arcnet.c +++ b/drivers/net/arcnet/arcnet.c @@ -346,7 +346,8 @@ struct net_device *alloc_arcdev(const char *name) struct net_device *dev; dev = alloc_netdev(sizeof(struct arcnet_local), - name && *name ? name : "arc%d", arcdev_setup); + name && *name ? name : "arc%d", NET_NAME_UNKNOWN, + arcdev_setup); if(dev) { struct arcnet_local *lp = netdev_priv(dev); spin_lock_init(&lp->lock); diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 09dc3ef771a..46dcb7b6216 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -4420,7 +4420,7 @@ int bond_create(struct net *net, const char *name) rtnl_lock(); bond_dev = alloc_netdev_mq(sizeof(struct bonding), - name ? name : "bond%d", + name ? name : "bond%d", NET_NAME_UNKNOWN, bond_setup, tx_queues); if (!bond_dev) { pr_err("%s: eek! can't alloc netdev!\n", name); diff --git a/drivers/net/caif/caif_serial.c b/drivers/net/caif/caif_serial.c index fc73865bb83..27bbc56de15 100644 --- a/drivers/net/caif/caif_serial.c +++ b/drivers/net/caif/caif_serial.c @@ -349,7 +349,8 @@ static int ldisc_open(struct tty_struct *tty) result = snprintf(name, sizeof(name), "cf%s", tty->name); if (result >= IFNAMSIZ) return -EINVAL; - dev = alloc_netdev(sizeof(*ser), name, caifdev_setup); + dev = alloc_netdev(sizeof(*ser), name, NET_NAME_UNKNOWN, + caifdev_setup); if (!dev) return -ENOMEM; diff --git a/drivers/net/caif/caif_spi.c b/drivers/net/caif/caif_spi.c index ff54c0eb205..72ea9ff9bb9 100644 --- a/drivers/net/caif/caif_spi.c +++ b/drivers/net/caif/caif_spi.c @@ -730,8 +730,8 @@ int cfspi_spi_probe(struct platform_device *pdev) int res; dev = (struct cfspi_dev *)pdev->dev.platform_data; - ndev = alloc_netdev(sizeof(struct cfspi), - "cfspi%d", cfspi_setup); + ndev = alloc_netdev(sizeof(struct cfspi), "cfspi%d", + NET_NAME_UNKNOWN, cfspi_setup); if (!dev) return -ENODEV; diff --git a/drivers/net/caif/caif_virtio.c b/drivers/net/caif/caif_virtio.c index 985608634f8..a5fefb9059c 100644 --- a/drivers/net/caif/caif_virtio.c +++ b/drivers/net/caif/caif_virtio.c @@ -661,7 +661,7 @@ static int cfv_probe(struct virtio_device *vdev) int err = -EINVAL; netdev = alloc_netdev(sizeof(struct cfv_info), cfv_netdev_name, - cfv_netdev_setup); + NET_NAME_UNKNOWN, cfv_netdev_setup); if (!netdev) return -ENOMEM; diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c index e318e87e2bf..9f91fcba43f 100644 --- a/drivers/net/can/dev.c +++ b/drivers/net/can/dev.c @@ -565,7 +565,7 @@ struct net_device *alloc_candev(int sizeof_priv, unsigned int echo_skb_max) else size = sizeof_priv; - dev = alloc_netdev(size, "can%d", can_setup); + dev = alloc_netdev(size, "can%d", NET_NAME_UNKNOWN, can_setup); if (!dev) return NULL; diff --git a/drivers/net/can/slcan.c b/drivers/net/can/slcan.c index ea4d4f1a641..acb5b92ace9 100644 --- a/drivers/net/can/slcan.c +++ b/drivers/net/can/slcan.c @@ -529,7 +529,7 @@ static struct slcan *slc_alloc(dev_t line) return NULL; sprintf(name, "slcan%d", i); - dev = alloc_netdev(sizeof(*sl), name, slc_setup); + dev = alloc_netdev(sizeof(*sl), name, NET_NAME_UNKNOWN, slc_setup); if (!dev) return NULL; diff --git a/drivers/net/dummy.c b/drivers/net/dummy.c index 0932ffbf381..ff435fbd1ad 100644 --- a/drivers/net/dummy.c +++ b/drivers/net/dummy.c @@ -164,7 +164,7 @@ static int __init dummy_init_one(void) struct net_device *dev_dummy; int err; - dev_dummy = alloc_netdev(0, "dummy%d", dummy_setup); + dev_dummy = alloc_netdev(0, "dummy%d", NET_NAME_UNKNOWN, dummy_setup); if (!dev_dummy) return -ENOMEM; diff --git a/drivers/net/eql.c b/drivers/net/eql.c index 7a79b604687..957e5c0cede 100644 --- a/drivers/net/eql.c +++ b/drivers/net/eql.c @@ -585,7 +585,8 @@ static int __init eql_init_module(void) pr_info("%s\n", version); - dev_eql = alloc_netdev(sizeof(equalizer_t), "eql", eql_setup); + dev_eql = alloc_netdev(sizeof(equalizer_t), "eql", NET_NAME_UNKNOWN, + eql_setup); if (!dev_eql) return -ENOMEM; diff --git a/drivers/net/ethernet/8390/lib8390.c b/drivers/net/ethernet/8390/lib8390.c index 599311f0e05..b96e8852b2d 100644 --- a/drivers/net/ethernet/8390/lib8390.c +++ b/drivers/net/ethernet/8390/lib8390.c @@ -986,7 +986,7 @@ static void ethdev_setup(struct net_device *dev) static struct net_device *____alloc_ei_netdev(int size) { return alloc_netdev(sizeof(struct ei_device) + size, "eth%d", - ethdev_setup); + NET_NAME_UNKNOWN, ethdev_setup); } diff --git a/drivers/net/ethernet/tile/tilegx.c b/drivers/net/ethernet/tile/tilegx.c index 4c70360967c..69557a26f74 100644 --- a/drivers/net/ethernet/tile/tilegx.c +++ b/drivers/net/ethernet/tile/tilegx.c @@ -2201,8 +2201,8 @@ static void tile_net_dev_init(const char *name, const uint8_t *mac) /* Allocate the device structure. Normally, "name" is a * template, instantiated by register_netdev(), but not for us. */ - dev = alloc_netdev_mqs(sizeof(*priv), name, tile_net_setup, - NR_CPUS, 1); + dev = alloc_netdev_mqs(sizeof(*priv), name, NET_NAME_UNKNOWN, + tile_net_setup, NR_CPUS, 1); if (!dev) { pr_err("alloc_netdev_mqs(%s) failed\n", name); return; diff --git a/drivers/net/ethernet/tile/tilepro.c b/drivers/net/ethernet/tile/tilepro.c index e5a5c5d4ce0..88c71212669 100644 --- a/drivers/net/ethernet/tile/tilepro.c +++ b/drivers/net/ethernet/tile/tilepro.c @@ -2292,7 +2292,8 @@ static struct net_device *tile_net_dev_init(const char *name) * tile_net_setup(), and saves "name". Normally, "name" is a * template, instantiated by register_netdev(), but not for us. */ - dev = alloc_netdev(sizeof(*priv), name, tile_net_setup); + dev = alloc_netdev(sizeof(*priv), name, NET_NAME_UNKNOWN, + tile_net_setup); if (!dev) { pr_err("alloc_netdev(%s) failed\n", name); return NULL; diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c index 66e2b19ef70..c3c4051a089 100644 --- a/drivers/net/hamradio/6pack.c +++ b/drivers/net/hamradio/6pack.c @@ -596,7 +596,8 @@ static int sixpack_open(struct tty_struct *tty) if (tty->ops->write == NULL) return -EOPNOTSUPP; - dev = alloc_netdev(sizeof(struct sixpack), "sp%d", sp_setup); + dev = alloc_netdev(sizeof(struct sixpack), "sp%d", NET_NAME_UNKNOWN, + sp_setup); if (!dev) { err = -ENOMEM; goto out; diff --git a/drivers/net/hamradio/baycom_epp.c b/drivers/net/hamradio/baycom_epp.c index 484f77ec2ce..a98c153f371 100644 --- a/drivers/net/hamradio/baycom_epp.c +++ b/drivers/net/hamradio/baycom_epp.c @@ -1206,7 +1206,7 @@ static int __init init_baycomepp(void) struct net_device *dev; dev = alloc_netdev(sizeof(struct baycom_state), "bce%d", - baycom_epp_dev_setup); + NET_NAME_UNKNOWN, baycom_epp_dev_setup); if (!dev) { printk(KERN_WARNING "bce%d : out of memory\n", i); diff --git a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c index d50b23cf9ea..c2894e43840 100644 --- a/drivers/net/hamradio/bpqether.c +++ b/drivers/net/hamradio/bpqether.c @@ -501,8 +501,8 @@ static int bpq_new_device(struct net_device *edev) struct net_device *ndev; struct bpqdev *bpq; - ndev = alloc_netdev(sizeof(struct bpqdev), "bpq%d", - bpq_setup); + ndev = alloc_netdev(sizeof(struct bpqdev), "bpq%d", NET_NAME_UNKNOWN, + bpq_setup); if (!ndev) return -ENOMEM; diff --git a/drivers/net/hamradio/dmascc.c b/drivers/net/hamradio/dmascc.c index 6636022a102..0fad408f24a 100644 --- a/drivers/net/hamradio/dmascc.c +++ b/drivers/net/hamradio/dmascc.c @@ -466,7 +466,7 @@ static int __init setup_adapter(int card_base, int type, int n) if (!info) goto out; - info->dev[0] = alloc_netdev(0, "", dev_setup); + info->dev[0] = alloc_netdev(0, "", NET_NAME_UNKNOWN, dev_setup); if (!info->dev[0]) { printk(KERN_ERR "dmascc: " "could not allocate memory for %s at %#3x\n", @@ -474,7 +474,7 @@ static int __init setup_adapter(int card_base, int type, int n) goto out1; } - info->dev[1] = alloc_netdev(0, "", dev_setup); + info->dev[1] = alloc_netdev(0, "", NET_NAME_UNKNOWN, dev_setup); if (!info->dev[1]) { printk(KERN_ERR "dmascc: " "could not allocate memory for %s at %#3x\n", diff --git a/drivers/net/hamradio/hdlcdrv.c b/drivers/net/hamradio/hdlcdrv.c index 5d78c1d08ab..c67a2724507 100644 --- a/drivers/net/hamradio/hdlcdrv.c +++ b/drivers/net/hamradio/hdlcdrv.c @@ -699,7 +699,7 @@ struct net_device *hdlcdrv_register(const struct hdlcdrv_ops *ops, if (privsize < sizeof(struct hdlcdrv_state)) privsize = sizeof(struct hdlcdrv_state); - dev = alloc_netdev(privsize, ifname, hdlcdrv_setup); + dev = alloc_netdev(privsize, ifname, NET_NAME_UNKNOWN, hdlcdrv_setup); if (!dev) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c index 8a6c720a4cc..f990bb1c3e0 100644 --- a/drivers/net/hamradio/mkiss.c +++ b/drivers/net/hamradio/mkiss.c @@ -734,7 +734,8 @@ static int mkiss_open(struct tty_struct *tty) if (tty->ops->write == NULL) return -EOPNOTSUPP; - dev = alloc_netdev(sizeof(struct mkiss), "ax%d", ax_setup); + dev = alloc_netdev(sizeof(struct mkiss), "ax%d", NET_NAME_UNKNOWN, + ax_setup); if (!dev) { err = -ENOMEM; goto out; diff --git a/drivers/net/hamradio/scc.c b/drivers/net/hamradio/scc.c index 4bc6ee8e798..57be9e0e98a 100644 --- a/drivers/net/hamradio/scc.c +++ b/drivers/net/hamradio/scc.c @@ -1515,7 +1515,7 @@ static int scc_net_alloc(const char *name, struct scc_channel *scc) int err; struct net_device *dev; - dev = alloc_netdev(0, name, scc_net_setup); + dev = alloc_netdev(0, name, NET_NAME_UNKNOWN, scc_net_setup); if (!dev) return -ENOMEM; diff --git a/drivers/net/hamradio/yam.c b/drivers/net/hamradio/yam.c index 81901659cc9..717433cfb81 100644 --- a/drivers/net/hamradio/yam.c +++ b/drivers/net/hamradio/yam.c @@ -1147,7 +1147,7 @@ static int __init yam_init_driver(void) sprintf(name, "yam%d", i); dev = alloc_netdev(sizeof(struct yam_port), name, - yam_setup); + NET_NAME_UNKNOWN, yam_setup); if (!dev) { pr_err("yam: cannot allocate net device\n"); err = -ENOMEM; diff --git a/drivers/net/ieee802154/fakehard.c b/drivers/net/ieee802154/fakehard.c index 78f18be3bbf..9ce854f4391 100644 --- a/drivers/net/ieee802154/fakehard.c +++ b/drivers/net/ieee802154/fakehard.c @@ -343,7 +343,8 @@ static int ieee802154fake_probe(struct platform_device *pdev) if (!phy) return -ENOMEM; - dev = alloc_netdev(sizeof(struct fakehard_priv), "hardwpan%d", ieee802154_fake_setup); + dev = alloc_netdev(sizeof(struct fakehard_priv), "hardwpan%d", + NET_NAME_UNKNOWN, ieee802154_fake_setup); if (!dev) { wpan_phy_free(phy); return -ENOMEM; diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c index 46a7790be00..d2d4a3d2237 100644 --- a/drivers/net/ifb.c +++ b/drivers/net/ifb.c @@ -269,8 +269,8 @@ static int __init ifb_init_one(int index) struct ifb_private *dp; int err; - dev_ifb = alloc_netdev(sizeof(struct ifb_private), - "ifb%d", ifb_setup); + dev_ifb = alloc_netdev(sizeof(struct ifb_private), "ifb%d", + NET_NAME_UNKNOWN, ifb_setup); if (!dev_ifb) return -ENOMEM; diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c index bb96409f8c0..8f226254056 100644 --- a/drivers/net/loopback.c +++ b/drivers/net/loopback.c @@ -195,7 +195,7 @@ static __net_init int loopback_net_init(struct net *net) int err; err = -ENOMEM; - dev = alloc_netdev(0, "lo", loopback_setup); + dev = alloc_netdev(0, "lo", NET_NAME_UNKNOWN, loopback_setup); if (!dev) goto out; diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c index 91d6c1272fc..5c002b1ef16 100644 --- a/drivers/net/ppp/ppp_generic.c +++ b/drivers/net/ppp/ppp_generic.c @@ -2665,7 +2665,8 @@ ppp_create_interface(struct net *net, int unit, int *retp) int ret = -ENOMEM; int i; - dev = alloc_netdev(sizeof(struct ppp), "", ppp_setup); + dev = alloc_netdev(sizeof(struct ppp), "", NET_NAME_UNKNOWN, + ppp_setup); if (!dev) goto out1; diff --git a/drivers/net/slip/slip.c b/drivers/net/slip/slip.c index 87526443841..05387b1e2e9 100644 --- a/drivers/net/slip/slip.c +++ b/drivers/net/slip/slip.c @@ -749,7 +749,7 @@ static struct slip *sl_alloc(dev_t line) return NULL; sprintf(name, "sl%d", i); - dev = alloc_netdev(sizeof(*sl), name, sl_setup); + dev = alloc_netdev(sizeof(*sl), name, NET_NAME_UNKNOWN, sl_setup); if (!dev) return NULL; diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 98bad1fb1bf..acaaf678417 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -1633,7 +1633,8 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) name = ifr->ifr_name; dev = alloc_netdev_mqs(sizeof(struct tun_struct), name, - tun_setup, queues, queues); + NET_NAME_UNKNOWN, tun_setup, queues, + queues); if (!dev) return -ENOMEM; diff --git a/drivers/net/usb/cdc-phonet.c b/drivers/net/usb/cdc-phonet.c index 6358d420e18..2ec1500d007 100644 --- a/drivers/net/usb/cdc-phonet.c +++ b/drivers/net/usb/cdc-phonet.c @@ -387,7 +387,7 @@ static int usbpn_probe(struct usb_interface *intf, const struct usb_device_id *i return -EINVAL; dev = alloc_netdev(sizeof(*pnd) + sizeof(pnd->urbs[0]) * rxq_size, - ifname, usbpn_setup); + ifname, NET_NAME_UNKNOWN, usbpn_setup); if (!dev) return -ENOMEM; diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index a3a05869309..50b36b29994 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -2520,7 +2520,8 @@ static struct hso_device *hso_create_net_device(struct usb_interface *interface, /* allocate our network device, then we can put in our private data */ /* call hso_net_init to do the basic initialization */ - net = alloc_netdev(sizeof(struct hso_net), "hso%d", hso_net_init); + net = alloc_netdev(sizeof(struct hso_net), "hso%d", NET_NAME_UNKNOWN, + hso_net_init); if (!net) { dev_err(&interface->dev, "Unable to create ethernet device\n"); goto exit; diff --git a/drivers/net/wan/dlci.c b/drivers/net/wan/dlci.c index 19f7cb2cdef..a463613a071 100644 --- a/drivers/net/wan/dlci.c +++ b/drivers/net/wan/dlci.c @@ -327,8 +327,8 @@ static int dlci_add(struct dlci_add *dlci) goto err1; /* create device name */ - master = alloc_netdev( sizeof(struct dlci_local), "dlci%d", - dlci_setup); + master = alloc_netdev(sizeof(struct dlci_local), "dlci%d", + NET_NAME_UNKNOWN, dlci_setup); if (!master) { err = -ENOMEM; goto err1; diff --git a/drivers/net/wan/hdlc.c b/drivers/net/wan/hdlc.c index 9c33ca918e1..51f6cee8aab 100644 --- a/drivers/net/wan/hdlc.c +++ b/drivers/net/wan/hdlc.c @@ -256,7 +256,8 @@ static void hdlc_setup(struct net_device *dev) struct net_device *alloc_hdlcdev(void *priv) { struct net_device *dev; - dev = alloc_netdev(sizeof(struct hdlc_device), "hdlc%d", hdlc_setup); + dev = alloc_netdev(sizeof(struct hdlc_device), "hdlc%d", + NET_NAME_UNKNOWN, hdlc_setup); if (dev) dev_to_hdlc(dev)->priv = priv; return dev; diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c index 7c6cb4f3179..7cc64eac0fa 100644 --- a/drivers/net/wan/hdlc_fr.c +++ b/drivers/net/wan/hdlc_fr.c @@ -1075,10 +1075,11 @@ static int fr_add_pvc(struct net_device *frad, unsigned int dlci, int type) used = pvc_is_used(pvc); if (type == ARPHRD_ETHER) { - dev = alloc_netdev(0, "pvceth%d", ether_setup); + dev = alloc_netdev(0, "pvceth%d", NET_NAME_UNKNOWN, + ether_setup); dev->priv_flags &= ~IFF_TX_SKB_SHARING; } else - dev = alloc_netdev(0, "pvc%d", pvc_setup); + dev = alloc_netdev(0, "pvc%d", NET_NAME_UNKNOWN, pvc_setup); if (!dev) { netdev_warn(frad, "Memory squeeze on fr_pvc()\n"); diff --git a/drivers/net/wan/lapbether.c b/drivers/net/wan/lapbether.c index a33a46fa88d..2f5eda8a722 100644 --- a/drivers/net/wan/lapbether.c +++ b/drivers/net/wan/lapbether.c @@ -325,8 +325,8 @@ static int lapbeth_new_device(struct net_device *dev) ASSERT_RTNL(); - ndev = alloc_netdev(sizeof(*lapbeth), "lapb%d", - lapbeth_setup); + ndev = alloc_netdev(sizeof(*lapbeth), "lapb%d", NET_NAME_UNKNOWN, + lapbeth_setup); if (!ndev) goto out; diff --git a/drivers/net/wan/sbni.c b/drivers/net/wan/sbni.c index 1b89ecf0959..758c4ba1e97 100644 --- a/drivers/net/wan/sbni.c +++ b/drivers/net/wan/sbni.c @@ -227,7 +227,8 @@ int __init sbni_probe(int unit) struct net_device *dev; int err; - dev = alloc_netdev(sizeof(struct net_local), "sbni", sbni_devsetup); + dev = alloc_netdev(sizeof(struct net_local), "sbni", + NET_NAME_UNKNOWN, sbni_devsetup); if (!dev) return -ENOMEM; @@ -1477,8 +1478,8 @@ int __init init_module( void ) int err; while( num < SBNI_MAX_NUM_CARDS ) { - dev = alloc_netdev(sizeof(struct net_local), - "sbni%d", sbni_devsetup); + dev = alloc_netdev(sizeof(struct net_local), "sbni%d", + NET_NAME_UNKNOWN, sbni_devsetup); if( !dev) break; diff --git a/drivers/net/wan/sdla.c b/drivers/net/wan/sdla.c index cdd45fb8a1f..421ac5f8569 100644 --- a/drivers/net/wan/sdla.c +++ b/drivers/net/wan/sdla.c @@ -1631,7 +1631,8 @@ static int __init init_sdla(void) printk("%s.\n", version); - sdla = alloc_netdev(sizeof(struct frad_local), "sdla0", setup_sdla); + sdla = alloc_netdev(sizeof(struct frad_local), "sdla0", + NET_NAME_UNKNOWN, setup_sdla); if (!sdla) return -ENOMEM; diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c index 5895f197869..df6c0735755 100644 --- a/drivers/net/wan/x25_asy.c +++ b/drivers/net/wan/x25_asy.c @@ -81,8 +81,8 @@ static struct x25_asy *x25_asy_alloc(void) char name[IFNAMSIZ]; sprintf(name, "x25asy%d", i); - dev = alloc_netdev(sizeof(struct x25_asy), - name, x25_asy_setup); + dev = alloc_netdev(sizeof(struct x25_asy), name, + NET_NAME_UNKNOWN, x25_asy_setup); if (!dev) return NULL; diff --git a/drivers/net/wimax/i2400m/usb.c b/drivers/net/wimax/i2400m/usb.c index cd15a93d908..e7f5910a651 100644 --- a/drivers/net/wimax/i2400m/usb.c +++ b/drivers/net/wimax/i2400m/usb.c @@ -472,7 +472,7 @@ int i2400mu_probe(struct usb_interface *iface, /* Allocate instance [calls i2400m_netdev_setup() on it]. */ result = -ENOMEM; - net_dev = alloc_netdev(sizeof(*i2400mu), "wmx%d", + net_dev = alloc_netdev(sizeof(*i2400mu), "wmx%d", NET_NAME_UNKNOWN, i2400mu_netdev_setup); if (net_dev == NULL) { dev_err(dev, "no memory for network device instance\n"); diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index 64747d457bb..29d88739454 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c @@ -2685,7 +2685,8 @@ static struct net_device *init_wifidev(struct airo_info *ai, struct net_device *ethdev) { int err; - struct net_device *dev = alloc_netdev(0, "wifi%d", wifi_setup); + struct net_device *dev = alloc_netdev(0, "wifi%d", NET_NAME_UNKNOWN, + wifi_setup); if (!dev) return NULL; dev->ml_priv = ethdev->ml_priv; @@ -2785,7 +2786,7 @@ static struct net_device *_init_airo_card( unsigned short irq, int port, CapabilityRid cap_rid; /* Create the network device object. */ - dev = alloc_netdev(sizeof(*ai), "", ether_setup); + dev = alloc_netdev(sizeof(*ai), "", NET_NAME_UNKNOWN, ether_setup); if (!dev) { airo_print_err("", "Couldn't alloc_etherdev"); return NULL; diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index 0e26f4a34fd..1c4ce8e3eeb 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -3636,7 +3636,7 @@ struct wireless_dev *ath6kl_interface_add(struct ath6kl *ar, const char *name, struct net_device *ndev; struct ath6kl_vif *vif; - ndev = alloc_netdev(sizeof(*vif), name, ether_setup); + ndev = alloc_netdev(sizeof(*vif), name, NET_NAME_UNKNOWN, ether_setup); if (!ndev) return NULL; diff --git a/drivers/net/wireless/ath/wil6210/netdev.c b/drivers/net/wireless/ath/wil6210/netdev.c index 106b6dcb773..7afce6e8c50 100644 --- a/drivers/net/wireless/ath/wil6210/netdev.c +++ b/drivers/net/wireless/ath/wil6210/netdev.c @@ -132,7 +132,7 @@ void *wil_if_alloc(struct device *dev, void __iomem *csr) ch = wdev->wiphy->bands[IEEE80211_BAND_60GHZ]->channels; cfg80211_chandef_create(&wdev->preset_chandef, ch, NL80211_CHAN_NO_HT); - ndev = alloc_netdev(0, "wlan%d", ether_setup); + ndev = alloc_netdev(0, "wlan%d", NET_NAME_UNKNOWN, ether_setup); if (!ndev) { dev_err(dev, "alloc_netdev_mqs failed\n"); rc = -ENOMEM; diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index 09dd8c13d84..2699441d4f4 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c @@ -808,7 +808,8 @@ struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, s32 ifidx, } else { brcmf_dbg(INFO, "allocate netdev interface\n"); /* Allocate netdev, including space for private structure */ - ndev = alloc_netdev(sizeof(*ifp), name, ether_setup); + ndev = alloc_netdev(sizeof(*ifp), name, NET_NAME_UNKNOWN, + ether_setup); if (!ndev) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index 0c02f0483d1..569b64ecc60 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c @@ -981,7 +981,7 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev) goto err_wdev; } - dev = alloc_netdev(0, "wlan%d", ether_setup); + dev = alloc_netdev(0, "wlan%d", NET_NAME_UNKNOWN, ether_setup); if (!dev) { dev_err(dmdev, "no memory for network device instance\n"); goto err_adapter; diff --git a/drivers/net/wireless/libertas/mesh.c b/drivers/net/wireless/libertas/mesh.c index 6fef746345b..01a67f62696 100644 --- a/drivers/net/wireless/libertas/mesh.c +++ b/drivers/net/wireless/libertas/mesh.c @@ -1000,7 +1000,7 @@ static int lbs_add_mesh(struct lbs_private *priv) goto done; } - mesh_dev = alloc_netdev(0, "msh%d", ether_setup); + mesh_dev = alloc_netdev(0, "msh%d", NET_NAME_UNKNOWN, ether_setup); if (!mesh_dev) { lbs_deb_mesh("init mshX device failed\n"); ret = -ENOMEM; diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index eba51460a5d..5ea65fce0b8 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -2676,7 +2676,8 @@ static int __init init_mac80211_hwsim(void) goto out_free_radios; } - hwsim_mon = alloc_netdev(0, "hwsim%d", hwsim_mon_setup); + hwsim_mon = alloc_netdev(0, "hwsim%d", NET_NAME_UNKNOWN, + hwsim_mon_setup); if (hwsim_mon == NULL) { err = -ENOMEM; goto out_free_radios; diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 6af135fa99f..ca87f923c61 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -2232,7 +2232,8 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy, } dev = alloc_netdev_mqs(sizeof(struct mwifiex_private *), name, - ether_setup, IEEE80211_NUM_ACS, 1); + NET_NAME_UNKNOWN, ether_setup, + IEEE80211_NUM_ACS, 1); if (!dev) { wiphy_err(wiphy, "no memory available for netdevice\n"); priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED; diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c index ef75b45e508..bd59d9dbf27 100644 --- a/drivers/net/xen-netback/interface.c +++ b/drivers/net/xen-netback/interface.c @@ -418,8 +418,8 @@ struct xenvif *xenvif_alloc(struct device *parent, domid_t domid, * When the guest selects the desired number, it will be updated * via netif_set_real_num_*_queues(). */ - dev = alloc_netdev_mq(sizeof(struct xenvif), name, ether_setup, - xenvif_max_queues); + dev = alloc_netdev_mq(sizeof(struct xenvif), name, NET_NAME_UNKNOWN, + ether_setup, xenvif_max_queues); if (dev == NULL) { pr_warn("Could not allocate netdev for %s\n", name); return ERR_PTR(-ENOMEM); diff --git a/drivers/s390/net/claw.c b/drivers/s390/net/claw.c index d837c3c5330..fbc6701bef3 100644 --- a/drivers/s390/net/claw.c +++ b/drivers/s390/net/claw.c @@ -2915,7 +2915,7 @@ claw_new_device(struct ccwgroup_device *cgdev) "failed with error code %d\n", ret); goto out; } - dev = alloc_netdev(0,"claw%d",claw_init_netdevice); + dev = alloc_netdev(0, "claw%d", NET_NAME_UNKNOWN, claw_init_netdevice); if (!dev) { dev_warn(&cgdev->dev, "Activating the CLAW device failed\n"); diff --git a/drivers/s390/net/ctcm_main.c b/drivers/s390/net/ctcm_main.c index 03b6ad03557..e056dd4fe44 100644 --- a/drivers/s390/net/ctcm_main.c +++ b/drivers/s390/net/ctcm_main.c @@ -1137,9 +1137,11 @@ static struct net_device *ctcm_init_netdevice(struct ctcm_priv *priv) return NULL; if (IS_MPC(priv)) - dev = alloc_netdev(0, MPC_DEVICE_GENE, ctcm_dev_setup); + dev = alloc_netdev(0, MPC_DEVICE_GENE, NET_NAME_UNKNOWN, + ctcm_dev_setup); else - dev = alloc_netdev(0, CTC_DEVICE_GENE, ctcm_dev_setup); + dev = alloc_netdev(0, CTC_DEVICE_GENE, NET_NAME_UNKNOWN, + ctcm_dev_setup); if (!dev) { CTCM_DBF_TEXT_(ERROR, CTC_DBF_CRIT, diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c index ce16d1bdb20..0a87809c8af 100644 --- a/drivers/s390/net/netiucv.c +++ b/drivers/s390/net/netiucv.c @@ -2015,7 +2015,7 @@ static struct net_device *netiucv_init_netdevice(char *username, char *userdata) struct net_device *dev; dev = alloc_netdev(sizeof(struct netiucv_priv), "iucv%d", - netiucv_setup_netdevice); + NET_NAME_UNKNOWN, netiucv_setup_netdevice); if (!dev) return NULL; rtnl_lock(); diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 5ef5b4f4575..c2679bfe7f6 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -952,10 +952,12 @@ static int qeth_l2_setup_netdev(struct qeth_card *card) { switch (card->info.type) { case QETH_CARD_TYPE_IQD: - card->dev = alloc_netdev(0, "hsi%d", ether_setup); + card->dev = alloc_netdev(0, "hsi%d", NET_NAME_UNKNOWN, + ether_setup); break; case QETH_CARD_TYPE_OSN: - card->dev = alloc_netdev(0, "osn%d", ether_setup); + card->dev = alloc_netdev(0, "osn%d", NET_NAME_UNKNOWN, + ether_setup); card->dev->flags |= IFF_NOARP; break; default: diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 14e0b5810e8..f8427a2c484 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -3287,7 +3287,8 @@ static int qeth_l3_setup_netdev(struct qeth_card *card) } } } else if (card->info.type == QETH_CARD_TYPE_IQD) { - card->dev = alloc_netdev(0, "hsi%d", ether_setup); + card->dev = alloc_netdev(0, "hsi%d", NET_NAME_UNKNOWN, + ether_setup); if (!card->dev) return -ENODEV; card->dev->flags |= IFF_NOARP; diff --git a/drivers/staging/cxt1e1/linux.c b/drivers/staging/cxt1e1/linux.c index 09f3d5ca75a..85d776bbfb1 100644 --- a/drivers/staging/cxt1e1/linux.c +++ b/drivers/staging/cxt1e1/linux.c @@ -917,7 +917,8 @@ c4_add_dev(hdw_info_t *hi, int brdno, unsigned long f0, unsigned long f1, struct net_device *ndev; ci_t *ci; - ndev = alloc_netdev(sizeof(ci_t), SBE_IFACETMPL, c4_setup); + ndev = alloc_netdev(sizeof(ci_t), SBE_IFACETMPL, NET_NAME_UNKNOWN, + c4_setup); if (!ndev) { pr_warning("%s: no memory for struct net_device !\n", hi->devname); diff --git a/drivers/staging/gdm724x/gdm_lte.c b/drivers/staging/gdm724x/gdm_lte.c index 64c55b99fda..c2268527422 100644 --- a/drivers/staging/gdm724x/gdm_lte.c +++ b/drivers/staging/gdm724x/gdm_lte.c @@ -885,7 +885,7 @@ int register_lte_device(struct phy_dev *phy_dev, /* Allocate netdev */ net = alloc_netdev(sizeof(struct nic), pdn_dev_name, - ether_setup); + NET_NAME_UNKNOWN, ether_setup); if (net == NULL) { pr_err("alloc_netdev failed\n"); ret = -ENOMEM; diff --git a/drivers/staging/gdm72xx/gdm_wimax.c b/drivers/staging/gdm72xx/gdm_wimax.c index e5e51158512..a9a6fc51024 100644 --- a/drivers/staging/gdm72xx/gdm_wimax.c +++ b/drivers/staging/gdm72xx/gdm_wimax.c @@ -886,7 +886,8 @@ int register_wimax_device(struct phy_dev *phy_dev, struct device *pdev) struct net_device *dev; int ret; - dev = alloc_netdev(sizeof(*nic), "wm%d", ether_setup); + dev = alloc_netdev(sizeof(*nic), "wm%d", NET_NAME_UNKNOWN, + ether_setup); if (dev == NULL) { pr_err("alloc_etherdev failed\n"); diff --git a/drivers/staging/vt6655/wpactl.c b/drivers/staging/vt6655/wpactl.c index 8392d4d1d5e..0814bfd68b2 100644 --- a/drivers/staging/vt6655/wpactl.c +++ b/drivers/staging/vt6655/wpactl.c @@ -89,7 +89,8 @@ static int wpa_init_wpadev(PSDevice pDevice) struct net_device *dev = pDevice->dev; int ret = 0; - pDevice->wpadev = alloc_netdev(sizeof(PSDevice), "vntwpa", wpadev_setup); + pDevice->wpadev = alloc_netdev(sizeof(PSDevice), "vntwpa", + NET_NAME_UNKNOWN, wpadev_setup); if (pDevice->wpadev == NULL) return -ENOMEM; diff --git a/drivers/staging/wlan-ng/p80211netdev.c b/drivers/staging/wlan-ng/p80211netdev.c index 00b186c5972..6c78f917e24 100644 --- a/drivers/staging/wlan-ng/p80211netdev.c +++ b/drivers/staging/wlan-ng/p80211netdev.c @@ -769,7 +769,7 @@ int wlan_setup(wlandevice_t *wlandev, struct device *physdev) /* Allocate and initialize the struct device */ netdev = alloc_netdev(sizeof(struct wireless_dev), "wlan%d", - ether_setup); + NET_NAME_UNKNOWN, ether_setup); if (netdev == NULL) { dev_err(physdev, "Failed to alloc netdev.\n"); wlan_free_wiphy(wiphy); diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 2ebe47b78a3..cde3ab97900 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -2789,9 +2789,8 @@ static int gsm_create_network(struct gsm_dlci *dlci, struct gsm_netconfig *nc) netname = "gsm%d"; if (nc->if_name[0] != '\0') netname = nc->if_name; - net = alloc_netdev(sizeof(struct gsm_mux_net), - netname, - gsm_mux_net_init); + net = alloc_netdev(sizeof(struct gsm_mux_net), netname, + NET_NAME_UNKNOWN, gsm_mux_net_init); if (!net) { pr_err("alloc_netdev failed"); return -ENOMEM; diff --git a/drivers/usb/gadget/f_phonet.c b/drivers/usb/gadget/f_phonet.c index f2b781773ee..b9cfc1571d7 100644 --- a/drivers/usb/gadget/f_phonet.c +++ b/drivers/usb/gadget/f_phonet.c @@ -721,7 +721,8 @@ struct net_device *gphonet_setup_default(void) struct phonet_port *port; /* Create net device */ - dev = alloc_netdev(sizeof(*port), "upnlink%d", pn_net_setup); + dev = alloc_netdev(sizeof(*port), "upnlink%d", NET_NAME_UNKNOWN, + pn_net_setup); if (!dev) return ERR_PTR(-ENOMEM); diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 9be34732142..15ed750458a 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -2991,13 +2991,15 @@ void ether_setup(struct net_device *dev); /* Support for loadable net-drivers */ struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name, + unsigned char name_assign_type, void (*setup)(struct net_device *), unsigned int txqs, unsigned int rxqs); -#define alloc_netdev(sizeof_priv, name, setup) \ - alloc_netdev_mqs(sizeof_priv, name, setup, 1, 1) +#define alloc_netdev(sizeof_priv, name, name_assign_type, setup) \ + alloc_netdev_mqs(sizeof_priv, name, name_assign_type, setup, 1, 1) -#define alloc_netdev_mq(sizeof_priv, name, setup, count) \ - alloc_netdev_mqs(sizeof_priv, name, setup, count, count) +#define alloc_netdev_mq(sizeof_priv, name, name_assign_type, setup, count) \ + alloc_netdev_mqs(sizeof_priv, name, name_assign_type, setup, count, \ + count) int register_netdev(struct net_device *dev); void unregister_netdev(struct net_device *dev); diff --git a/net/802/fc.c b/net/802/fc.c index 05eea6b98bb..7c174b6750c 100644 --- a/net/802/fc.c +++ b/net/802/fc.c @@ -126,6 +126,6 @@ static void fc_setup(struct net_device *dev) */ struct net_device *alloc_fcdev(int sizeof_priv) { - return alloc_netdev(sizeof_priv, "fc%d", fc_setup); + return alloc_netdev(sizeof_priv, "fc%d", NET_NAME_UNKNOWN, fc_setup); } EXPORT_SYMBOL(alloc_fcdev); diff --git a/net/802/fddi.c b/net/802/fddi.c index 9cda40661e0..59e7346f119 100644 --- a/net/802/fddi.c +++ b/net/802/fddi.c @@ -207,7 +207,8 @@ static void fddi_setup(struct net_device *dev) */ struct net_device *alloc_fddidev(int sizeof_priv) { - return alloc_netdev(sizeof_priv, "fddi%d", fddi_setup); + return alloc_netdev(sizeof_priv, "fddi%d", NET_NAME_UNKNOWN, + fddi_setup); } EXPORT_SYMBOL(alloc_fddidev); diff --git a/net/802/hippi.c b/net/802/hippi.c index 5ff2a718ddc..2e03f8259dd 100644 --- a/net/802/hippi.c +++ b/net/802/hippi.c @@ -228,7 +228,8 @@ static void hippi_setup(struct net_device *dev) struct net_device *alloc_hippi_dev(int sizeof_priv) { - return alloc_netdev(sizeof_priv, "hip%d", hippi_setup); + return alloc_netdev(sizeof_priv, "hip%d", NET_NAME_UNKNOWN, + hippi_setup); } EXPORT_SYMBOL(alloc_hippi_dev); diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index 44ebd5c2cd4..cba9c212a73 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c @@ -250,7 +250,8 @@ static int register_vlan_device(struct net_device *real_dev, u16 vlan_id) snprintf(name, IFNAMSIZ, "vlan%.4i", vlan_id); } - new_dev = alloc_netdev(sizeof(struct vlan_dev_priv), name, vlan_setup); + new_dev = alloc_netdev(sizeof(struct vlan_dev_priv), name, + NET_NAME_UNKNOWN, vlan_setup); if (new_dev == NULL) return -ENOBUFS; diff --git a/net/appletalk/dev.c b/net/appletalk/dev.c index 6c8016f6186..e4158b8b926 100644 --- a/net/appletalk/dev.c +++ b/net/appletalk/dev.c @@ -39,6 +39,7 @@ static void ltalk_setup(struct net_device *dev) struct net_device *alloc_ltalkdev(int sizeof_priv) { - return alloc_netdev(sizeof_priv, "lt%d", ltalk_setup); + return alloc_netdev(sizeof_priv, "lt%d", NET_NAME_UNKNOWN, + ltalk_setup); } EXPORT_SYMBOL(alloc_ltalkdev); diff --git a/net/atm/br2684.c b/net/atm/br2684.c index 403e71fa88f..cc78538d163 100644 --- a/net/atm/br2684.c +++ b/net/atm/br2684.c @@ -682,8 +682,8 @@ static int br2684_create(void __user *arg) netdev = alloc_netdev(sizeof(struct br2684_dev), ni.ifname[0] ? ni.ifname : "nas%d", - (payload == p_routed) ? - br2684_setup_routed : br2684_setup); + NET_NAME_UNKNOWN, + (payload == p_routed) ? br2684_setup_routed : br2684_setup); if (!netdev) return -ENOMEM; diff --git a/net/atm/clip.c b/net/atm/clip.c index ba291ce4bdf..46339040fef 100644 --- a/net/atm/clip.c +++ b/net/atm/clip.c @@ -520,7 +520,8 @@ static int clip_create(int number) if (PRIV(dev)->number >= number) number = PRIV(dev)->number + 1; } - dev = alloc_netdev(sizeof(struct clip_priv), "", clip_setup); + dev = alloc_netdev(sizeof(struct clip_priv), "", NET_NAME_UNKNOWN, + clip_setup); if (!dev) return -ENOMEM; clip_priv = PRIV(dev); diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index e7ee65dc20b..d551e6302cf 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c @@ -895,7 +895,7 @@ struct net_device *batadv_softif_create(const char *name) int ret; soft_iface = alloc_netdev(sizeof(struct batadv_priv), name, - batadv_softif_init_early); + NET_NAME_UNKNOWN, batadv_softif_init_early); if (!soft_iface) return NULL; diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c index 5a7f81df603..206b65ccd5b 100644 --- a/net/bluetooth/6lowpan.c +++ b/net/bluetooth/6lowpan.c @@ -712,7 +712,7 @@ static int setup_netdev(struct l2cap_chan *chan, struct lowpan_dev **dev) unsigned long flags; netdev = alloc_netdev(sizeof(struct lowpan_dev), IFACE_NAME_TEMPLATE, - netdev_setup); + NET_NAME_UNKNOWN, netdev_setup); if (!netdev) return -ENOMEM; diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c index a841d3e776c..85bcc21e84d 100644 --- a/net/bluetooth/bnep/core.c +++ b/net/bluetooth/bnep/core.c @@ -538,8 +538,9 @@ int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock) /* session struct allocated as private part of net_device */ dev = alloc_netdev(sizeof(struct bnep_session), - (*req->device) ? req->device : "bnep%d", - bnep_net_setup); + (*req->device) ? req->device : "bnep%d", + NET_NAME_UNKNOWN, + bnep_net_setup); if (!dev) return -ENOMEM; diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index 3eca3fdf8fe..078d336a1f3 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c @@ -344,7 +344,7 @@ int br_add_bridge(struct net *net, const char *name) struct net_device *dev; int res; - dev = alloc_netdev(sizeof(struct net_bridge), name, + dev = alloc_netdev(sizeof(struct net_bridge), name, NET_NAME_UNKNOWN, br_dev_setup); if (!dev) diff --git a/net/core/dev.c b/net/core/dev.c index 38793fb84a3..2c98f10ee62 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -6441,17 +6441,19 @@ void netdev_freemem(struct net_device *dev) /** * alloc_netdev_mqs - allocate network device - * @sizeof_priv: size of private data to allocate space for - * @name: device name format string - * @setup: callback to initialize device - * @txqs: the number of TX subqueues to allocate - * @rxqs: the number of RX subqueues to allocate + * @sizeof_priv: size of private data to allocate space for + * @name: device name format string + * @name_assign_type: origin of device name + * @setup: callback to initialize device + * @txqs: the number of TX subqueues to allocate + * @rxqs: the number of RX subqueues to allocate * * Allocates a struct net_device with private data area for driver use * and performs basic initialization. Also allocates subqueue structs * for each queue on the device. */ struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name, + unsigned char name_assign_type, void (*setup)(struct net_device *), unsigned int txqs, unsigned int rxqs) { @@ -6530,6 +6532,7 @@ struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name, #endif strcpy(dev->name, name); + dev->name_assign_type = name_assign_type; dev->group = INIT_NETDEV_GROUP; if (!dev->ethtool_ops) dev->ethtool_ops = &default_ethtool_ops; diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 1f8a59e02c4..599864322de 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -1828,8 +1828,8 @@ struct net_device *rtnl_create_link(struct net *net, num_rx_queues = ops->get_num_rx_queues(); err = -ENOMEM; - dev = alloc_netdev_mqs(ops->priv_size, ifname, ops->setup, - num_tx_queues, num_rx_queues); + dev = alloc_netdev_mqs(ops->priv_size, ifname, NET_NAME_UNKNOWN, + ops->setup, num_tx_queues, num_rx_queues); if (!dev) goto err; diff --git a/net/dsa/slave.c b/net/dsa/slave.c index 64c5af0a10d..45a1e34c89e 100644 --- a/net/dsa/slave.c +++ b/net/dsa/slave.c @@ -340,8 +340,8 @@ dsa_slave_create(struct dsa_switch *ds, struct device *parent, struct dsa_slave_priv *p; int ret; - slave_dev = alloc_netdev(sizeof(struct dsa_slave_priv), - name, ether_setup); + slave_dev = alloc_netdev(sizeof(struct dsa_slave_priv), name, + NET_NAME_UNKNOWN, ether_setup); if (slave_dev == NULL) return slave_dev; diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c index 5dc638cad2e..f405e059240 100644 --- a/net/ethernet/eth.c +++ b/net/ethernet/eth.c @@ -390,7 +390,8 @@ EXPORT_SYMBOL(ether_setup); struct net_device *alloc_etherdev_mqs(int sizeof_priv, unsigned int txqs, unsigned int rxqs) { - return alloc_netdev_mqs(sizeof_priv, "eth%d", ether_setup, txqs, rxqs); + return alloc_netdev_mqs(sizeof_priv, "eth%d", NET_NAME_UNKNOWN, + ether_setup, txqs, rxqs); } EXPORT_SYMBOL(alloc_etherdev_mqs); diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c index 54b6731dab5..0157a7af20a 100644 --- a/net/ipv4/ip_tunnel.c +++ b/net/ipv4/ip_tunnel.c @@ -301,7 +301,7 @@ static struct net_device *__ip_tunnel_create(struct net *net, } ASSERT_RTNL(); - dev = alloc_netdev(ops->priv_size, name, ops->setup); + dev = alloc_netdev(ops->priv_size, name, NET_NAME_UNKNOWN, ops->setup); if (!dev) { err = -ENOMEM; goto failed; diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 65bcaa78904..c8034587859 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -500,7 +500,7 @@ static struct net_device *ipmr_reg_vif(struct net *net, struct mr_table *mrt) else sprintf(name, "pimreg%u", mrt->id); - dev = alloc_netdev(0, name, reg_vif_setup); + dev = alloc_netdev(0, name, NET_NAME_UNKNOWN, reg_vif_setup); if (dev == NULL) return NULL; diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c index 365b2b6f394..5f19dfbc4c6 100644 --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c @@ -322,7 +322,8 @@ static struct ip6_tnl *ip6gre_tunnel_locate(struct net *net, else strcpy(name, "ip6gre%d"); - dev = alloc_netdev(sizeof(*t), name, ip6gre_tunnel_setup); + dev = alloc_netdev(sizeof(*t), name, NET_NAME_UNKNOWN, + ip6gre_tunnel_setup); if (!dev) return NULL; @@ -1326,7 +1327,8 @@ static int __net_init ip6gre_init_net(struct net *net) int err; ign->fb_tunnel_dev = alloc_netdev(sizeof(struct ip6_tnl), "ip6gre0", - ip6gre_tunnel_setup); + NET_NAME_UNKNOWN, + ip6gre_tunnel_setup); if (!ign->fb_tunnel_dev) { err = -ENOMEM; goto err_alloc_dev; diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 51a1eb185ea..f9de5a69507 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -315,7 +315,8 @@ static struct ip6_tnl *ip6_tnl_create(struct net *net, struct __ip6_tnl_parm *p) else sprintf(name, "ip6tnl%%d"); - dev = alloc_netdev(sizeof (*t), name, ip6_tnl_dev_setup); + dev = alloc_netdev(sizeof(*t), name, NET_NAME_UNKNOWN, + ip6_tnl_dev_setup); if (dev == NULL) goto failed; @@ -1773,7 +1774,7 @@ static int __net_init ip6_tnl_init_net(struct net *net) err = -ENOMEM; ip6n->fb_tnl_dev = alloc_netdev(sizeof(struct ip6_tnl), "ip6tnl0", - ip6_tnl_dev_setup); + NET_NAME_UNKNOWN, ip6_tnl_dev_setup); if (!ip6n->fb_tnl_dev) goto err_alloc_dev; diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c index 9aaa6bb229e..17ee4fc32df 100644 --- a/net/ipv6/ip6_vti.c +++ b/net/ipv6/ip6_vti.c @@ -204,7 +204,7 @@ static struct ip6_tnl *vti6_tnl_create(struct net *net, struct __ip6_tnl_parm *p else sprintf(name, "ip6_vti%%d"); - dev = alloc_netdev(sizeof(*t), name, vti6_dev_setup); + dev = alloc_netdev(sizeof(*t), name, NET_NAME_UNKNOWN, vti6_dev_setup); if (dev == NULL) goto failed; @@ -1020,7 +1020,7 @@ static int __net_init vti6_init_net(struct net *net) err = -ENOMEM; ip6n->fb_tnl_dev = alloc_netdev(sizeof(struct ip6_tnl), "ip6_vti0", - vti6_dev_setup); + NET_NAME_UNKNOWN, vti6_dev_setup); if (!ip6n->fb_tnl_dev) goto err_alloc_dev; diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index 8250474ab7d..f9a3fd320d1 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c @@ -744,7 +744,7 @@ static struct net_device *ip6mr_reg_vif(struct net *net, struct mr6_table *mrt) else sprintf(name, "pim6reg%u", mrt->id); - dev = alloc_netdev(0, name, reg_vif_setup); + dev = alloc_netdev(0, name, NET_NAME_UNKNOWN, reg_vif_setup); if (dev == NULL) return NULL; diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 4f408176dc6..2e9ba035fb5 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -250,7 +250,8 @@ static struct ip_tunnel *ipip6_tunnel_locate(struct net *net, else strcpy(name, "sit%d"); - dev = alloc_netdev(sizeof(*t), name, ipip6_tunnel_setup); + dev = alloc_netdev(sizeof(*t), name, NET_NAME_UNKNOWN, + ipip6_tunnel_setup); if (dev == NULL) return NULL; @@ -1729,6 +1730,7 @@ static int __net_init sit_init_net(struct net *net) sitn->tunnels[3] = sitn->tunnels_r_l; sitn->fb_tunnel_dev = alloc_netdev(sizeof(struct ip_tunnel), "sit0", + NET_NAME_UNKNOWN, ipip6_tunnel_setup); if (!sitn->fb_tunnel_dev) { err = -ENOMEM; diff --git a/net/irda/irda_device.c b/net/irda/irda_device.c index 365b895da84..9e0d909390f 100644 --- a/net/irda/irda_device.c +++ b/net/irda/irda_device.c @@ -293,7 +293,8 @@ static void irda_device_setup(struct net_device *dev) */ struct net_device *alloc_irdadev(int sizeof_priv) { - return alloc_netdev(sizeof_priv, "irda%d", irda_device_setup); + return alloc_netdev(sizeof_priv, "irda%d", NET_NAME_UNKNOWN, + irda_device_setup); } EXPORT_SYMBOL(alloc_irdadev); diff --git a/net/irda/irlan/irlan_eth.c b/net/irda/irlan/irlan_eth.c index ffcec225b5d..dc13f1a45f2 100644 --- a/net/irda/irlan/irlan_eth.c +++ b/net/irda/irlan/irlan_eth.c @@ -96,7 +96,7 @@ static void irlan_eth_setup(struct net_device *dev) */ struct net_device *alloc_irlandev(const char *name) { - return alloc_netdev(sizeof(struct irlan_cb), name, + return alloc_netdev(sizeof(struct irlan_cb), name, NET_NAME_UNKNOWN, irlan_eth_setup); } diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c index 76125c57ee6..edb78e69efe 100644 --- a/net/l2tp/l2tp_eth.c +++ b/net/l2tp/l2tp_eth.c @@ -246,7 +246,8 @@ static int l2tp_eth_create(struct net *net, u32 tunnel_id, u32 session_id, u32 p goto out; } - dev = alloc_netdev(sizeof(*priv), name, l2tp_eth_dev_setup); + dev = alloc_netdev(sizeof(*priv), name, NET_NAME_UNKNOWN, + l2tp_eth_dev_setup); if (!dev) { rc = -ENOMEM; goto out_del_session; diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index bbf51b2f065..4edfc7c1524 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -1624,9 +1624,9 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, if (local->hw.queues >= IEEE80211_NUM_ACS) txqs = IEEE80211_NUM_ACS; - ndev = alloc_netdev_mqs(sizeof(*sdata) + - local->hw.vif_data_size, - name, ieee80211_if_setup, txqs, 1); + ndev = alloc_netdev_mqs(sizeof(*sdata) + local->hw.vif_data_size, + name, NET_NAME_UNKNOWN, + ieee80211_if_setup, txqs, 1); if (!ndev) return -ENOMEM; dev_net_set(ndev, wiphy_net(local->hw.wiphy)); diff --git a/net/mac802154/ieee802154_dev.c b/net/mac802154/ieee802154_dev.c index 9b54370f5e8..b36b2b99657 100644 --- a/net/mac802154/ieee802154_dev.c +++ b/net/mac802154/ieee802154_dev.c @@ -167,11 +167,13 @@ mac802154_add_iface(struct wpan_phy *phy, const char *name, int type) switch (type) { case IEEE802154_DEV_MONITOR: dev = alloc_netdev(sizeof(struct mac802154_sub_if_data), - name, mac802154_monitor_setup); + name, NET_NAME_UNKNOWN, + mac802154_monitor_setup); break; case IEEE802154_DEV_WPAN: dev = alloc_netdev(sizeof(struct mac802154_sub_if_data), - name, mac802154_wpan_setup); + name, NET_NAME_UNKNOWN, + mac802154_wpan_setup); break; default: dev = NULL; diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c index ede50d197e1..71cf1bffea0 100644 --- a/net/netrom/af_netrom.c +++ b/net/netrom/af_netrom.c @@ -1418,7 +1418,7 @@ static int __init nr_proto_init(void) struct net_device *dev; sprintf(name, "nr%d", i); - dev = alloc_netdev(0, name, nr_setup); + dev = alloc_netdev(0, name, NET_NAME_UNKNOWN, nr_setup); if (!dev) { printk(KERN_ERR "NET/ROM: nr_proto_init - unable to allocate device structure\n"); goto fail; diff --git a/net/openvswitch/vport-internal_dev.c b/net/openvswitch/vport-internal_dev.c index 295471a66c7..bd658555afd 100644 --- a/net/openvswitch/vport-internal_dev.c +++ b/net/openvswitch/vport-internal_dev.c @@ -165,7 +165,8 @@ static struct vport *internal_dev_create(const struct vport_parms *parms) netdev_vport = netdev_vport_priv(vport); netdev_vport->dev = alloc_netdev(sizeof(struct internal_dev), - parms->name, do_setup); + parms->name, NET_NAME_UNKNOWN, + do_setup); if (!netdev_vport->dev) { err = -ENOMEM; goto error_free_vport; diff --git a/net/phonet/pep-gprs.c b/net/phonet/pep-gprs.c index 66dc65e7c6a..e9a83a63718 100644 --- a/net/phonet/pep-gprs.c +++ b/net/phonet/pep-gprs.c @@ -267,7 +267,7 @@ int gprs_attach(struct sock *sk) return -EINVAL; /* need packet boundaries */ /* Create net device */ - dev = alloc_netdev(sizeof(*gp), ifname, gprs_setup); + dev = alloc_netdev(sizeof(*gp), ifname, NET_NAME_UNKNOWN, gprs_setup); if (!dev) return -ENOMEM; gp = netdev_priv(dev); diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c index 8451c8cdc9d..a85c1a086ae 100644 --- a/net/rose/af_rose.c +++ b/net/rose/af_rose.c @@ -1538,7 +1538,7 @@ static int __init rose_proto_init(void) char name[IFNAMSIZ]; sprintf(name, "rose%d", i); - dev = alloc_netdev(0, name, rose_setup); + dev = alloc_netdev(0, name, NET_NAME_UNKNOWN, rose_setup); if (!dev) { printk(KERN_ERR "ROSE: rose_proto_init - unable to allocate memory\n"); rc = -ENOMEM; diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c index 47416716294..bd33793b527 100644 --- a/net/sched/sch_teql.c +++ b/net/sched/sch_teql.c @@ -485,8 +485,8 @@ static int __init teql_init(void) struct net_device *dev; struct teql_master *master; - dev = alloc_netdev(sizeof(struct teql_master), - "teql%d", teql_master_setup); + dev = alloc_netdev(sizeof(struct teql_master), "teql%d", + NET_NAME_UNKNOWN, teql_master_setup); if (!dev) { err = -ENOMEM; break; -- cgit v1.2.3-70-g09d2 From 9374a2b514194acd4865f0183acd7c48c3b36b05 Mon Sep 17 00:00:00 2001 From: Hante Meuleman Date: Wed, 30 Jul 2014 13:20:01 +0200 Subject: brcmfmac: Export brcmf_netif_rx for new protocol msgbuf. Reviewed-by: Arend Van Spriel Reviewed-by: Franky (Zhenhui) Lin Reviewed-by: Pieter-Paul Giesberts Reviewed-by: Daniel (Deognyoun) Kim Signed-off-by: Hante Meuleman Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/dhd.h | 1 + drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h index 7da6441bcfa..1825f736fd4 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h @@ -181,6 +181,7 @@ void brcmf_txflowblock_if(struct brcmf_if *ifp, enum brcmf_netif_stop_reason reason, bool state); void brcmf_txfinalize(struct brcmf_pub *drvr, struct sk_buff *txp, u8 ifidx, bool success); +void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb); /* Sets dongle media info (drv_version, mac address). */ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp); diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index bf448081d6f..7e14e5fa474 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c @@ -288,7 +288,7 @@ void brcmf_txflowblock(struct device *dev, bool state) brcmf_fws_bus_blocked(drvr, state); } -static void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb) +void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb) { skb->dev = ifp->ndev; skb->protocol = eth_type_trans(skb, skb->dev); -- cgit v1.2.3-70-g09d2 From 9e37f045d5e7f33450515f237c2f6f6bfee137dd Mon Sep 17 00:00:00 2001 From: Hante Meuleman Date: Wed, 30 Jul 2014 13:20:04 +0200 Subject: brcmfmac: Adding PCIe bus layer support. This patch will add PCIe support. With this patch the PCIe chipsets 43602, 4354, 4356, 43567, and 43570 will be supported. Reviewed-by: Arend Van Spriel Reviewed-by: Franky (Zhenhui) Lin Reviewed-by: Pieter-Paul Giesberts Reviewed-by: Daniel (Deognyoun) Kim Signed-off-by: Hante Meuleman Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/Kconfig | 10 + drivers/net/wireless/brcm80211/brcmfmac/Makefile | 2 + drivers/net/wireless/brcm80211/brcmfmac/chip.c | 8 + drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h | 1 + drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h | 1 + .../net/wireless/brcm80211/brcmfmac/dhd_linux.c | 7 + drivers/net/wireless/brcm80211/brcmfmac/pcie.c | 1811 ++++++++++++++++++++ drivers/net/wireless/brcm80211/brcmfmac/pcie.h | 29 + .../net/wireless/brcm80211/include/brcm_hw_ids.h | 11 + 9 files changed, 1880 insertions(+) create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/pcie.c create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/pcie.h (limited to 'drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c') diff --git a/drivers/net/wireless/brcm80211/Kconfig b/drivers/net/wireless/brcm80211/Kconfig index fcfed6b99a6..b8e2561ea64 100644 --- a/drivers/net/wireless/brcm80211/Kconfig +++ b/drivers/net/wireless/brcm80211/Kconfig @@ -48,6 +48,16 @@ config BRCMFMAC_USB IEEE802.11n embedded FullMAC WLAN driver. Say Y if you want to use the driver for an USB wireless card. +config BRCMFMAC_PCIE + bool "PCIE bus interface support for FullMAC driver" + depends on BRCMFMAC + depends on PCI + select FW_LOADER + ---help--- + This option enables the PCIE bus interface support for Broadcom + IEEE802.11ac embedded FullMAC WLAN driver. Say Y if you want to + use the driver for an PCIE wireless card. + config BRCM_TRACING bool "Broadcom device tracing" depends on BRCMSMAC || BRCMFMAC diff --git a/drivers/net/wireless/brcm80211/brcmfmac/Makefile b/drivers/net/wireless/brcm80211/brcmfmac/Makefile index 0447a47fe23..c35adf4bc70 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/Makefile +++ b/drivers/net/wireless/brcm80211/brcmfmac/Makefile @@ -45,6 +45,8 @@ brcmfmac-$(CONFIG_BRCMFMAC_SDIO) += \ bcmsdh.o brcmfmac-$(CONFIG_BRCMFMAC_USB) += \ usb.o +brcmfmac-$(CONFIG_BRCMFMAC_PCIE) += \ + pcie.o brcmfmac-$(CONFIG_BRCMDBG) += \ dhd_dbg.o brcmfmac-$(CONFIG_BRCM_TRACING) += \ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/chip.c b/drivers/net/wireless/brcm80211/brcmfmac/chip.c index 96800db0536..95efde868db 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/chip.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.c @@ -506,9 +506,17 @@ static void brcmf_chip_get_raminfo(struct brcmf_chip_priv *ci) break; case BRCM_CC_4339_CHIP_ID: case BRCM_CC_4354_CHIP_ID: + case BRCM_CC_4356_CHIP_ID: + case BRCM_CC_43567_CHIP_ID: + case BRCM_CC_43569_CHIP_ID: + case BRCM_CC_43570_CHIP_ID: ci->pub.ramsize = 0xc0000; ci->pub.rambase = 0x180000; break; + case BRCM_CC_43602_CHIP_ID: + ci->pub.ramsize = 0xf0000; + ci->pub.rambase = 0x180000; + break; default: brcmf_err("unknown chip: %s\n", ci->pub.name); break; diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h index 4053368eb74..3122b86050a 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h @@ -120,6 +120,7 @@ struct brcmf_bus { union { struct brcmf_sdio_dev *sdio; struct brcmf_usbdev *usb; + struct brcmf_pciedev *pcie; } bus_priv; enum brcmf_bus_protocol_type proto_type; struct device *dev; diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h index 6804eeca768..dec40d316c8 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h @@ -36,6 +36,7 @@ #define BRCMF_BCDC_VAL 0x00010000 #define BRCMF_SDIO_VAL 0x00020000 #define BRCMF_MSGBUF_VAL 0x00040000 +#define BRCMF_PCIE_VAL 0x00080000 /* set default print format */ #undef pr_fmt diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index 7e14e5fa474..b456bcb7f91 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c @@ -32,6 +32,7 @@ #include "fwsignal.h" #include "feature.h" #include "proto.h" +#include "pcie.h" MODULE_AUTHOR("Broadcom Corporation"); MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver."); @@ -1084,6 +1085,9 @@ static void brcmf_driver_register(struct work_struct *work) #ifdef CONFIG_BRCMFMAC_USB brcmf_usb_register(); #endif +#ifdef CONFIG_BRCMFMAC_PCIE + brcmf_pcie_register(); +#endif } static DECLARE_WORK(brcmf_driver_work, brcmf_driver_register); @@ -1108,6 +1112,9 @@ static void __exit brcmfmac_module_exit(void) #endif #ifdef CONFIG_BRCMFMAC_USB brcmf_usb_exit(); +#endif +#ifdef CONFIG_BRCMFMAC_PCIE + brcmf_pcie_exit(); #endif brcmf_debugfs_exit(); } diff --git a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c new file mode 100644 index 00000000000..89be96d3b6e --- /dev/null +++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c @@ -0,0 +1,1811 @@ +/* Copyright (c) 2014 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "dhd_dbg.h" +#include "dhd_bus.h" +#include "commonring.h" +#include "msgbuf.h" +#include "pcie.h" +#include "firmware.h" +#include "chip.h" + + +enum brcmf_pcie_state { + BRCMFMAC_PCIE_STATE_DOWN, + BRCMFMAC_PCIE_STATE_UP +}; + + +#define BRCMF_PCIE_43602_FW_NAME "brcm/brcmfmac43602-pcie.bin" +#define BRCMF_PCIE_43602_NVRAM_NAME "brcm/brcmfmac43602-pcie.txt" +#define BRCMF_PCIE_4354_FW_NAME "brcm/brcmfmac4354-pcie.bin" +#define BRCMF_PCIE_4354_NVRAM_NAME "brcm/brcmfmac4354-pcie.txt" +#define BRCMF_PCIE_4356_FW_NAME "brcm/brcmfmac4356-pcie.bin" +#define BRCMF_PCIE_4356_NVRAM_NAME "brcm/brcmfmac4356-pcie.txt" +#define BRCMF_PCIE_43570_FW_NAME "brcm/brcmfmac43570-pcie.bin" +#define BRCMF_PCIE_43570_NVRAM_NAME "brcm/brcmfmac43570-pcie.txt" + +#define BRCMF_PCIE_FW_UP_TIMEOUT 2000 /* msec */ + +#define BRCMF_PCIE_TCM_MAP_SIZE (4096 * 1024) +#define BRCMF_PCIE_REG_MAP_SIZE (32 * 1024) + +/* backplane addres space accessed by BAR0 */ +#define BRCMF_PCIE_BAR0_WINDOW 0x80 +#define BRCMF_PCIE_BAR0_REG_SIZE 0x1000 +#define BRCMF_PCIE_BAR0_WRAPPERBASE 0x70 + +#define BRCMF_PCIE_BAR0_WRAPBASE_DMP_OFFSET 0x1000 +#define BRCMF_PCIE_BARO_PCIE_ENUM_OFFSET 0x2000 + +#define BRCMF_PCIE_ARMCR4REG_BANKIDX 0x40 +#define BRCMF_PCIE_ARMCR4REG_BANKPDA 0x4C + +#define BRCMF_PCIE_REG_INTSTATUS 0x90 +#define BRCMF_PCIE_REG_INTMASK 0x94 +#define BRCMF_PCIE_REG_SBMBX 0x98 + +#define BRCMF_PCIE_PCIE2REG_INTMASK 0x24 +#define BRCMF_PCIE_PCIE2REG_MAILBOXINT 0x48 +#define BRCMF_PCIE_PCIE2REG_MAILBOXMASK 0x4C +#define BRCMF_PCIE_PCIE2REG_CONFIGADDR 0x120 +#define BRCMF_PCIE_PCIE2REG_CONFIGDATA 0x124 +#define BRCMF_PCIE_PCIE2REG_H2D_MAILBOX 0x140 + +#define BRCMF_PCIE_GENREV1 1 +#define BRCMF_PCIE_GENREV2 2 + +#define BRCMF_PCIE2_INTA 0x01 +#define BRCMF_PCIE2_INTB 0x02 + +#define BRCMF_PCIE_INT_0 0x01 +#define BRCMF_PCIE_INT_1 0x02 +#define BRCMF_PCIE_INT_DEF (BRCMF_PCIE_INT_0 | \ + BRCMF_PCIE_INT_1) + +#define BRCMF_PCIE_MB_INT_FN0_0 0x0100 +#define BRCMF_PCIE_MB_INT_FN0_1 0x0200 +#define BRCMF_PCIE_MB_INT_D2H0_DB0 0x10000 +#define BRCMF_PCIE_MB_INT_D2H0_DB1 0x20000 +#define BRCMF_PCIE_MB_INT_D2H1_DB0 0x40000 +#define BRCMF_PCIE_MB_INT_D2H1_DB1 0x80000 +#define BRCMF_PCIE_MB_INT_D2H2_DB0 0x100000 +#define BRCMF_PCIE_MB_INT_D2H2_DB1 0x200000 +#define BRCMF_PCIE_MB_INT_D2H3_DB0 0x400000 +#define BRCMF_PCIE_MB_INT_D2H3_DB1 0x800000 + +#define BRCMF_PCIE_MB_INT_D2H_DB (BRCMF_PCIE_MB_INT_D2H0_DB0 | \ + BRCMF_PCIE_MB_INT_D2H0_DB1 | \ + BRCMF_PCIE_MB_INT_D2H1_DB0 | \ + BRCMF_PCIE_MB_INT_D2H1_DB1 | \ + BRCMF_PCIE_MB_INT_D2H2_DB0 | \ + BRCMF_PCIE_MB_INT_D2H2_DB1 | \ + BRCMF_PCIE_MB_INT_D2H3_DB0 | \ + BRCMF_PCIE_MB_INT_D2H3_DB1) + +#define BRCMF_PCIE_MIN_SHARED_VERSION 4 +#define BRCMF_PCIE_MAX_SHARED_VERSION 5 +#define BRCMF_PCIE_SHARED_VERSION_MASK 0x00FF +#define BRCMF_PCIE_SHARED_TXPUSH_SUPPORT 0x4000 + +#define BRCMF_PCIE_FLAGS_HTOD_SPLIT 0x4000 +#define BRCMF_PCIE_FLAGS_DTOH_SPLIT 0x8000 + +#define BRCMF_SHARED_MAX_RXBUFPOST_OFFSET 34 +#define BRCMF_SHARED_RING_BASE_OFFSET 52 +#define BRCMF_SHARED_RX_DATAOFFSET_OFFSET 36 +#define BRCMF_SHARED_CONSOLE_ADDR_OFFSET 20 +#define BRCMF_SHARED_HTOD_MB_DATA_ADDR_OFFSET 40 +#define BRCMF_SHARED_DTOH_MB_DATA_ADDR_OFFSET 44 +#define BRCMF_SHARED_RING_INFO_ADDR_OFFSET 48 +#define BRCMF_SHARED_DMA_SCRATCH_LEN_OFFSET 52 +#define BRCMF_SHARED_DMA_SCRATCH_ADDR_OFFSET 56 +#define BRCMF_SHARED_DMA_RINGUPD_LEN_OFFSET 64 +#define BRCMF_SHARED_DMA_RINGUPD_ADDR_OFFSET 68 + +#define BRCMF_RING_H2D_RING_COUNT_OFFSET 0 +#define BRCMF_RING_D2H_RING_COUNT_OFFSET 1 +#define BRCMF_RING_H2D_RING_MEM_OFFSET 4 +#define BRCMF_RING_H2D_RING_STATE_OFFSET 8 + +#define BRCMF_RING_MEM_BASE_ADDR_OFFSET 8 +#define BRCMF_RING_MAX_ITEM_OFFSET 4 +#define BRCMF_RING_LEN_ITEMS_OFFSET 6 +#define BRCMF_RING_MEM_SZ 16 +#define BRCMF_RING_STATE_SZ 8 + +#define BRCMF_SHARED_RING_H2D_W_IDX_PTR_OFFSET 4 +#define BRCMF_SHARED_RING_H2D_R_IDX_PTR_OFFSET 8 +#define BRCMF_SHARED_RING_D2H_W_IDX_PTR_OFFSET 12 +#define BRCMF_SHARED_RING_D2H_R_IDX_PTR_OFFSET 16 +#define BRCMF_SHARED_RING_TCM_MEMLOC_OFFSET 0 +#define BRCMF_SHARED_RING_MAX_SUB_QUEUES 52 + +#define BRCMF_DEF_MAX_RXBUFPOST 255 + +#define BRCMF_CONSOLE_BUFADDR_OFFSET 8 +#define BRCMF_CONSOLE_BUFSIZE_OFFSET 12 +#define BRCMF_CONSOLE_WRITEIDX_OFFSET 16 + +#define BRCMF_DMA_D2H_SCRATCH_BUF_LEN 8 +#define BRCMF_DMA_D2H_RINGUPD_BUF_LEN 1024 + +#define BRCMF_D2H_DEV_D3_ACK 0x00000001 +#define BRCMF_D2H_DEV_DS_ENTER_REQ 0x00000002 +#define BRCMF_D2H_DEV_DS_EXIT_NOTE 0x00000004 + +#define BRCMF_H2D_HOST_D3_INFORM 0x00000001 +#define BRCMF_H2D_HOST_DS_ACK 0x00000002 + +#define BRCMF_PCIE_MBDATA_TIMEOUT 2000 + + +MODULE_FIRMWARE(BRCMF_PCIE_43602_FW_NAME); +MODULE_FIRMWARE(BRCMF_PCIE_43602_NVRAM_NAME); +MODULE_FIRMWARE(BRCMF_PCIE_4354_FW_NAME); +MODULE_FIRMWARE(BRCMF_PCIE_4354_NVRAM_NAME); +MODULE_FIRMWARE(BRCMF_PCIE_43570_FW_NAME); +MODULE_FIRMWARE(BRCMF_PCIE_43570_NVRAM_NAME); + + +struct brcmf_pcie_console { + u32 base_addr; + u32 buf_addr; + u32 bufsize; + u32 read_idx; + u8 log_str[256]; + u8 log_idx; +}; + +struct brcmf_pcie_shared_info { + u32 tcm_base_address; + u32 flags; + struct brcmf_pcie_ringbuf *commonrings[BRCMF_NROF_COMMON_MSGRINGS]; + struct brcmf_pcie_ringbuf *flowrings; + u16 max_rxbufpost; + u32 nrof_flowrings; + u32 rx_dataoffset; + u32 htod_mb_data_addr; + u32 dtoh_mb_data_addr; + u32 ring_info_addr; + struct brcmf_pcie_console console; + void *scratch; + dma_addr_t scratch_dmahandle; + void *ringupd; + dma_addr_t ringupd_dmahandle; +}; + +struct brcmf_pcie_core_info { + u32 base; + u32 wrapbase; +}; + +struct brcmf_pciedev_info { + enum brcmf_pcie_state state; + bool in_irq; + bool irq_requested; + struct pci_dev *pdev; + char fw_name[BRCMF_FW_PATH_LEN + BRCMF_FW_NAME_LEN]; + char nvram_name[BRCMF_FW_PATH_LEN + BRCMF_FW_NAME_LEN]; + void __iomem *regs; + void __iomem *tcm; + u32 tcm_size; + u32 ram_base; + u32 ram_size; + struct brcmf_chip *ci; + u32 coreid; + u32 generic_corerev; + struct brcmf_pcie_shared_info shared; + void (*ringbell)(struct brcmf_pciedev_info *devinfo); + wait_queue_head_t mbdata_resp_wait; + bool mbdata_completed; + bool irq_allocated; +}; + +struct brcmf_pcie_ringbuf { + struct brcmf_commonring commonring; + dma_addr_t dma_handle; + u32 w_idx_addr; + u32 r_idx_addr; + struct brcmf_pciedev_info *devinfo; + u8 id; +}; + + +static const u32 brcmf_ring_max_item[BRCMF_NROF_COMMON_MSGRINGS] = { + BRCMF_H2D_MSGRING_CONTROL_SUBMIT_MAX_ITEM, + BRCMF_H2D_MSGRING_RXPOST_SUBMIT_MAX_ITEM, + BRCMF_D2H_MSGRING_CONTROL_COMPLETE_MAX_ITEM, + BRCMF_D2H_MSGRING_TX_COMPLETE_MAX_ITEM, + BRCMF_D2H_MSGRING_RX_COMPLETE_MAX_ITEM +}; + +static const u32 brcmf_ring_itemsize[BRCMF_NROF_COMMON_MSGRINGS] = { + BRCMF_H2D_MSGRING_CONTROL_SUBMIT_ITEMSIZE, + BRCMF_H2D_MSGRING_RXPOST_SUBMIT_ITEMSIZE, + BRCMF_D2H_MSGRING_CONTROL_COMPLETE_ITEMSIZE, + BRCMF_D2H_MSGRING_TX_COMPLETE_ITEMSIZE, + BRCMF_D2H_MSGRING_RX_COMPLETE_ITEMSIZE +}; + + +/* dma flushing needs implementation for mips and arm platforms. Should + * be put in util. Note, this is not real flushing. It is virtual non + * cached memory. Only write buffers should have to be drained. Though + * this may be different depending on platform...... + */ +#define brcmf_dma_flush(addr, len) +#define brcmf_dma_invalidate_cache(addr, len) + + +static u32 +brcmf_pcie_read_reg32(struct brcmf_pciedev_info *devinfo, u32 reg_offset) +{ + void __iomem *address = devinfo->regs + reg_offset; + + return (ioread32(address)); +} + + +static void +brcmf_pcie_write_reg32(struct brcmf_pciedev_info *devinfo, u32 reg_offset, + u32 value) +{ + void __iomem *address = devinfo->regs + reg_offset; + + iowrite32(value, address); +} + + +static u8 +brcmf_pcie_read_tcm8(struct brcmf_pciedev_info *devinfo, u32 mem_offset) +{ + void __iomem *address = devinfo->tcm + mem_offset; + + return (ioread8(address)); +} + + +static u16 +brcmf_pcie_read_tcm16(struct brcmf_pciedev_info *devinfo, u32 mem_offset) +{ + void __iomem *address = devinfo->tcm + mem_offset; + + return (ioread16(address)); +} + + +static void +brcmf_pcie_write_tcm16(struct brcmf_pciedev_info *devinfo, u32 mem_offset, + u16 value) +{ + void __iomem *address = devinfo->tcm + mem_offset; + + iowrite16(value, address); +} + + +static u32 +brcmf_pcie_read_tcm32(struct brcmf_pciedev_info *devinfo, u32 mem_offset) +{ + void __iomem *address = devinfo->tcm + mem_offset; + + return (ioread32(address)); +} + + +static void +brcmf_pcie_write_tcm32(struct brcmf_pciedev_info *devinfo, u32 mem_offset, + u32 value) +{ + void __iomem *address = devinfo->tcm + mem_offset; + + iowrite32(value, address); +} + + +static u32 +brcmf_pcie_read_ram32(struct brcmf_pciedev_info *devinfo, u32 mem_offset) +{ + void __iomem *addr = devinfo->tcm + devinfo->ci->rambase + mem_offset; + + return (ioread32(addr)); +} + + +static void +brcmf_pcie_write_ram32(struct brcmf_pciedev_info *devinfo, u32 mem_offset, + u32 value) +{ + void __iomem *addr = devinfo->tcm + devinfo->ci->rambase + mem_offset; + + iowrite32(value, addr); +} + + +static void +brcmf_pcie_copy_mem_todev(struct brcmf_pciedev_info *devinfo, u32 mem_offset, + void *srcaddr, u32 len) +{ + void __iomem *address = devinfo->tcm + mem_offset; + __le32 *src32; + __le16 *src16; + u8 *src8; + + if (((ulong)address & 4) || ((ulong)srcaddr & 4) || (len & 4)) { + if (((ulong)address & 2) || ((ulong)srcaddr & 2) || (len & 2)) { + src8 = (u8 *)srcaddr; + while (len) { + iowrite8(*src8, address); + address++; + src8++; + len--; + } + } else { + len = len / 2; + src16 = (__le16 *)srcaddr; + while (len) { + iowrite16(le16_to_cpu(*src16), address); + address += 2; + src16++; + len--; + } + } + } else { + len = len / 4; + src32 = (__le32 *)srcaddr; + while (len) { + iowrite32(le32_to_cpu(*src32), address); + address += 4; + src32++; + len--; + } + } +} + + +#define WRITECC32(devinfo, reg, value) brcmf_pcie_write_reg32(devinfo, \ + CHIPCREGOFFS(reg), value) + + +static void +brcmf_pcie_select_core(struct brcmf_pciedev_info *devinfo, u16 coreid) +{ + const struct pci_dev *pdev = devinfo->pdev; + struct brcmf_core *core; + u32 bar0_win; + + core = brcmf_chip_get_core(devinfo->ci, coreid); + if (core) { + bar0_win = core->base; + pci_write_config_dword(pdev, BRCMF_PCIE_BAR0_WINDOW, bar0_win); + if (pci_read_config_dword(pdev, BRCMF_PCIE_BAR0_WINDOW, + &bar0_win) == 0) { + if (bar0_win != core->base) { + bar0_win = core->base; + pci_write_config_dword(pdev, + BRCMF_PCIE_BAR0_WINDOW, + bar0_win); + } + } + } else { + brcmf_err("Unsupported core selected %x\n", coreid); + } +} + + +static void brcmf_pcie_detach(struct brcmf_pciedev_info *devinfo) +{ + u16 cfg_offset[] = { 0x4, 0x4C, 0x58, 0x5C, 0x60, 0x64, 0xDC, 0x228, + 0x248, 0x4e0, 0x4f4 }; + u32 i; + u32 val; + + if (!devinfo->ci) + return; + + brcmf_pcie_select_core(devinfo, BCMA_CORE_CHIPCOMMON); + WRITECC32(devinfo, watchdog, 0x4e0); + + msleep(100); + + brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2); + for (i = 0; i < ARRAY_SIZE(cfg_offset); i++) { + brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_CONFIGADDR, + cfg_offset[i]); + val = brcmf_pcie_read_reg32(devinfo, + BRCMF_PCIE_PCIE2REG_CONFIGDATA); + brcmf_dbg(PCIE, "config offset 0x%04x, value 0x%04x\n", + cfg_offset[i], val); + brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_CONFIGDATA, + val); + } +} + + +static void brcmf_pcie_attach(struct brcmf_pciedev_info *devinfo) +{ + u32 config; + + brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2); + if (brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_INTMASK) != 0) + brcmf_pcie_detach(devinfo); + /* BAR1 window may not be sized properly */ + brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2); + brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_CONFIGADDR, 0x4e0); + config = brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_CONFIGDATA); + brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_CONFIGDATA, config); + + device_wakeup_enable(&devinfo->pdev->dev); +} + + +static int brcmf_pcie_enter_download_state(struct brcmf_pciedev_info *devinfo) +{ + brcmf_chip_enter_download(devinfo->ci); + + if (devinfo->ci->chip == BRCM_CC_43602_CHIP_ID) { + brcmf_pcie_select_core(devinfo, BCMA_CORE_ARM_CR4); + brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_ARMCR4REG_BANKIDX, + 5); + brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_ARMCR4REG_BANKPDA, + 0); + brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_ARMCR4REG_BANKIDX, + 7); + brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_ARMCR4REG_BANKPDA, + 0); + } + return 0; +} + + +static int brcmf_pcie_exit_download_state(struct brcmf_pciedev_info *devinfo, + u32 resetintr) +{ + struct brcmf_core *core; + + if (devinfo->ci->chip == BRCM_CC_43602_CHIP_ID) { + core = brcmf_chip_get_core(devinfo->ci, BCMA_CORE_INTERNAL_MEM); + brcmf_chip_resetcore(core, 0, 0, 0); + } + + return !brcmf_chip_exit_download(devinfo->ci, resetintr); +} + + +static void +brcmf_pcie_send_mb_data(struct brcmf_pciedev_info *devinfo, u32 htod_mb_data) +{ + struct brcmf_pcie_shared_info *shared; + u32 addr; + u32 cur_htod_mb_data; + u32 i; + + shared = &devinfo->shared; + addr = shared->htod_mb_data_addr; + cur_htod_mb_data = brcmf_pcie_read_tcm32(devinfo, addr); + + if (cur_htod_mb_data != 0) + brcmf_dbg(PCIE, "MB transaction is already pending 0x%04x\n", + cur_htod_mb_data); + + i = 0; + while (cur_htod_mb_data != 0) { + msleep(10); + i++; + if (i > 100) + break; + cur_htod_mb_data = brcmf_pcie_read_tcm32(devinfo, addr); + } + + brcmf_pcie_write_tcm32(devinfo, addr, htod_mb_data); + pci_write_config_dword(devinfo->pdev, BRCMF_PCIE_REG_SBMBX, 1); + pci_write_config_dword(devinfo->pdev, BRCMF_PCIE_REG_SBMBX, 1); +} + + +static void brcmf_pcie_handle_mb_data(struct brcmf_pciedev_info *devinfo) +{ + struct brcmf_pcie_shared_info *shared; + u32 addr; + u32 dtoh_mb_data; + + shared = &devinfo->shared; + addr = shared->dtoh_mb_data_addr; + dtoh_mb_data = brcmf_pcie_read_tcm32(devinfo, addr); + + if (!dtoh_mb_data) + return; + + brcmf_pcie_write_tcm32(devinfo, addr, 0); + + brcmf_dbg(PCIE, "D2H_MB_DATA: 0x%04x\n", dtoh_mb_data); + if (dtoh_mb_data & BRCMF_D2H_DEV_DS_ENTER_REQ) { + brcmf_dbg(PCIE, "D2H_MB_DATA: DEEP SLEEP REQ\n"); + brcmf_pcie_send_mb_data(devinfo, BRCMF_H2D_HOST_DS_ACK); + brcmf_dbg(PCIE, "D2H_MB_DATA: sent DEEP SLEEP ACK\n"); + } + if (dtoh_mb_data & BRCMF_D2H_DEV_DS_EXIT_NOTE) + brcmf_dbg(PCIE, "D2H_MB_DATA: DEEP SLEEP EXIT\n"); + if (dtoh_mb_data & BRCMF_D2H_DEV_D3_ACK) + brcmf_dbg(PCIE, "D2H_MB_DATA: D3 ACK\n"); + if (waitqueue_active(&devinfo->mbdata_resp_wait)) { + devinfo->mbdata_completed = true; + wake_up(&devinfo->mbdata_resp_wait); + } +} + + +static void brcmf_pcie_bus_console_init(struct brcmf_pciedev_info *devinfo) +{ + struct brcmf_pcie_shared_info *shared; + struct brcmf_pcie_console *console; + u32 addr; + + shared = &devinfo->shared; + console = &shared->console; + addr = shared->tcm_base_address + BRCMF_SHARED_CONSOLE_ADDR_OFFSET; + console->base_addr = brcmf_pcie_read_tcm32(devinfo, addr); + + addr = console->base_addr + BRCMF_CONSOLE_BUFADDR_OFFSET; + console->buf_addr = brcmf_pcie_read_tcm32(devinfo, addr); + addr = console->base_addr + BRCMF_CONSOLE_BUFSIZE_OFFSET; + console->bufsize = brcmf_pcie_read_tcm32(devinfo, addr); + + brcmf_dbg(PCIE, "Console: base %x, buf %x, size %d\n", + console->base_addr, console->buf_addr, console->bufsize); +} + + +static void brcmf_pcie_bus_console_read(struct brcmf_pciedev_info *devinfo) +{ + struct brcmf_pcie_console *console; + u32 addr; + u8 ch; + u32 newidx; + + console = &devinfo->shared.console; + addr = console->base_addr + BRCMF_CONSOLE_WRITEIDX_OFFSET; + newidx = brcmf_pcie_read_tcm32(devinfo, addr); + while (newidx != console->read_idx) { + addr = console->buf_addr + console->read_idx; + ch = brcmf_pcie_read_tcm8(devinfo, addr); + console->read_idx++; + if (console->read_idx == console->bufsize) + console->read_idx = 0; + if (ch == '\r') + continue; + console->log_str[console->log_idx] = ch; + console->log_idx++; + if ((ch != '\n') && + (console->log_idx == (sizeof(console->log_str) - 2))) { + ch = '\n'; + console->log_str[console->log_idx] = ch; + console->log_idx++; + } + + if (ch == '\n') { + console->log_str[console->log_idx] = 0; + brcmf_dbg(PCIE, "CONSOLE: %s\n", console->log_str); + console->log_idx = 0; + } + } +} + + +static __used void brcmf_pcie_ringbell_v1(struct brcmf_pciedev_info *devinfo) +{ + u32 reg_value; + + brcmf_dbg(PCIE, "RING !\n"); + reg_value = brcmf_pcie_read_reg32(devinfo, + BRCMF_PCIE_PCIE2REG_MAILBOXINT); + reg_value |= BRCMF_PCIE2_INTB; + brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT, + reg_value); +} + + +static void brcmf_pcie_ringbell_v2(struct brcmf_pciedev_info *devinfo) +{ + brcmf_dbg(PCIE, "RING !\n"); + /* Any arbitrary value will do, lets use 1 */ + brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_H2D_MAILBOX, 1); +} + + +static void brcmf_pcie_intr_disable(struct brcmf_pciedev_info *devinfo) +{ + if (devinfo->generic_corerev == BRCMF_PCIE_GENREV1) + pci_write_config_dword(devinfo->pdev, BRCMF_PCIE_REG_INTMASK, + 0); + else + brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXMASK, + 0); +} + + +static void brcmf_pcie_intr_enable(struct brcmf_pciedev_info *devinfo) +{ + if (devinfo->generic_corerev == BRCMF_PCIE_GENREV1) + pci_write_config_dword(devinfo->pdev, BRCMF_PCIE_REG_INTMASK, + BRCMF_PCIE_INT_DEF); + else + brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXMASK, + BRCMF_PCIE_MB_INT_D2H_DB | + BRCMF_PCIE_MB_INT_FN0_0 | + BRCMF_PCIE_MB_INT_FN0_1); +} + + +static irqreturn_t brcmf_pcie_quick_check_isr_v1(int irq, void *arg) +{ + struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)arg; + u32 status; + + status = 0; + pci_read_config_dword(devinfo->pdev, BRCMF_PCIE_REG_INTSTATUS, &status); + if (status) { + brcmf_pcie_intr_disable(devinfo); + brcmf_dbg(PCIE, "Enter\n"); + return IRQ_WAKE_THREAD; + } + return IRQ_NONE; +} + + +static irqreturn_t brcmf_pcie_quick_check_isr_v2(int irq, void *arg) +{ + struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)arg; + + if (brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT)) { + brcmf_pcie_intr_disable(devinfo); + brcmf_dbg(PCIE, "Enter\n"); + return IRQ_WAKE_THREAD; + } + return IRQ_NONE; +} + + +static irqreturn_t brcmf_pcie_isr_thread_v1(int irq, void *arg) +{ + struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)arg; + const struct pci_dev *pdev = devinfo->pdev; + u32 status; + + devinfo->in_irq = true; + status = 0; + pci_read_config_dword(pdev, BRCMF_PCIE_REG_INTSTATUS, &status); + brcmf_dbg(PCIE, "Enter %x\n", status); + if (status) { + pci_write_config_dword(pdev, BRCMF_PCIE_REG_INTSTATUS, status); + if (devinfo->state == BRCMFMAC_PCIE_STATE_UP) + brcmf_proto_msgbuf_rx_trigger(&devinfo->pdev->dev); + } + if (devinfo->state == BRCMFMAC_PCIE_STATE_UP) + brcmf_pcie_intr_enable(devinfo); + devinfo->in_irq = false; + return IRQ_HANDLED; +} + + +static irqreturn_t brcmf_pcie_isr_thread_v2(int irq, void *arg) +{ + struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)arg; + u32 status; + + devinfo->in_irq = true; + status = brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT); + brcmf_dbg(PCIE, "Enter %x\n", status); + if (status) { + brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT, + status); + if (status & (BRCMF_PCIE_MB_INT_FN0_0 | + BRCMF_PCIE_MB_INT_FN0_1)) + brcmf_pcie_handle_mb_data(devinfo); + if (status & BRCMF_PCIE_MB_INT_D2H_DB) { + if (devinfo->state == BRCMFMAC_PCIE_STATE_UP) + brcmf_proto_msgbuf_rx_trigger( + &devinfo->pdev->dev); + } + } + brcmf_pcie_bus_console_read(devinfo); + if (devinfo->state == BRCMFMAC_PCIE_STATE_UP) + brcmf_pcie_intr_enable(devinfo); + devinfo->in_irq = false; + return IRQ_HANDLED; +} + + +static int brcmf_pcie_request_irq(struct brcmf_pciedev_info *devinfo) +{ + struct pci_dev *pdev; + + pdev = devinfo->pdev; + + brcmf_pcie_intr_disable(devinfo); + + brcmf_dbg(PCIE, "Enter\n"); + /* is it a v1 or v2 implementation */ + devinfo->irq_requested = false; + if (devinfo->generic_corerev == BRCMF_PCIE_GENREV1) { + if (request_threaded_irq(pdev->irq, + brcmf_pcie_quick_check_isr_v1, + brcmf_pcie_isr_thread_v1, + IRQF_SHARED, "brcmf_pcie_intr", + devinfo)) { + brcmf_err("Failed to request IRQ %d\n", pdev->irq); + return -EIO; + } + } else { + if (request_threaded_irq(pdev->irq, + brcmf_pcie_quick_check_isr_v2, + brcmf_pcie_isr_thread_v2, + IRQF_SHARED, "brcmf_pcie_intr", + devinfo)) { + brcmf_err("Failed to request IRQ %d\n", pdev->irq); + return -EIO; + } + } + devinfo->irq_requested = true; + devinfo->irq_allocated = true; + return 0; +} + + +static void brcmf_pcie_release_irq(struct brcmf_pciedev_info *devinfo) +{ + struct pci_dev *pdev; + u32 status; + u32 count; + + if (!devinfo->irq_allocated) + return; + + pdev = devinfo->pdev; + + brcmf_pcie_intr_disable(devinfo); + if (!devinfo->irq_requested) + return; + devinfo->irq_requested = false; + free_irq(pdev->irq, devinfo); + + msleep(50); + count = 0; + while ((devinfo->in_irq) && (count < 20)) { + msleep(50); + count++; + } + if (devinfo->in_irq) + brcmf_err("Still in IRQ (processing) !!!\n"); + + if (devinfo->generic_corerev == BRCMF_PCIE_GENREV1) { + status = 0; + pci_read_config_dword(pdev, BRCMF_PCIE_REG_INTSTATUS, &status); + pci_write_config_dword(pdev, BRCMF_PCIE_REG_INTSTATUS, status); + } else { + status = brcmf_pcie_read_reg32(devinfo, + BRCMF_PCIE_PCIE2REG_MAILBOXINT); + brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT, + status); + } + devinfo->irq_allocated = false; +} + + +static int brcmf_pcie_ring_mb_write_rptr(void *ctx) +{ + struct brcmf_pcie_ringbuf *ring = (struct brcmf_pcie_ringbuf *)ctx; + struct brcmf_pciedev_info *devinfo = ring->devinfo; + struct brcmf_commonring *commonring = &ring->commonring; + + if (devinfo->state != BRCMFMAC_PCIE_STATE_UP) + return -EIO; + + brcmf_dbg(PCIE, "W r_ptr %d (%d), ring %d\n", commonring->r_ptr, + commonring->w_ptr, ring->id); + + brcmf_pcie_write_tcm16(devinfo, ring->r_idx_addr, commonring->r_ptr); + + return 0; +} + + +static int brcmf_pcie_ring_mb_write_wptr(void *ctx) +{ + struct brcmf_pcie_ringbuf *ring = (struct brcmf_pcie_ringbuf *)ctx; + struct brcmf_pciedev_info *devinfo = ring->devinfo; + struct brcmf_commonring *commonring = &ring->commonring; + + if (devinfo->state != BRCMFMAC_PCIE_STATE_UP) + return -EIO; + + brcmf_dbg(PCIE, "W w_ptr %d (%d), ring %d\n", commonring->w_ptr, + commonring->r_ptr, ring->id); + + brcmf_pcie_write_tcm16(devinfo, ring->w_idx_addr, commonring->w_ptr); + + return 0; +} + + +static int brcmf_pcie_ring_mb_ring_bell(void *ctx) +{ + struct brcmf_pcie_ringbuf *ring = (struct brcmf_pcie_ringbuf *)ctx; + struct brcmf_pciedev_info *devinfo = ring->devinfo; + + if (devinfo->state != BRCMFMAC_PCIE_STATE_UP) + return -EIO; + + devinfo->ringbell(devinfo); + + return 0; +} + + +static int brcmf_pcie_ring_mb_update_rptr(void *ctx) +{ + struct brcmf_pcie_ringbuf *ring = (struct brcmf_pcie_ringbuf *)ctx; + struct brcmf_pciedev_info *devinfo = ring->devinfo; + struct brcmf_commonring *commonring = &ring->commonring; + + if (devinfo->state != BRCMFMAC_PCIE_STATE_UP) + return -EIO; + + commonring->r_ptr = brcmf_pcie_read_tcm16(devinfo, ring->r_idx_addr); + + brcmf_dbg(PCIE, "R r_ptr %d (%d), ring %d\n", commonring->r_ptr, + commonring->w_ptr, ring->id); + + return 0; +} + + +static int brcmf_pcie_ring_mb_update_wptr(void *ctx) +{ + struct brcmf_pcie_ringbuf *ring = (struct brcmf_pcie_ringbuf *)ctx; + struct brcmf_pciedev_info *devinfo = ring->devinfo; + struct brcmf_commonring *commonring = &ring->commonring; + + if (devinfo->state != BRCMFMAC_PCIE_STATE_UP) + return -EIO; + + commonring->w_ptr = brcmf_pcie_read_tcm16(devinfo, ring->w_idx_addr); + + brcmf_dbg(PCIE, "R w_ptr %d (%d), ring %d\n", commonring->w_ptr, + commonring->r_ptr, ring->id); + + return 0; +} + + +static void * +brcmf_pcie_init_dmabuffer_for_device(struct brcmf_pciedev_info *devinfo, + u32 size, u32 tcm_dma_phys_addr, + dma_addr_t *dma_handle) +{ + void *ring; + long long address; + + ring = dma_alloc_coherent(&devinfo->pdev->dev, size, dma_handle, + GFP_KERNEL); + if (!ring) + return NULL; + + address = (long long)(long)*dma_handle; + brcmf_pcie_write_tcm32(devinfo, tcm_dma_phys_addr, + address & 0xffffffff); + brcmf_pcie_write_tcm32(devinfo, tcm_dma_phys_addr + 4, address >> 32); + + memset(ring, 0, size); + + return (ring); +} + + +static struct brcmf_pcie_ringbuf * +brcmf_pcie_alloc_dma_and_ring(struct brcmf_pciedev_info *devinfo, u32 ring_id, + u32 tcm_ring_phys_addr) +{ + void *dma_buf; + dma_addr_t dma_handle; + struct brcmf_pcie_ringbuf *ring; + u32 size; + u32 addr; + + size = brcmf_ring_max_item[ring_id] * brcmf_ring_itemsize[ring_id]; + dma_buf = brcmf_pcie_init_dmabuffer_for_device(devinfo, size, + tcm_ring_phys_addr + BRCMF_RING_MEM_BASE_ADDR_OFFSET, + &dma_handle); + if (!dma_buf) + return NULL; + + addr = tcm_ring_phys_addr + BRCMF_RING_MAX_ITEM_OFFSET; + brcmf_pcie_write_tcm16(devinfo, addr, brcmf_ring_max_item[ring_id]); + addr = tcm_ring_phys_addr + BRCMF_RING_LEN_ITEMS_OFFSET; + brcmf_pcie_write_tcm16(devinfo, addr, brcmf_ring_itemsize[ring_id]); + + ring = kzalloc(sizeof(*ring), GFP_KERNEL); + if (!ring) { + dma_free_coherent(&devinfo->pdev->dev, size, dma_buf, + dma_handle); + return NULL; + } + brcmf_commonring_config(&ring->commonring, brcmf_ring_max_item[ring_id], + brcmf_ring_itemsize[ring_id], dma_buf); + ring->dma_handle = dma_handle; + ring->devinfo = devinfo; + brcmf_commonring_register_cb(&ring->commonring, + brcmf_pcie_ring_mb_ring_bell, + brcmf_pcie_ring_mb_update_rptr, + brcmf_pcie_ring_mb_update_wptr, + brcmf_pcie_ring_mb_write_rptr, + brcmf_pcie_ring_mb_write_wptr, ring); + + return (ring); +} + + +static void brcmf_pcie_release_ringbuffer(struct device *dev, + struct brcmf_pcie_ringbuf *ring) +{ + void *dma_buf; + u32 size; + + if (!ring) + return; + + dma_buf = ring->commonring.buf_addr; + if (dma_buf) { + size = ring->commonring.depth * ring->commonring.item_len; + dma_free_coherent(dev, size, dma_buf, ring->dma_handle); + } + kfree(ring); +} + + +static void brcmf_pcie_release_ringbuffers(struct brcmf_pciedev_info *devinfo) +{ + u32 i; + + for (i = 0; i < BRCMF_NROF_COMMON_MSGRINGS; i++) { + brcmf_pcie_release_ringbuffer(&devinfo->pdev->dev, + devinfo->shared.commonrings[i]); + devinfo->shared.commonrings[i] = NULL; + } + kfree(devinfo->shared.flowrings); + devinfo->shared.flowrings = NULL; +} + + +static int brcmf_pcie_init_ringbuffers(struct brcmf_pciedev_info *devinfo) +{ + struct brcmf_pcie_ringbuf *ring; + struct brcmf_pcie_ringbuf *rings; + u32 ring_addr; + u32 d2h_w_idx_ptr; + u32 d2h_r_idx_ptr; + u32 h2d_w_idx_ptr; + u32 h2d_r_idx_ptr; + u32 addr; + u32 ring_mem_ptr; + u32 i; + u16 max_sub_queues; + + ring_addr = devinfo->shared.ring_info_addr; + brcmf_dbg(PCIE, "Base ring addr = 0x%08x\n", ring_addr); + + addr = ring_addr + BRCMF_SHARED_RING_D2H_W_IDX_PTR_OFFSET; + d2h_w_idx_ptr = brcmf_pcie_read_tcm32(devinfo, addr); + addr = ring_addr + BRCMF_SHARED_RING_D2H_R_IDX_PTR_OFFSET; + d2h_r_idx_ptr = brcmf_pcie_read_tcm32(devinfo, addr); + addr = ring_addr + BRCMF_SHARED_RING_H2D_W_IDX_PTR_OFFSET; + h2d_w_idx_ptr = brcmf_pcie_read_tcm32(devinfo, addr); + addr = ring_addr + BRCMF_SHARED_RING_H2D_R_IDX_PTR_OFFSET; + h2d_r_idx_ptr = brcmf_pcie_read_tcm32(devinfo, addr); + + addr = ring_addr + BRCMF_SHARED_RING_TCM_MEMLOC_OFFSET; + ring_mem_ptr = brcmf_pcie_read_tcm32(devinfo, addr); + + for (i = 0; i < BRCMF_NROF_H2D_COMMON_MSGRINGS; i++) { + ring = brcmf_pcie_alloc_dma_and_ring(devinfo, i, ring_mem_ptr); + if (!ring) + goto fail; + ring->w_idx_addr = h2d_w_idx_ptr; + ring->r_idx_addr = h2d_r_idx_ptr; + ring->id = i; + devinfo->shared.commonrings[i] = ring; + + h2d_w_idx_ptr += sizeof(u32); + h2d_r_idx_ptr += sizeof(u32); + ring_mem_ptr += BRCMF_RING_MEM_SZ; + } + + for (i = BRCMF_NROF_H2D_COMMON_MSGRINGS; + i < BRCMF_NROF_COMMON_MSGRINGS; i++) { + ring = brcmf_pcie_alloc_dma_and_ring(devinfo, i, ring_mem_ptr); + if (!ring) + goto fail; + ring->w_idx_addr = d2h_w_idx_ptr; + ring->r_idx_addr = d2h_r_idx_ptr; + ring->id = i; + devinfo->shared.commonrings[i] = ring; + + d2h_w_idx_ptr += sizeof(u32); + d2h_r_idx_ptr += sizeof(u32); + ring_mem_ptr += BRCMF_RING_MEM_SZ; + } + + addr = ring_addr + BRCMF_SHARED_RING_MAX_SUB_QUEUES; + max_sub_queues = brcmf_pcie_read_tcm16(devinfo, addr); + devinfo->shared.nrof_flowrings = + max_sub_queues - BRCMF_NROF_H2D_COMMON_MSGRINGS; + rings = kcalloc(devinfo->shared.nrof_flowrings, sizeof(*ring), + GFP_KERNEL); + if (!rings) + goto fail; + + brcmf_dbg(PCIE, "Nr of flowrings is %d\n", + devinfo->shared.nrof_flowrings); + + for (i = 0; i < devinfo->shared.nrof_flowrings; i++) { + ring = &rings[i]; + ring->devinfo = devinfo; + ring->id = i + BRCMF_NROF_COMMON_MSGRINGS; + brcmf_commonring_register_cb(&ring->commonring, + brcmf_pcie_ring_mb_ring_bell, + brcmf_pcie_ring_mb_update_rptr, + brcmf_pcie_ring_mb_update_wptr, + brcmf_pcie_ring_mb_write_rptr, + brcmf_pcie_ring_mb_write_wptr, + ring); + ring->w_idx_addr = h2d_w_idx_ptr; + ring->r_idx_addr = h2d_r_idx_ptr; + h2d_w_idx_ptr += sizeof(u32); + h2d_r_idx_ptr += sizeof(u32); + } + devinfo->shared.flowrings = rings; + + return 0; + +fail: + brcmf_err("Allocating commonring buffers failed\n"); + brcmf_pcie_release_ringbuffers(devinfo); + return -ENOMEM; +} + + +static void +brcmf_pcie_release_scratchbuffers(struct brcmf_pciedev_info *devinfo) +{ + if (devinfo->shared.scratch) + dma_free_coherent(&devinfo->pdev->dev, + BRCMF_DMA_D2H_SCRATCH_BUF_LEN, + devinfo->shared.scratch, + devinfo->shared.scratch_dmahandle); + if (devinfo->shared.ringupd) + dma_free_coherent(&devinfo->pdev->dev, + BRCMF_DMA_D2H_RINGUPD_BUF_LEN, + devinfo->shared.ringupd, + devinfo->shared.ringupd_dmahandle); +} + +static int brcmf_pcie_init_scratchbuffers(struct brcmf_pciedev_info *devinfo) +{ + long long address; + u32 addr; + + devinfo->shared.scratch = dma_alloc_coherent(&devinfo->pdev->dev, + BRCMF_DMA_D2H_SCRATCH_BUF_LEN, + &devinfo->shared.scratch_dmahandle, GFP_KERNEL); + if (!devinfo->shared.scratch) + goto fail; + + memset(devinfo->shared.scratch, 0, BRCMF_DMA_D2H_SCRATCH_BUF_LEN); + brcmf_dma_flush(devinfo->shared.scratch, BRCMF_DMA_D2H_SCRATCH_BUF_LEN); + + addr = devinfo->shared.tcm_base_address + + BRCMF_SHARED_DMA_SCRATCH_ADDR_OFFSET; + address = (long long)(long)devinfo->shared.scratch_dmahandle; + brcmf_pcie_write_tcm32(devinfo, addr, address & 0xffffffff); + brcmf_pcie_write_tcm32(devinfo, addr + 4, address >> 32); + addr = devinfo->shared.tcm_base_address + + BRCMF_SHARED_DMA_SCRATCH_LEN_OFFSET; + brcmf_pcie_write_tcm32(devinfo, addr, BRCMF_DMA_D2H_SCRATCH_BUF_LEN); + + devinfo->shared.ringupd = dma_alloc_coherent(&devinfo->pdev->dev, + BRCMF_DMA_D2H_RINGUPD_BUF_LEN, + &devinfo->shared.ringupd_dmahandle, GFP_KERNEL); + if (!devinfo->shared.ringupd) + goto fail; + + memset(devinfo->shared.ringupd, 0, BRCMF_DMA_D2H_RINGUPD_BUF_LEN); + brcmf_dma_flush(devinfo->shared.ringupd, BRCMF_DMA_D2H_RINGUPD_BUF_LEN); + + addr = devinfo->shared.tcm_base_address + + BRCMF_SHARED_DMA_RINGUPD_ADDR_OFFSET; + address = (long long)(long)devinfo->shared.ringupd_dmahandle; + brcmf_pcie_write_tcm32(devinfo, addr, address & 0xffffffff); + brcmf_pcie_write_tcm32(devinfo, addr + 4, address >> 32); + addr = devinfo->shared.tcm_base_address + + BRCMF_SHARED_DMA_RINGUPD_LEN_OFFSET; + brcmf_pcie_write_tcm32(devinfo, addr, BRCMF_DMA_D2H_RINGUPD_BUF_LEN); + return 0; + +fail: + brcmf_err("Allocating scratch buffers failed\n"); + brcmf_pcie_release_scratchbuffers(devinfo); + return -ENOMEM; +} + + +static void brcmf_pcie_down(struct device *dev) +{ +} + + +static int brcmf_pcie_tx(struct device *dev, struct sk_buff *skb) +{ + return 0; +} + + +static int brcmf_pcie_tx_ctlpkt(struct device *dev, unsigned char *msg, + uint len) +{ + return 0; +} + + +static int brcmf_pcie_rx_ctlpkt(struct device *dev, unsigned char *msg, + uint len) +{ + return 0; +} + + +static struct brcmf_bus_ops brcmf_pcie_bus_ops = { + .txdata = brcmf_pcie_tx, + .stop = brcmf_pcie_down, + .txctl = brcmf_pcie_tx_ctlpkt, + .rxctl = brcmf_pcie_rx_ctlpkt, +}; + + +static int +brcmf_pcie_init_share_ram_info(struct brcmf_pciedev_info *devinfo, + u32 sharedram_addr) +{ + struct brcmf_pcie_shared_info *shared; + u32 addr; + u32 version; + + shared = &devinfo->shared; + shared->tcm_base_address = sharedram_addr; + + shared->flags = brcmf_pcie_read_tcm32(devinfo, sharedram_addr); + version = shared->flags & BRCMF_PCIE_SHARED_VERSION_MASK; + brcmf_dbg(PCIE, "PCIe protocol version %d\n", version); + if ((version > BRCMF_PCIE_MAX_SHARED_VERSION) || + (version < BRCMF_PCIE_MIN_SHARED_VERSION)) { + brcmf_err("Unsupported PCIE version %d\n", version); + return -EINVAL; + } + if (shared->flags & BRCMF_PCIE_SHARED_TXPUSH_SUPPORT) { + brcmf_err("Unsupported legacy TX mode 0x%x\n", + shared->flags & BRCMF_PCIE_SHARED_TXPUSH_SUPPORT); + return -EINVAL; + } + + addr = sharedram_addr + BRCMF_SHARED_MAX_RXBUFPOST_OFFSET; + shared->max_rxbufpost = brcmf_pcie_read_tcm16(devinfo, addr); + if (shared->max_rxbufpost == 0) + shared->max_rxbufpost = BRCMF_DEF_MAX_RXBUFPOST; + + addr = sharedram_addr + BRCMF_SHARED_RX_DATAOFFSET_OFFSET; + shared->rx_dataoffset = brcmf_pcie_read_tcm32(devinfo, addr); + + addr = sharedram_addr + BRCMF_SHARED_HTOD_MB_DATA_ADDR_OFFSET; + shared->htod_mb_data_addr = brcmf_pcie_read_tcm32(devinfo, addr); + + addr = sharedram_addr + BRCMF_SHARED_DTOH_MB_DATA_ADDR_OFFSET; + shared->dtoh_mb_data_addr = brcmf_pcie_read_tcm32(devinfo, addr); + + addr = sharedram_addr + BRCMF_SHARED_RING_INFO_ADDR_OFFSET; + shared->ring_info_addr = brcmf_pcie_read_tcm32(devinfo, addr); + + brcmf_dbg(PCIE, "max rx buf post %d, rx dataoffset %d\n", + shared->max_rxbufpost, shared->rx_dataoffset); + + brcmf_pcie_bus_console_init(devinfo); + + return 0; +} + + +static int brcmf_pcie_get_fwnames(struct brcmf_pciedev_info *devinfo) +{ + char *fw_name; + char *nvram_name; + uint fw_len, nv_len; + char end; + + brcmf_dbg(PCIE, "Enter, chip 0x%04x chiprev %d\n", devinfo->ci->chip, + devinfo->ci->chiprev); + + switch (devinfo->ci->chip) { + case BRCM_CC_43602_CHIP_ID: + fw_name = BRCMF_PCIE_43602_FW_NAME; + nvram_name = BRCMF_PCIE_43602_NVRAM_NAME; + break; + case BRCM_CC_4354_CHIP_ID: + fw_name = BRCMF_PCIE_4354_FW_NAME; + nvram_name = BRCMF_PCIE_4354_NVRAM_NAME; + break; + case BRCM_CC_4356_CHIP_ID: + fw_name = BRCMF_PCIE_4356_FW_NAME; + nvram_name = BRCMF_PCIE_4356_NVRAM_NAME; + break; + case BRCM_CC_43567_CHIP_ID: + case BRCM_CC_43569_CHIP_ID: + case BRCM_CC_43570_CHIP_ID: + fw_name = BRCMF_PCIE_43570_FW_NAME; + nvram_name = BRCMF_PCIE_43570_NVRAM_NAME; + break; + default: + brcmf_err("Unsupported chip 0x%04x\n", devinfo->ci->chip); + return -ENODEV; + } + + fw_len = sizeof(devinfo->fw_name) - 1; + nv_len = sizeof(devinfo->nvram_name) - 1; + /* check if firmware path is provided by module parameter */ + if (brcmf_firmware_path[0] != '\0') { + strncpy(devinfo->fw_name, brcmf_firmware_path, fw_len); + strncpy(devinfo->nvram_name, brcmf_firmware_path, nv_len); + fw_len -= strlen(devinfo->fw_name); + nv_len -= strlen(devinfo->nvram_name); + + end = brcmf_firmware_path[strlen(brcmf_firmware_path) - 1]; + if (end != '/') { + strncat(devinfo->fw_name, "/", fw_len); + strncat(devinfo->nvram_name, "/", nv_len); + fw_len--; + nv_len--; + } + } + strncat(devinfo->fw_name, fw_name, fw_len); + strncat(devinfo->nvram_name, nvram_name, nv_len); + + return 0; +} + + +static int brcmf_pcie_download_fw_nvram(struct brcmf_pciedev_info *devinfo, + const struct firmware *fw, void *nvram, + u32 nvram_len) +{ + u32 sharedram_addr; + u32 sharedram_addr_written; + u32 loop_counter; + int err; + u32 address; + u32 resetintr; + + devinfo->ringbell = brcmf_pcie_ringbell_v2; + devinfo->generic_corerev = BRCMF_PCIE_GENREV2; + + brcmf_dbg(PCIE, "Halt ARM.\n"); + err = brcmf_pcie_enter_download_state(devinfo); + if (err) + return err; + + brcmf_dbg(PCIE, "Download FW %s\n", devinfo->fw_name); + brcmf_pcie_copy_mem_todev(devinfo, devinfo->ci->rambase, + (void *)fw->data, fw->size); + + resetintr = get_unaligned_le32(fw->data); + release_firmware(fw); + + /* reset last 4 bytes of RAM address. to be used for shared + * area. This identifies when FW is running + */ + brcmf_pcie_write_ram32(devinfo, devinfo->ci->ramsize - 4, 0); + + if (nvram) { + brcmf_dbg(PCIE, "Download NVRAM %s\n", devinfo->nvram_name); + address = devinfo->ci->rambase + devinfo->ci->ramsize - + nvram_len; + brcmf_pcie_copy_mem_todev(devinfo, address, nvram, nvram_len); + brcmf_fw_nvram_free(nvram); + } else { + brcmf_dbg(PCIE, "No matching NVRAM file found %s\n", + devinfo->nvram_name); + } + + sharedram_addr_written = brcmf_pcie_read_ram32(devinfo, + devinfo->ci->ramsize - + 4); + brcmf_dbg(PCIE, "Bring ARM in running state\n"); + err = brcmf_pcie_exit_download_state(devinfo, resetintr); + if (err) + return err; + + brcmf_dbg(PCIE, "Wait for FW init\n"); + sharedram_addr = sharedram_addr_written; + loop_counter = BRCMF_PCIE_FW_UP_TIMEOUT / 50; + while ((sharedram_addr == sharedram_addr_written) && (loop_counter)) { + msleep(50); + sharedram_addr = brcmf_pcie_read_ram32(devinfo, + devinfo->ci->ramsize - + 4); + loop_counter--; + } + if (sharedram_addr == sharedram_addr_written) { + brcmf_err("FW failed to initialize\n"); + return -ENODEV; + } + brcmf_dbg(PCIE, "Shared RAM addr: 0x%08x\n", sharedram_addr); + + return (brcmf_pcie_init_share_ram_info(devinfo, sharedram_addr)); +} + + +static int brcmf_pcie_get_resource(struct brcmf_pciedev_info *devinfo) +{ + struct pci_dev *pdev; + int err; + phys_addr_t bar0_addr, bar1_addr; + ulong bar1_size; + + pdev = devinfo->pdev; + + err = pci_enable_device(pdev); + if (err) { + brcmf_err("pci_enable_device failed err=%d\n", err); + return err; + } + + pci_set_master(pdev); + + /* Bar-0 mapped address */ + bar0_addr = pci_resource_start(pdev, 0); + /* Bar-1 mapped address */ + bar1_addr = pci_resource_start(pdev, 2); + /* read Bar-1 mapped memory range */ + bar1_size = pci_resource_len(pdev, 2); + if ((bar1_size == 0) || (bar1_addr == 0)) { + brcmf_err("BAR1 Not enabled, device size=%ld, addr=%#016llx\n", + bar1_size, (unsigned long long)bar1_addr); + return -EINVAL; + } + + devinfo->regs = ioremap_nocache(bar0_addr, BRCMF_PCIE_REG_MAP_SIZE); + devinfo->tcm = ioremap_nocache(bar1_addr, BRCMF_PCIE_TCM_MAP_SIZE); + devinfo->tcm_size = BRCMF_PCIE_TCM_MAP_SIZE; + + if (!devinfo->regs || !devinfo->tcm) { + brcmf_err("ioremap() failed (%p,%p)\n", devinfo->regs, + devinfo->tcm); + return -EINVAL; + } + brcmf_dbg(PCIE, "Phys addr : reg space = %p base addr %#016llx\n", + devinfo->regs, (unsigned long long)bar0_addr); + brcmf_dbg(PCIE, "Phys addr : mem space = %p base addr %#016llx\n", + devinfo->tcm, (unsigned long long)bar1_addr); + + return 0; +} + + +static void brcmf_pcie_release_resource(struct brcmf_pciedev_info *devinfo) +{ + if (devinfo->tcm) + iounmap(devinfo->tcm); + if (devinfo->regs) + iounmap(devinfo->regs); + + pci_disable_device(devinfo->pdev); +} + + +static int brcmf_pcie_attach_bus(struct device *dev) +{ + int ret; + + /* Attach to the common driver interface */ + ret = brcmf_attach(dev); + if (ret) { + brcmf_err("brcmf_attach failed\n"); + } else { + ret = brcmf_bus_start(dev); + if (ret) + brcmf_err("dongle is not responding\n"); + } + + return ret; +} + + +static u32 brcmf_pcie_buscore_prep_addr(const struct pci_dev *pdev, u32 addr) +{ + u32 ret_addr; + + ret_addr = addr & (BRCMF_PCIE_BAR0_REG_SIZE - 1); + addr &= ~(BRCMF_PCIE_BAR0_REG_SIZE - 1); + pci_write_config_dword(pdev, BRCMF_PCIE_BAR0_WINDOW, addr); + + return ret_addr; +} + + +static u32 brcmf_pcie_buscore_read32(void *ctx, u32 addr) +{ + struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)ctx; + + addr = brcmf_pcie_buscore_prep_addr(devinfo->pdev, addr); + return brcmf_pcie_read_reg32(devinfo, addr); +} + + +static void brcmf_pcie_buscore_write32(void *ctx, u32 addr, u32 value) +{ + struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)ctx; + + addr = brcmf_pcie_buscore_prep_addr(devinfo->pdev, addr); + brcmf_pcie_write_reg32(devinfo, addr, value); +} + + +static int brcmf_pcie_buscoreprep(void *ctx) +{ + struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)ctx; + int err; + + err = brcmf_pcie_get_resource(devinfo); + if (err == 0) { + /* Set CC watchdog to reset all the cores on the chip to bring + * back dongle to a sane state. + */ + brcmf_pcie_buscore_write32(ctx, CORE_CC_REG(SI_ENUM_BASE, + watchdog), 4); + msleep(100); + } + + return err; +} + + +static void brcmf_pcie_buscore_exitdl(void *ctx, struct brcmf_chip *chip, + u32 rstvec) +{ + struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)ctx; + + brcmf_pcie_write_tcm32(devinfo, 0, rstvec); +} + + +static const struct brcmf_buscore_ops brcmf_pcie_buscore_ops = { + .prepare = brcmf_pcie_buscoreprep, + .exit_dl = brcmf_pcie_buscore_exitdl, + .read32 = brcmf_pcie_buscore_read32, + .write32 = brcmf_pcie_buscore_write32, +}; + +static void brcmf_pcie_setup(struct device *dev, const struct firmware *fw, + void *nvram, u32 nvram_len) +{ + struct brcmf_bus *bus = dev_get_drvdata(dev); + struct brcmf_pciedev *pcie_bus_dev = bus->bus_priv.pcie; + struct brcmf_pciedev_info *devinfo = pcie_bus_dev->devinfo; + struct brcmf_commonring **flowrings; + int ret; + u32 i; + + brcmf_pcie_attach(devinfo); + + ret = brcmf_pcie_download_fw_nvram(devinfo, fw, nvram, nvram_len); + if (ret) + goto fail; + + devinfo->state = BRCMFMAC_PCIE_STATE_UP; + + ret = brcmf_pcie_init_ringbuffers(devinfo); + if (ret) + goto fail; + + ret = brcmf_pcie_init_scratchbuffers(devinfo); + if (ret) + goto fail; + + brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2); + ret = brcmf_pcie_request_irq(devinfo); + if (ret) + goto fail; + + /* hook the commonrings in the bus structure. */ + for (i = 0; i < BRCMF_NROF_COMMON_MSGRINGS; i++) + bus->msgbuf->commonrings[i] = + &devinfo->shared.commonrings[i]->commonring; + + flowrings = kcalloc(devinfo->shared.nrof_flowrings, sizeof(flowrings), + GFP_KERNEL); + if (!flowrings) + goto fail; + + for (i = 0; i < devinfo->shared.nrof_flowrings; i++) + flowrings[i] = &devinfo->shared.flowrings[i].commonring; + bus->msgbuf->flowrings = flowrings; + + bus->msgbuf->rx_dataoffset = devinfo->shared.rx_dataoffset; + bus->msgbuf->max_rxbufpost = devinfo->shared.max_rxbufpost; + bus->msgbuf->nrof_flowrings = devinfo->shared.nrof_flowrings; + + init_waitqueue_head(&devinfo->mbdata_resp_wait); + + brcmf_pcie_intr_enable(devinfo); + if (brcmf_pcie_attach_bus(bus->dev) == 0) + return; + + brcmf_pcie_bus_console_read(devinfo); + +fail: + device_release_driver(dev); +} + +static int +brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) +{ + int ret; + struct brcmf_pciedev_info *devinfo; + struct brcmf_pciedev *pcie_bus_dev; + struct brcmf_bus *bus; + + brcmf_dbg(PCIE, "Enter %x:%x\n", pdev->vendor, pdev->device); + + ret = -ENOMEM; + devinfo = kzalloc(sizeof(*devinfo), GFP_KERNEL); + if (devinfo == NULL) + return ret; + + devinfo->pdev = pdev; + pcie_bus_dev = NULL; + devinfo->ci = brcmf_chip_attach(devinfo, &brcmf_pcie_buscore_ops); + if (IS_ERR(devinfo->ci)) { + ret = PTR_ERR(devinfo->ci); + devinfo->ci = NULL; + goto fail; + } + + pcie_bus_dev = kzalloc(sizeof(*pcie_bus_dev), GFP_KERNEL); + if (pcie_bus_dev == NULL) { + ret = -ENOMEM; + goto fail; + } + + bus = kzalloc(sizeof(*bus), GFP_KERNEL); + if (!bus) { + ret = -ENOMEM; + goto fail; + } + bus->msgbuf = kzalloc(sizeof(*bus->msgbuf), GFP_KERNEL); + if (!bus->msgbuf) { + ret = -ENOMEM; + kfree(bus); + goto fail; + } + + /* hook it all together. */ + pcie_bus_dev->devinfo = devinfo; + pcie_bus_dev->bus = bus; + bus->dev = &pdev->dev; + bus->bus_priv.pcie = pcie_bus_dev; + bus->ops = &brcmf_pcie_bus_ops; + bus->proto_type = BRCMF_PROTO_MSGBUF; + bus->chip = devinfo->coreid; + dev_set_drvdata(&pdev->dev, bus); + + ret = brcmf_pcie_get_fwnames(devinfo); + if (ret) + goto fail_bus; + + ret = brcmf_fw_get_firmwares(bus->dev, BRCMF_FW_REQUEST_NVRAM | + BRCMF_FW_REQ_NV_OPTIONAL, + devinfo->fw_name, devinfo->nvram_name, + brcmf_pcie_setup); + if (ret == 0) + return 0; +fail_bus: + kfree(bus->msgbuf); + kfree(bus); +fail: + brcmf_err("failed %x:%x\n", pdev->vendor, pdev->device); + brcmf_pcie_release_resource(devinfo); + if (devinfo->ci) + brcmf_chip_detach(devinfo->ci); + kfree(pcie_bus_dev); + kfree(devinfo); + return ret; +} + + +static void +brcmf_pcie_remove(struct pci_dev *pdev) +{ + struct brcmf_pciedev_info *devinfo; + struct brcmf_bus *bus; + + brcmf_dbg(PCIE, "Enter\n"); + + bus = dev_get_drvdata(&pdev->dev); + if (bus == NULL) + return; + + devinfo = bus->bus_priv.pcie->devinfo; + + devinfo->state = BRCMFMAC_PCIE_STATE_DOWN; + if (devinfo->ci) + brcmf_pcie_intr_disable(devinfo); + + brcmf_detach(&pdev->dev); + + kfree(bus->bus_priv.pcie); + kfree(bus->msgbuf->flowrings); + kfree(bus->msgbuf); + kfree(bus); + + brcmf_pcie_release_irq(devinfo); + brcmf_pcie_release_scratchbuffers(devinfo); + brcmf_pcie_release_ringbuffers(devinfo); + brcmf_pcie_detach(devinfo); + brcmf_pcie_release_resource(devinfo); + + if (devinfo->ci) + brcmf_chip_detach(devinfo->ci); + + kfree(devinfo); + dev_set_drvdata(&pdev->dev, NULL); +} + + +#ifdef CONFIG_PM + + +static int brcmf_pcie_suspend(struct pci_dev *pdev, pm_message_t state) +{ + struct brcmf_pciedev_info *devinfo; + struct brcmf_bus *bus; + int err; + + brcmf_dbg(PCIE, "Enter, state=%d, pdev=%p\n", state.event, pdev); + + bus = dev_get_drvdata(&pdev->dev); + devinfo = bus->bus_priv.pcie->devinfo; + + brcmf_bus_change_state(bus, BRCMF_BUS_DOWN); + + devinfo->mbdata_completed = false; + brcmf_pcie_send_mb_data(devinfo, BRCMF_H2D_HOST_D3_INFORM); + + wait_event_timeout(devinfo->mbdata_resp_wait, + devinfo->mbdata_completed, + msecs_to_jiffies(BRCMF_PCIE_MBDATA_TIMEOUT)); + if (!devinfo->mbdata_completed) { + brcmf_err("Timeout on response for entering D3 substate\n"); + return -EIO; + } + brcmf_pcie_release_irq(devinfo); + + err = pci_save_state(pdev); + if (err) { + brcmf_err("pci_save_state failed, err=%d\n", err); + return err; + } + + brcmf_chip_detach(devinfo->ci); + devinfo->ci = NULL; + + brcmf_pcie_remove(pdev); + + return pci_prepare_to_sleep(pdev); +} + + +static int brcmf_pcie_resume(struct pci_dev *pdev) +{ + int err; + + brcmf_dbg(PCIE, "Enter, pdev=%p\n", pdev); + + err = pci_set_power_state(pdev, PCI_D0); + if (err) { + brcmf_err("pci_set_power_state failed, err=%d\n", err); + return err; + } + pci_restore_state(pdev); + + err = brcmf_pcie_probe(pdev, NULL); + if (err) + brcmf_err("probe after resume failed, err=%d\n", err); + + return err; +} + + +#endif /* CONFIG_PM */ + + +#define BRCMF_PCIE_DEVICE(dev_id) { BRCM_PCIE_VENDOR_ID_BROADCOM, dev_id,\ + PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_NETWORK_OTHER << 8, 0xffff00, 0 } + +static struct pci_device_id brcmf_pcie_devid_table[] = { + BRCMF_PCIE_DEVICE(BRCM_PCIE_4354_DEVICE_ID), + BRCMF_PCIE_DEVICE(BRCM_PCIE_4356_DEVICE_ID), + BRCMF_PCIE_DEVICE(BRCM_PCIE_43567_DEVICE_ID), + BRCMF_PCIE_DEVICE(BRCM_PCIE_43570_DEVICE_ID), + BRCMF_PCIE_DEVICE(BRCM_PCIE_43602_DEVICE_ID), + { /* end: all zeroes */ } +}; + + +MODULE_DEVICE_TABLE(pci, brcmf_pcie_devid_table); + + +static struct pci_driver brcmf_pciedrvr = { + .node = {}, + .name = KBUILD_MODNAME, + .id_table = brcmf_pcie_devid_table, + .probe = brcmf_pcie_probe, + .remove = brcmf_pcie_remove, +#ifdef CONFIG_PM + .suspend = brcmf_pcie_suspend, + .resume = brcmf_pcie_resume +#endif /* CONFIG_PM */ +}; + + +void brcmf_pcie_register(void) +{ + int err; + + brcmf_dbg(PCIE, "Enter\n"); + err = pci_register_driver(&brcmf_pciedrvr); + if (err) + brcmf_err("PCIE driver registration failed, err=%d\n", err); +} + + +void brcmf_pcie_exit(void) +{ + brcmf_dbg(PCIE, "Enter\n"); + pci_unregister_driver(&brcmf_pciedrvr); +} diff --git a/drivers/net/wireless/brcm80211/brcmfmac/pcie.h b/drivers/net/wireless/brcm80211/brcmfmac/pcie.h new file mode 100644 index 00000000000..6edaaf8ef5c --- /dev/null +++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.h @@ -0,0 +1,29 @@ +/* Copyright (c) 2014 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#ifndef BRCMFMAC_PCIE_H +#define BRCMFMAC_PCIE_H + + +struct brcmf_pciedev { + struct brcmf_bus *bus; + struct brcmf_pciedev_info *devinfo; +}; + + +void brcmf_pcie_exit(void); +void brcmf_pcie_register(void); + + +#endif /* BRCMFMAC_PCIE_H */ diff --git a/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h index 64d1a7ba040..af26e0de1e5 100644 --- a/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h +++ b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h @@ -38,8 +38,12 @@ #define BRCM_CC_4335_CHIP_ID 0x4335 #define BRCM_CC_4339_CHIP_ID 0x4339 #define BRCM_CC_4354_CHIP_ID 0x4354 +#define BRCM_CC_4356_CHIP_ID 0x4356 #define BRCM_CC_43566_CHIP_ID 43566 +#define BRCM_CC_43567_CHIP_ID 43567 #define BRCM_CC_43569_CHIP_ID 43569 +#define BRCM_CC_43570_CHIP_ID 43570 +#define BRCM_CC_43602_CHIP_ID 43602 /* SDIO Device IDs */ #define BRCM_SDIO_43143_DEVICE_ID BRCM_CC_43143_CHIP_ID @@ -58,6 +62,13 @@ #define BRCM_USB_43569_DEVICE_ID 0xbd27 #define BRCM_USB_BCMFW_DEVICE_ID 0x0bdc +/* PCIE Device IDs */ +#define BRCM_PCIE_4354_DEVICE_ID 0x43df +#define BRCM_PCIE_4356_DEVICE_ID 0x43ec +#define BRCM_PCIE_43567_DEVICE_ID 0x43d3 +#define BRCM_PCIE_43570_DEVICE_ID 0x43d9 +#define BRCM_PCIE_43602_DEVICE_ID 0x43ba + /* brcmsmac IDs */ #define BCM4313_D11N2G_ID 0x4727 /* 4313 802.11n 2.4G device */ #define BCM43224_D11N_ID 0x4353 /* 43224 802.11n dualband device */ -- cgit v1.2.3-70-g09d2