diff --git a/[refs] b/[refs] index e15e97b731bf..75d31791f457 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: bd2d0837abc0206ecdd3f6b9fc8c25b55b63c96b +refs/heads/master: 80d0a69fc57715dc9080c0567df1ed911b78abea diff --git a/trunk/Documentation/networking/ip-sysctl.txt b/trunk/Documentation/networking/ip-sysctl.txt index e1e021594cff..e20c17a7d34e 100644 --- a/trunk/Documentation/networking/ip-sysctl.txt +++ b/trunk/Documentation/networking/ip-sysctl.txt @@ -565,11 +565,6 @@ tcp_limit_output_bytes - INTEGER reduce the size of individual GSO packet (64KB being the max) Default: 131072 -tcp_challenge_ack_limit - INTEGER - Limits number of Challenge ACK sent per second, as recommended - in RFC 5961 (Improving TCP's Robustness to Blind In-Window Attacks) - Default: 100 - UDP variables: udp_mem - vector of 3 INTEGERs: min, pressure, max diff --git a/trunk/arch/blackfin/mach-bf537/boards/stamp.c b/trunk/arch/blackfin/mach-bf537/boards/stamp.c index 5ed654ae66e1..c9d9473a5ab2 100644 --- a/trunk/arch/blackfin/mach-bf537/boards/stamp.c +++ b/trunk/arch/blackfin/mach-bf537/boards/stamp.c @@ -873,7 +873,7 @@ static struct adf702x_platform_data adf7021_platform_data = { }; static inline void adf702x_mac_init(void) { - eth_random_addr(adf7021_platform_data.mac_addr); + random_ether_addr(adf7021_platform_data.mac_addr); } #else static inline void adf702x_mac_init(void) {} diff --git a/trunk/arch/c6x/kernel/soc.c b/trunk/arch/c6x/kernel/soc.c index 3ac74080fded..0748c94ebef6 100644 --- a/trunk/arch/c6x/kernel/soc.c +++ b/trunk/arch/c6x/kernel/soc.c @@ -80,7 +80,7 @@ int soc_mac_addr(unsigned int index, u8 *addr) if (have_fuse_mac) memcpy(addr, c6x_fuse_mac, 6); else - eth_random_addr(addr); + random_ether_addr(addr); } /* adjust for specific EMAC device */ diff --git a/trunk/arch/mips/ar7/platform.c b/trunk/arch/mips/ar7/platform.c index 1bbc24b08685..1a24d317e7a3 100644 --- a/trunk/arch/mips/ar7/platform.c +++ b/trunk/arch/mips/ar7/platform.c @@ -310,10 +310,10 @@ static void __init cpmac_get_mac(int instance, unsigned char *dev_addr) &dev_addr[4], &dev_addr[5]) != 6) { pr_warning("cannot parse mac address, " "using random address\n"); - eth_random_addr(dev_addr); + random_ether_addr(dev_addr); } } else - eth_random_addr(dev_addr); + random_ether_addr(dev_addr); } /***************************************************************************** diff --git a/trunk/arch/mips/powertv/powertv_setup.c b/trunk/arch/mips/powertv/powertv_setup.c index 820b8480f222..3933c373a438 100644 --- a/trunk/arch/mips/powertv/powertv_setup.c +++ b/trunk/arch/mips/powertv/powertv_setup.c @@ -254,7 +254,7 @@ early_param("rfmac", rfmac_param); * Generates an Ethernet MAC address that is highly likely to be unique for * this particular system on a network with other systems of the same type. * - * The problem we are solving is that, when eth_random_addr() is used to + * The problem we are solving is that, when random_ether_addr() is used to * generate MAC addresses at startup, there isn't much entropy for the random * number generator to use and the addresses it produces are fairly likely to * be the same as those of other identical systems on the same local network. @@ -269,7 +269,7 @@ early_param("rfmac", rfmac_param); * Still, this does give us something to work with. * * The approach we take is: - * 1. If we can't get the RF MAC Address, just call eth_random_addr. + * 1. If we can't get the RF MAC Address, just call random_ether_addr. * 2. Use the 24-bit NIC-specific bits of the RF MAC address as the last 24 * bits of the new address. This is very likely to be unique, except for * the current box. @@ -299,7 +299,7 @@ void platform_random_ether_addr(u8 addr[ETH_ALEN]) if (!have_rfmac) { pr_warning("rfmac not available on command line; " "generating random MAC address\n"); - eth_random_addr(addr); + random_ether_addr(addr); } else { diff --git a/trunk/arch/um/drivers/net_kern.c b/trunk/arch/um/drivers/net_kern.c index 458d324f062d..0d60c5685c26 100644 --- a/trunk/arch/um/drivers/net_kern.c +++ b/trunk/arch/um/drivers/net_kern.c @@ -339,7 +339,7 @@ static int setup_etheraddr(char *str, unsigned char *addr, char *name) random: printk(KERN_INFO "Choosing a random ethernet address for device %s\n", name); - eth_random_addr(addr); + random_ether_addr(addr); return 1; } diff --git a/trunk/drivers/connector/cn_proc.c b/trunk/drivers/connector/cn_proc.c index 3e92b7d3fcd2..77e1e6cd66ce 100644 --- a/trunk/drivers/connector/cn_proc.c +++ b/trunk/drivers/connector/cn_proc.c @@ -46,7 +46,7 @@ static DEFINE_PER_CPU(__u32, proc_event_counts) = { 0 }; static inline void get_seq(__u32 *ts, int *cpu) { preempt_disable(); - *ts = __this_cpu_inc_return(proc_event_counts) - 1; + *ts = __this_cpu_inc_return(proc_event_counts) -1; *cpu = smp_processor_id(); preempt_enable(); } @@ -62,8 +62,8 @@ void proc_fork_connector(struct task_struct *task) if (atomic_read(&proc_event_num_listeners) < 1) return; - msg = (struct cn_msg *)buffer; - ev = (struct proc_event *)msg->data; + msg = (struct cn_msg*)buffer; + ev = (struct proc_event*)msg->data; get_seq(&msg->seq, &ev->cpu); ktime_get_ts(&ts); /* get high res monotonic timestamp */ put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns); @@ -93,8 +93,8 @@ void proc_exec_connector(struct task_struct *task) if (atomic_read(&proc_event_num_listeners) < 1) return; - msg = (struct cn_msg *)buffer; - ev = (struct proc_event *)msg->data; + msg = (struct cn_msg*)buffer; + ev = (struct proc_event*)msg->data; get_seq(&msg->seq, &ev->cpu); ktime_get_ts(&ts); /* get high res monotonic timestamp */ put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns); @@ -119,8 +119,8 @@ void proc_id_connector(struct task_struct *task, int which_id) if (atomic_read(&proc_event_num_listeners) < 1) return; - msg = (struct cn_msg *)buffer; - ev = (struct proc_event *)msg->data; + msg = (struct cn_msg*)buffer; + ev = (struct proc_event*)msg->data; ev->what = which_id; ev->event_data.id.process_pid = task->pid; ev->event_data.id.process_tgid = task->tgid; @@ -134,7 +134,7 @@ void proc_id_connector(struct task_struct *task, int which_id) ev->event_data.id.e.egid = cred->egid; } else { rcu_read_unlock(); - return; + return; } rcu_read_unlock(); get_seq(&msg->seq, &ev->cpu); @@ -241,8 +241,8 @@ void proc_exit_connector(struct task_struct *task) if (atomic_read(&proc_event_num_listeners) < 1) return; - msg = (struct cn_msg *)buffer; - ev = (struct proc_event *)msg->data; + msg = (struct cn_msg*)buffer; + ev = (struct proc_event*)msg->data; get_seq(&msg->seq, &ev->cpu); ktime_get_ts(&ts); /* get high res monotonic timestamp */ put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns); @@ -276,8 +276,8 @@ static void cn_proc_ack(int err, int rcvd_seq, int rcvd_ack) if (atomic_read(&proc_event_num_listeners) < 1) return; - msg = (struct cn_msg *)buffer; - ev = (struct proc_event *)msg->data; + msg = (struct cn_msg*)buffer; + ev = (struct proc_event*)msg->data; msg->seq = rcvd_seq; ktime_get_ts(&ts); /* get high res monotonic timestamp */ put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns); @@ -303,7 +303,7 @@ static void cn_proc_mcast_ctl(struct cn_msg *msg, if (msg->len != sizeof(*mc_op)) return; - mc_op = (enum proc_cn_mcast_op *)msg->data; + mc_op = (enum proc_cn_mcast_op*)msg->data; switch (*mc_op) { case PROC_CN_MCAST_LISTEN: atomic_inc(&proc_event_num_listeners); @@ -325,11 +325,11 @@ static void cn_proc_mcast_ctl(struct cn_msg *msg, */ static int __init cn_proc_init(void) { - int err = cn_add_callback(&cn_proc_event_id, - "cn_proc", - &cn_proc_mcast_ctl); - if (err) { - pr_warn("cn_proc failed to register\n"); + int err; + + if ((err = cn_add_callback(&cn_proc_event_id, "cn_proc", + &cn_proc_mcast_ctl))) { + printk(KERN_WARNING "cn_proc failed to register\n"); return err; } return 0; diff --git a/trunk/drivers/connector/cn_queue.c b/trunk/drivers/connector/cn_queue.c index 1f8bf054d11c..c42c9d517790 100644 --- a/trunk/drivers/connector/cn_queue.c +++ b/trunk/drivers/connector/cn_queue.c @@ -1,5 +1,5 @@ /* - * cn_queue.c + * cn_queue.c * * 2004+ Copyright (c) Evgeniy Polyakov * All rights reserved. @@ -34,14 +34,13 @@ static struct cn_callback_entry * cn_queue_alloc_callback_entry(struct cn_queue_dev *dev, const char *name, struct cb_id *id, - void (*callback)(struct cn_msg *, - struct netlink_skb_parms *)) + void (*callback)(struct cn_msg *, struct netlink_skb_parms *)) { struct cn_callback_entry *cbq; cbq = kzalloc(sizeof(*cbq), GFP_KERNEL); if (!cbq) { - pr_err("Failed to create new callback queue.\n"); + printk(KERN_ERR "Failed to create new callback queue.\n"); return NULL; } @@ -72,8 +71,7 @@ int cn_cb_equal(struct cb_id *i1, struct cb_id *i2) int cn_queue_add_callback(struct cn_queue_dev *dev, const char *name, struct cb_id *id, - void (*callback)(struct cn_msg *, - struct netlink_skb_parms *)) + void (*callback)(struct cn_msg *, struct netlink_skb_parms *)) { struct cn_callback_entry *cbq, *__cbq; int found = 0; @@ -151,7 +149,7 @@ void cn_queue_free_dev(struct cn_queue_dev *dev) spin_unlock_bh(&dev->queue_lock); while (atomic_read(&dev->refcnt)) { - pr_info("Waiting for %s to become free: refcnt=%d.\n", + printk(KERN_INFO "Waiting for %s to become free: refcnt=%d.\n", dev->name, atomic_read(&dev->refcnt)); msleep(1000); } diff --git a/trunk/drivers/connector/connector.c b/trunk/drivers/connector/connector.c index 82fa4f0f91d6..116cf8d02834 100644 --- a/trunk/drivers/connector/connector.c +++ b/trunk/drivers/connector/connector.c @@ -1,5 +1,5 @@ /* - * connector.c + * connector.c * * 2004+ Copyright (c) Evgeniy Polyakov * All rights reserved. @@ -185,8 +185,7 @@ static void cn_rx_skb(struct sk_buff *__skb) * May sleep. */ int cn_add_callback(struct cb_id *id, const char *name, - void (*callback)(struct cn_msg *, - struct netlink_skb_parms *)) + void (*callback)(struct cn_msg *, struct netlink_skb_parms *)) { int err; struct cn_dev *dev = &cdev; diff --git a/trunk/drivers/isdn/gigaset/capi.c b/trunk/drivers/isdn/gigaset/capi.c index 68452b768da2..27e4a3e21d64 100644 --- a/trunk/drivers/isdn/gigaset/capi.c +++ b/trunk/drivers/isdn/gigaset/capi.c @@ -288,7 +288,6 @@ static inline void dump_rawmsg(enum debuglevel level, const char *tag, * format CAPI IE as string */ -#ifdef CONFIG_GIGASET_DEBUG static const char *format_ie(const char *ie) { static char result[3 * MAX_FMT_IE_LEN]; @@ -314,7 +313,6 @@ static const char *format_ie(const char *ie) *--pout = 0; return result; } -#endif /* * emit DATA_B3_CONF message diff --git a/trunk/drivers/net/bonding/bond_main.c b/trunk/drivers/net/bonding/bond_main.c index 1eb3979d0af5..4ddcc3e41dab 100644 --- a/trunk/drivers/net/bonding/bond_main.c +++ b/trunk/drivers/net/bonding/bond_main.c @@ -1240,7 +1240,9 @@ static inline int slave_enable_netpoll(struct slave *slave) if (!np) goto out; - err = __netpoll_setup(np, slave->dev); + np->dev = slave->dev; + strlcpy(np->dev_name, slave->dev->name, IFNAMSIZ); + err = __netpoll_setup(np); if (err) { kfree(np); goto out; diff --git a/trunk/drivers/net/can/flexcan.c b/trunk/drivers/net/can/flexcan.c index 1b6f5621ce89..81324a11a50f 100644 --- a/trunk/drivers/net/can/flexcan.c +++ b/trunk/drivers/net/can/flexcan.c @@ -192,7 +192,7 @@ struct flexcan_priv { struct clk *clk; struct flexcan_platform_data *pdata; - const struct flexcan_devtype_data *devtype_data; + struct flexcan_devtype_data *devtype_data; }; static struct flexcan_devtype_data fsl_p1010_devtype_data = { @@ -960,7 +960,7 @@ static const struct platform_device_id flexcan_id_table[] = { static int __devinit flexcan_probe(struct platform_device *pdev) { const struct of_device_id *of_id; - const struct flexcan_devtype_data *devtype_data; + struct flexcan_devtype_data *devtype_data; struct net_device *dev; struct flexcan_priv *priv; struct resource *mem; diff --git a/trunk/drivers/net/can/mscan/mpc5xxx_can.c b/trunk/drivers/net/can/mscan/mpc5xxx_can.c index 06adf881ea24..5caa572d71e3 100644 --- a/trunk/drivers/net/can/mscan/mpc5xxx_can.c +++ b/trunk/drivers/net/can/mscan/mpc5xxx_can.c @@ -251,7 +251,7 @@ static struct of_device_id mpc5xxx_can_table[]; static int __devinit mpc5xxx_can_probe(struct platform_device *ofdev) { const struct of_device_id *match; - const struct mpc5xxx_can_data *data; + struct mpc5xxx_can_data *data; struct device_node *np = ofdev->dev.of_node; struct net_device *dev; struct mscan_priv *priv; diff --git a/trunk/drivers/net/can/softing/softing_main.c b/trunk/drivers/net/can/softing/softing_main.c index f2a221e7b968..a7c77c744ee9 100644 --- a/trunk/drivers/net/can/softing/softing_main.c +++ b/trunk/drivers/net/can/softing/softing_main.c @@ -826,12 +826,12 @@ static __devinit int softing_pdev_probe(struct platform_device *pdev) goto sysfs_failed; } + ret = -ENOMEM; for (j = 0; j < ARRAY_SIZE(card->net); ++j) { card->net[j] = netdev = softing_netdev_create(card, card->id.chip[j]); if (!netdev) { dev_alert(&pdev->dev, "failed to make can[%i]", j); - ret = -ENOMEM; goto netdev_failed; } priv = netdev_priv(card->net[j]); diff --git a/trunk/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c b/trunk/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c index 21e261ffbe10..801f0126512d 100644 --- a/trunk/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c +++ b/trunk/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c @@ -199,7 +199,7 @@ int atl1c_read_mac_addr(struct atl1c_hw *hw) err = atl1c_get_permanent_address(hw); if (err) - eth_random_addr(hw->perm_mac_addr); + random_ether_addr(hw->perm_mac_addr); memcpy(hw->mac_addr, hw->perm_mac_addr, sizeof(hw->perm_mac_addr)); return err; diff --git a/trunk/drivers/net/ethernet/atheros/atlx/atl1.c b/trunk/drivers/net/ethernet/atheros/atlx/atl1.c index 7bae2ad7a7c0..f2402f355cec 100644 --- a/trunk/drivers/net/ethernet/atheros/atlx/atl1.c +++ b/trunk/drivers/net/ethernet/atheros/atlx/atl1.c @@ -538,7 +538,7 @@ static s32 atl1_read_mac_addr(struct atl1_hw *hw) u16 i; if (atl1_get_permanent_address(hw)) { - eth_random_addr(hw->perm_mac_addr); + random_ether_addr(hw->perm_mac_addr); ret = 1; } diff --git a/trunk/drivers/net/ethernet/atheros/atlx/atl2.c b/trunk/drivers/net/ethernet/atheros/atlx/atl2.c index 57d64b80fd72..7c0b7e2bcb66 100644 --- a/trunk/drivers/net/ethernet/atheros/atlx/atl2.c +++ b/trunk/drivers/net/ethernet/atheros/atlx/atl2.c @@ -2346,7 +2346,7 @@ static s32 atl2_read_mac_addr(struct atl2_hw *hw) { if (get_permanent_address(hw)) { /* for test */ - /* FIXME: shouldn't we use eth_random_addr() here? */ + /* FIXME: shouldn't we use random_ether_addr() here? */ hw->perm_mac_addr[0] = 0x00; hw->perm_mac_addr[1] = 0x13; hw->perm_mac_addr[2] = 0x74; diff --git a/trunk/drivers/net/ethernet/broadcom/bnx2.c b/trunk/drivers/net/ethernet/broadcom/bnx2.c index 79cebd8525ce..0ced154129a9 100644 --- a/trunk/drivers/net/ethernet/broadcom/bnx2.c +++ b/trunk/drivers/net/ethernet/broadcom/bnx2.c @@ -6388,7 +6388,6 @@ bnx2_reset_task(struct work_struct *work) { struct bnx2 *bp = container_of(work, struct bnx2, reset_task); int rc; - u16 pcicmd; rtnl_lock(); if (!netif_running(bp->dev)) { @@ -6398,12 +6397,6 @@ bnx2_reset_task(struct work_struct *work) bnx2_netif_stop(bp, true); - pci_read_config_word(bp->pdev, PCI_COMMAND, &pcicmd); - if (!(pcicmd & PCI_COMMAND_MEMORY)) { - /* in case PCI block has reset */ - pci_restore_state(bp->pdev); - pci_save_state(bp->pdev); - } rc = bnx2_init_nic(bp, 1); if (rc) { netdev_err(bp->dev, "failed to reset NIC, closing\n"); diff --git a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h index dbe97918a7fd..52f33b8c41e5 100644 --- a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +++ b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h @@ -614,22 +614,6 @@ struct bnx2x_fastpath { #define TX_BD(x) ((x) & MAX_TX_BD) #define TX_BD_POFF(x) ((x) & MAX_TX_DESC_CNT) -/* number of NEXT_PAGE descriptors may be required during placement */ -#define NEXT_CNT_PER_TX_PKT(bds) \ - (((bds) + MAX_TX_DESC_CNT - 1) / \ - MAX_TX_DESC_CNT * NEXT_PAGE_TX_DESC_CNT) -/* max BDs per tx packet w/o next_pages: - * START_BD - describes packed - * START_BD(splitted) - includes unpaged data segment for GSO - * PARSING_BD - for TSO and CSUM data - * Frag BDs - decribes pages for frags - */ -#define BDS_PER_TX_PKT 3 -#define MAX_BDS_PER_TX_PKT (MAX_SKB_FRAGS + BDS_PER_TX_PKT) -/* max BDs per tx packet including next pages */ -#define MAX_DESC_PER_TX_PKT (MAX_BDS_PER_TX_PKT + \ - NEXT_CNT_PER_TX_PKT(MAX_BDS_PER_TX_PKT)) - /* The RX BD ring is special, each bd is 8 bytes but the last one is 16 */ #define NUM_RX_RINGS 8 #define RX_DESC_CNT (BCM_PAGE_SIZE / sizeof(struct eth_rx_bd)) diff --git a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index e879e19eb0d6..5aeb034fa05c 100644 --- a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -221,7 +221,7 @@ int bnx2x_tx_int(struct bnx2x *bp, struct bnx2x_fp_txdata *txdata) if ((netif_tx_queue_stopped(txq)) && (bp->state == BNX2X_STATE_OPEN) && - (bnx2x_tx_avail(bp, txdata) >= MAX_DESC_PER_TX_PKT)) + (bnx2x_tx_avail(bp, txdata) >= MAX_SKB_FRAGS + 4)) netif_tx_wake_queue(txq); __netif_tx_unlock(txq); @@ -2948,9 +2948,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) txdata->cid, fp_index, txdata_index, txdata, fp); */ if (unlikely(bnx2x_tx_avail(bp, txdata) < - skb_shinfo(skb)->nr_frags + - BDS_PER_TX_PKT + - NEXT_CNT_PER_TX_PKT(MAX_BDS_PER_TX_PKT))) { + (skb_shinfo(skb)->nr_frags + 3))) { bnx2x_fp_qstats(bp, txdata->parent_fp)->driver_xoff++; netif_tx_stop_queue(txq); BNX2X_ERR("BUG! Tx ring full when queue awake!\n"); @@ -3225,7 +3223,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) txdata->tx_bd_prod += nbd; - if (unlikely(bnx2x_tx_avail(bp, txdata) < MAX_DESC_PER_TX_PKT)) { + if (unlikely(bnx2x_tx_avail(bp, txdata) < MAX_SKB_FRAGS + 4)) { netif_tx_stop_queue(txq); /* paired memory barrier is in bnx2x_tx_int(), we have to keep @@ -3234,7 +3232,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) smp_mb(); bnx2x_fp_qstats(bp, txdata->parent_fp)->driver_xoff++; - if (bnx2x_tx_avail(bp, txdata) >= MAX_DESC_PER_TX_PKT) + if (bnx2x_tx_avail(bp, txdata) >= MAX_SKB_FRAGS + 4) netif_tx_wake_queue(txq); } txdata->tx_pkt++; diff --git a/trunk/drivers/net/ethernet/broadcom/tg3.c b/trunk/drivers/net/ethernet/broadcom/tg3.c index fce4c1e4dd3f..ac9091f9d42b 100644 --- a/trunk/drivers/net/ethernet/broadcom/tg3.c +++ b/trunk/drivers/net/ethernet/broadcom/tg3.c @@ -44,10 +44,6 @@ #include #include #include -#if IS_ENABLED(CONFIG_HWMON) -#include -#include -#endif #include #include @@ -735,131 +731,44 @@ static void tg3_ape_unlock(struct tg3 *tp, int locknum) tg3_ape_write32(tp, gnt + 4 * locknum, bit); } -static int tg3_ape_event_lock(struct tg3 *tp, u32 timeout_us) +static void tg3_ape_send_event(struct tg3 *tp, u32 event) { + int i; u32 apedata; - while (timeout_us) { - if (tg3_ape_lock(tp, TG3_APE_LOCK_MEM)) - return -EBUSY; - - apedata = tg3_ape_read32(tp, TG3_APE_EVENT_STATUS); - if (!(apedata & APE_EVENT_STATUS_EVENT_PENDING)) - break; - - tg3_ape_unlock(tp, TG3_APE_LOCK_MEM); - - udelay(10); - timeout_us -= (timeout_us > 10) ? 10 : timeout_us; - } - - return timeout_us ? 0 : -EBUSY; -} - -static int tg3_ape_wait_for_event(struct tg3 *tp, u32 timeout_us) -{ - u32 i, apedata; - - for (i = 0; i < timeout_us / 10; i++) { - apedata = tg3_ape_read32(tp, TG3_APE_EVENT_STATUS); - - if (!(apedata & APE_EVENT_STATUS_EVENT_PENDING)) - break; - - udelay(10); - } - - return i == timeout_us / 10; -} - -int tg3_ape_scratchpad_read(struct tg3 *tp, u32 *data, u32 base_off, u32 len) -{ - int err; - u32 i, bufoff, msgoff, maxlen, apedata; - - if (!tg3_flag(tp, APE_HAS_NCSI)) - return 0; + /* NCSI does not support APE events */ + if (tg3_flag(tp, APE_HAS_NCSI)) + return; apedata = tg3_ape_read32(tp, TG3_APE_SEG_SIG); if (apedata != APE_SEG_SIG_MAGIC) - return -ENODEV; + return; apedata = tg3_ape_read32(tp, TG3_APE_FW_STATUS); if (!(apedata & APE_FW_STATUS_READY)) - return -EAGAIN; - - bufoff = tg3_ape_read32(tp, TG3_APE_SEG_MSG_BUF_OFF) + - TG3_APE_SHMEM_BASE; - msgoff = bufoff + 2 * sizeof(u32); - maxlen = tg3_ape_read32(tp, TG3_APE_SEG_MSG_BUF_LEN); - - while (len) { - u32 length; - - /* Cap xfer sizes to scratchpad limits. */ - length = (len > maxlen) ? maxlen : len; - len -= length; - - apedata = tg3_ape_read32(tp, TG3_APE_FW_STATUS); - if (!(apedata & APE_FW_STATUS_READY)) - return -EAGAIN; + return; - /* Wait for up to 1 msec for APE to service previous event. */ - err = tg3_ape_event_lock(tp, 1000); - if (err) - return err; + /* Wait for up to 1 millisecond for APE to service previous event. */ + for (i = 0; i < 10; i++) { + if (tg3_ape_lock(tp, TG3_APE_LOCK_MEM)) + return; - apedata = APE_EVENT_STATUS_DRIVER_EVNT | - APE_EVENT_STATUS_SCRTCHPD_READ | - APE_EVENT_STATUS_EVENT_PENDING; - tg3_ape_write32(tp, TG3_APE_EVENT_STATUS, apedata); + apedata = tg3_ape_read32(tp, TG3_APE_EVENT_STATUS); - tg3_ape_write32(tp, bufoff, base_off); - tg3_ape_write32(tp, bufoff + sizeof(u32), length); + if (!(apedata & APE_EVENT_STATUS_EVENT_PENDING)) + tg3_ape_write32(tp, TG3_APE_EVENT_STATUS, + event | APE_EVENT_STATUS_EVENT_PENDING); tg3_ape_unlock(tp, TG3_APE_LOCK_MEM); - tg3_ape_write32(tp, TG3_APE_EVENT, APE_EVENT_1); - - base_off += length; - if (tg3_ape_wait_for_event(tp, 30000)) - return -EAGAIN; + if (!(apedata & APE_EVENT_STATUS_EVENT_PENDING)) + break; - for (i = 0; length; i += 4, length -= 4) { - u32 val = tg3_ape_read32(tp, msgoff + i); - memcpy(data, &val, sizeof(u32)); - data++; - } + udelay(100); } - return 0; -} - -static int tg3_ape_send_event(struct tg3 *tp, u32 event) -{ - int err; - u32 apedata; - - apedata = tg3_ape_read32(tp, TG3_APE_SEG_SIG); - if (apedata != APE_SEG_SIG_MAGIC) - return -EAGAIN; - - apedata = tg3_ape_read32(tp, TG3_APE_FW_STATUS); - if (!(apedata & APE_FW_STATUS_READY)) - return -EAGAIN; - - /* Wait for up to 1 millisecond for APE to service previous event. */ - err = tg3_ape_event_lock(tp, 1000); - if (err) - return err; - - tg3_ape_write32(tp, TG3_APE_EVENT_STATUS, - event | APE_EVENT_STATUS_EVENT_PENDING); - - tg3_ape_unlock(tp, TG3_APE_LOCK_MEM); - tg3_ape_write32(tp, TG3_APE_EVENT, APE_EVENT_1); - - return 0; + if (!(apedata & APE_EVENT_STATUS_EVENT_PENDING)) + tg3_ape_write32(tp, TG3_APE_EVENT, APE_EVENT_1); } static void tg3_ape_driver_state_change(struct tg3 *tp, int kind) @@ -9485,110 +9394,6 @@ static int tg3_init_hw(struct tg3 *tp, int reset_phy) return tg3_reset_hw(tp, reset_phy); } -#if IS_ENABLED(CONFIG_HWMON) -static void tg3_sd_scan_scratchpad(struct tg3 *tp, struct tg3_ocir *ocir) -{ - int i; - - for (i = 0; i < TG3_SD_NUM_RECS; i++, ocir++) { - u32 off = i * TG3_OCIR_LEN, len = TG3_OCIR_LEN; - - tg3_ape_scratchpad_read(tp, (u32 *) ocir, off, len); - off += len; - - if (ocir->signature != TG3_OCIR_SIG_MAGIC || - !(ocir->version_flags & TG3_OCIR_FLAG_ACTIVE)) - memset(ocir, 0, TG3_OCIR_LEN); - } -} - -/* sysfs attributes for hwmon */ -static ssize_t tg3_show_temp(struct device *dev, - struct device_attribute *devattr, char *buf) -{ - struct pci_dev *pdev = to_pci_dev(dev); - struct net_device *netdev = pci_get_drvdata(pdev); - struct tg3 *tp = netdev_priv(netdev); - struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); - u32 temperature; - - spin_lock_bh(&tp->lock); - tg3_ape_scratchpad_read(tp, &temperature, attr->index, - sizeof(temperature)); - spin_unlock_bh(&tp->lock); - return sprintf(buf, "%u\n", temperature); -} - - -static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, tg3_show_temp, NULL, - TG3_TEMP_SENSOR_OFFSET); -static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, tg3_show_temp, NULL, - TG3_TEMP_CAUTION_OFFSET); -static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO, tg3_show_temp, NULL, - TG3_TEMP_MAX_OFFSET); - -static struct attribute *tg3_attributes[] = { - &sensor_dev_attr_temp1_input.dev_attr.attr, - &sensor_dev_attr_temp1_crit.dev_attr.attr, - &sensor_dev_attr_temp1_max.dev_attr.attr, - NULL -}; - -static const struct attribute_group tg3_group = { - .attrs = tg3_attributes, -}; - -#endif - -static void tg3_hwmon_close(struct tg3 *tp) -{ -#if IS_ENABLED(CONFIG_HWMON) - if (tp->hwmon_dev) { - hwmon_device_unregister(tp->hwmon_dev); - tp->hwmon_dev = NULL; - sysfs_remove_group(&tp->pdev->dev.kobj, &tg3_group); - } -#endif -} - -static void tg3_hwmon_open(struct tg3 *tp) -{ -#if IS_ENABLED(CONFIG_HWMON) - int i, err; - u32 size = 0; - struct pci_dev *pdev = tp->pdev; - struct tg3_ocir ocirs[TG3_SD_NUM_RECS]; - - tg3_sd_scan_scratchpad(tp, ocirs); - - for (i = 0; i < TG3_SD_NUM_RECS; i++) { - if (!ocirs[i].src_data_length) - continue; - - size += ocirs[i].src_hdr_length; - size += ocirs[i].src_data_length; - } - - if (!size) - return; - - /* Register hwmon sysfs hooks */ - err = sysfs_create_group(&pdev->dev.kobj, &tg3_group); - if (err) { - dev_err(&pdev->dev, "Cannot create sysfs group, aborting\n"); - return; - } - - tp->hwmon_dev = hwmon_device_register(&pdev->dev); - if (IS_ERR(tp->hwmon_dev)) { - tp->hwmon_dev = NULL; - dev_err(&pdev->dev, "Cannot register hwmon device, aborting\n"); - sysfs_remove_group(&pdev->dev.kobj, &tg3_group); - } -#endif -} - - #define TG3_STAT_ADD32(PSTAT, REG) \ do { u32 __val = tr32(REG); \ (PSTAT)->low += __val; \ @@ -10297,8 +10102,6 @@ static int tg3_open(struct net_device *dev) tg3_phy_start(tp); - tg3_hwmon_open(tp); - tg3_full_lock(tp, 0); tg3_timer_start(tp); @@ -10348,8 +10151,6 @@ static int tg3_close(struct net_device *dev) tg3_timer_stop(tp); - tg3_hwmon_close(tp); - tg3_phy_stop(tp); tg3_full_lock(tp, 1); @@ -14057,9 +13858,14 @@ static void __devinit tg3_read_mgmtfw_ver(struct tg3 *tp) } } -static void __devinit tg3_probe_ncsi(struct tg3 *tp) +static void __devinit tg3_read_dash_ver(struct tg3 *tp) { + int vlen; u32 apedata; + char *fwtype; + + if (!tg3_flag(tp, ENABLE_APE) || !tg3_flag(tp, ENABLE_ASF)) + return; apedata = tg3_ape_read32(tp, TG3_APE_SEG_SIG); if (apedata != APE_SEG_SIG_MAGIC) @@ -14069,22 +13875,14 @@ static void __devinit tg3_probe_ncsi(struct tg3 *tp) if (!(apedata & APE_FW_STATUS_READY)) return; - if (tg3_ape_read32(tp, TG3_APE_FW_FEATURES) & TG3_APE_FW_FEATURE_NCSI) - tg3_flag_set(tp, APE_HAS_NCSI); -} - -static void __devinit tg3_read_dash_ver(struct tg3 *tp) -{ - int vlen; - u32 apedata; - char *fwtype; - apedata = tg3_ape_read32(tp, TG3_APE_FW_VERSION); - if (tg3_flag(tp, APE_HAS_NCSI)) + if (tg3_ape_read32(tp, TG3_APE_FW_FEATURES) & TG3_APE_FW_FEATURE_NCSI) { + tg3_flag_set(tp, APE_HAS_NCSI); fwtype = "NCSI"; - else + } else { fwtype = "DASH"; + } vlen = strlen(tp->fw_ver); @@ -14118,17 +13916,20 @@ static void __devinit tg3_read_fw_ver(struct tg3 *tp) tg3_read_sb_ver(tp, val); else if ((val & TG3_EEPROM_MAGIC_HW_MSK) == TG3_EEPROM_MAGIC_HW) tg3_read_hwsb_ver(tp); + else + return; - if (tg3_flag(tp, ENABLE_ASF)) { - if (tg3_flag(tp, ENABLE_APE)) { - tg3_probe_ncsi(tp); - if (!vpd_vers) - tg3_read_dash_ver(tp); - } else if (!vpd_vers) { - tg3_read_mgmtfw_ver(tp); - } + if (vpd_vers) + goto done; + + if (tg3_flag(tp, ENABLE_APE)) { + if (tg3_flag(tp, ENABLE_ASF)) + tg3_read_dash_ver(tp); + } else if (tg3_flag(tp, ENABLE_ASF)) { + tg3_read_mgmtfw_ver(tp); } +done: tp->fw_ver[TG3_VER_SIZE - 1] = 0; } diff --git a/trunk/drivers/net/ethernet/broadcom/tg3.h b/trunk/drivers/net/ethernet/broadcom/tg3.h index a1b75cd67b9d..93865f899a4f 100644 --- a/trunk/drivers/net/ethernet/broadcom/tg3.h +++ b/trunk/drivers/net/ethernet/broadcom/tg3.h @@ -2311,11 +2311,10 @@ #define APE_LOCK_REQ_DRIVER 0x00001000 #define TG3_APE_LOCK_GRANT 0x004c #define APE_LOCK_GRANT_DRIVER 0x00001000 - -/* APE shared memory. Accessible through BAR1 */ -#define TG3_APE_SHMEM_BASE 0x4000 #define TG3_APE_SEG_SIG 0x4000 #define APE_SEG_SIG_MAGIC 0x41504521 + +/* APE shared memory. Accessible through BAR1 */ #define TG3_APE_FW_STATUS 0x400c #define APE_FW_STATUS_READY 0x00000100 #define TG3_APE_FW_FEATURES 0x4010 @@ -2328,8 +2327,6 @@ #define APE_FW_VERSION_REVMSK 0x0000ff00 #define APE_FW_VERSION_REVSFT 8 #define APE_FW_VERSION_BLDMSK 0x000000ff -#define TG3_APE_SEG_MSG_BUF_OFF 0x401c -#define TG3_APE_SEG_MSG_BUF_LEN 0x4020 #define TG3_APE_HOST_SEG_SIG 0x4200 #define APE_HOST_SEG_SIG_MAGIC 0x484f5354 #define TG3_APE_HOST_SEG_LEN 0x4204 @@ -2356,8 +2353,6 @@ #define APE_EVENT_STATUS_DRIVER_EVNT 0x00000010 #define APE_EVENT_STATUS_STATE_CHNGE 0x00000500 -#define APE_EVENT_STATUS_SCRTCHPD_READ 0x00001600 -#define APE_EVENT_STATUS_SCRTCHPD_WRITE 0x00001700 #define APE_EVENT_STATUS_STATE_START 0x00010000 #define APE_EVENT_STATUS_STATE_UNLOAD 0x00020000 #define APE_EVENT_STATUS_STATE_WOL 0x00030000 @@ -2676,40 +2671,6 @@ struct tg3_hw_stats { u8 __reserved4[0xb00-0x9c8]; }; -#define TG3_SD_NUM_RECS 3 -#define TG3_OCIR_LEN (sizeof(struct tg3_ocir)) -#define TG3_OCIR_SIG_MAGIC 0x5253434f -#define TG3_OCIR_FLAG_ACTIVE 0x00000001 - -#define TG3_TEMP_CAUTION_OFFSET 0xc8 -#define TG3_TEMP_MAX_OFFSET 0xcc -#define TG3_TEMP_SENSOR_OFFSET 0xd4 - - -struct tg3_ocir { - u32 signature; - u16 version_flags; - u16 refresh_int; - u32 refresh_tmr; - u32 update_tmr; - u32 dst_base_addr; - u16 src_hdr_offset; - u16 src_hdr_length; - u16 src_data_offset; - u16 src_data_length; - u16 dst_hdr_offset; - u16 dst_data_offset; - u16 dst_reg_upd_offset; - u16 dst_sem_offset; - u32 reserved1[2]; - u32 port0_flags; - u32 port1_flags; - u32 port2_flags; - u32 port3_flags; - u32 reserved2[1]; -}; - - /* 'mapping' is superfluous as the chip does not write into * the tx/rx post rings so we could just fetch it from there. * But the cache behavior is better how we are doing it now. @@ -3245,10 +3206,6 @@ struct tg3 { const char *fw_needed; const struct firmware *fw; u32 fw_len; /* includes BSS */ - -#if IS_ENABLED(CONFIG_HWMON) - struct device *hwmon_dev; -#endif }; #endif /* !(_T3_H) */ diff --git a/trunk/drivers/net/ethernet/emulex/benet/be.h b/trunk/drivers/net/ethernet/emulex/benet/be.h index d266c86a53f7..330d59af0576 100644 --- a/trunk/drivers/net/ethernet/emulex/benet/be.h +++ b/trunk/drivers/net/ethernet/emulex/benet/be.h @@ -34,7 +34,7 @@ #include "be_hw.h" #include "be_roce.h" -#define DRV_VER "4.4.31.0u" +#define DRV_VER "4.2.248.0u" #define DRV_NAME "be2net" #define BE_NAME "ServerEngines BladeEngine2 10Gbps NIC" #define BE3_NAME "ServerEngines BladeEngine3 10Gbps NIC" diff --git a/trunk/drivers/net/ethernet/emulex/benet/be_cmds.h b/trunk/drivers/net/ethernet/emulex/benet/be_cmds.h index d5a4dedf1132..45d70def92d6 100644 --- a/trunk/drivers/net/ethernet/emulex/benet/be_cmds.h +++ b/trunk/drivers/net/ethernet/emulex/benet/be_cmds.h @@ -1082,18 +1082,8 @@ struct be_cmd_resp_query_fw_cfg { u32 function_caps; }; -/******************** RSS Config ****************************************/ -/* RSS type Input parameters used to compute RX hash - * RSS_ENABLE_IPV4 SRC IPv4, DST IPv4 - * RSS_ENABLE_TCP_IPV4 SRC IPv4, DST IPv4, TCP SRC PORT, TCP DST PORT - * RSS_ENABLE_IPV6 SRC IPv6, DST IPv6 - * RSS_ENABLE_TCP_IPV6 SRC IPv6, DST IPv6, TCP SRC PORT, TCP DST PORT - * RSS_ENABLE_UDP_IPV4 SRC IPv4, DST IPv4, UDP SRC PORT, UDP DST PORT - * RSS_ENABLE_UDP_IPV6 SRC IPv6, DST IPv6, UDP SRC PORT, UDP DST PORT - * - * When multiple RSS types are enabled, HW picks the best hash policy - * based on the type of the received packet. - */ +/******************** RSS Config *******************/ +/* RSS types */ #define RSS_ENABLE_NONE 0x0 #define RSS_ENABLE_IPV4 0x1 #define RSS_ENABLE_TCP_IPV4 0x2 diff --git a/trunk/drivers/net/ethernet/emulex/benet/be_main.c b/trunk/drivers/net/ethernet/emulex/benet/be_main.c index f18375cd75ee..7e989d06523f 100644 --- a/trunk/drivers/net/ethernet/emulex/benet/be_main.c +++ b/trunk/drivers/net/ethernet/emulex/benet/be_main.c @@ -1228,16 +1228,16 @@ static void skb_fill_rx_data(struct be_rx_obj *rxo, struct sk_buff *skb, /* Copy data in the first descriptor of this completion */ curr_frag_len = min(rxcp->pkt_size, rx_frag_size); + /* Copy the header portion into skb_data */ + hdr_len = min(BE_HDR_LEN, curr_frag_len); + memcpy(skb->data, start, hdr_len); skb->len = curr_frag_len; if (curr_frag_len <= BE_HDR_LEN) { /* tiny packet */ - memcpy(skb->data, start, curr_frag_len); /* Complete packet has now been moved to data */ put_page(page_info->page); skb->data_len = 0; skb->tail += curr_frag_len; } else { - hdr_len = ETH_HLEN; - memcpy(skb->data, start, hdr_len); skb_shinfo(skb)->nr_frags = 1; skb_frag_set_page(skb, 0, page_info->page); skb_shinfo(skb)->frags[0].page_offset = diff --git a/trunk/drivers/net/ethernet/ethoc.c b/trunk/drivers/net/ethernet/ethoc.c index 94b7bfcdb24e..20297881f8eb 100644 --- a/trunk/drivers/net/ethernet/ethoc.c +++ b/trunk/drivers/net/ethernet/ethoc.c @@ -1057,7 +1057,7 @@ static int __devinit ethoc_probe(struct platform_device *pdev) /* Check the MAC again for validity, if it still isn't choose and * program a random one. */ if (!is_valid_ether_addr(netdev->dev_addr)) { - eth_random_addr(netdev->dev_addr); + random_ether_addr(netdev->dev_addr); random_mac = true; } diff --git a/trunk/drivers/net/ethernet/intel/e1000e/82571.c b/trunk/drivers/net/ethernet/intel/e1000e/82571.c index 19f4cb9582b5..36db4df09aed 100644 --- a/trunk/drivers/net/ethernet/intel/e1000e/82571.c +++ b/trunk/drivers/net/ethernet/intel/e1000e/82571.c @@ -1677,18 +1677,16 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw) e_dbg("ANYSTATE -> DOWN\n"); } else { /* - * Check several times, if SYNCH bit and CONFIG - * bit both are consistently 1 then simply ignore - * the IV bit and restart Autoneg + * Check several times, if Sync and Config + * both are consistently 1 then simply ignore + * the Invalid bit and restart Autoneg */ for (i = 0; i < AN_RETRY_COUNT; i++) { udelay(10); rxcw = er32(RXCW); - if ((rxcw & E1000_RXCW_SYNCH) && - (rxcw & E1000_RXCW_C)) - continue; - - if (rxcw & E1000_RXCW_IV) { + if ((rxcw & E1000_RXCW_IV) && + !((rxcw & E1000_RXCW_SYNCH) && + (rxcw & E1000_RXCW_C))) { mac->serdes_has_link = false; mac->serdes_link_state = e1000_serdes_link_down; diff --git a/trunk/drivers/net/ethernet/intel/e1000e/e1000.h b/trunk/drivers/net/ethernet/intel/e1000e/e1000.h index cd153326c3cf..6e6fffb34581 100644 --- a/trunk/drivers/net/ethernet/intel/e1000e/e1000.h +++ b/trunk/drivers/net/ethernet/intel/e1000e/e1000.h @@ -514,7 +514,6 @@ extern void e1000e_set_interrupt_capability(struct e1000_adapter *adapter); extern void e1000e_reset_interrupt_capability(struct e1000_adapter *adapter); extern void e1000e_get_hw_control(struct e1000_adapter *adapter); extern void e1000e_release_hw_control(struct e1000_adapter *adapter); -extern void e1000e_write_itr(struct e1000_adapter *adapter, u32 itr); extern unsigned int copybreak; diff --git a/trunk/drivers/net/ethernet/intel/e1000e/ethtool.c b/trunk/drivers/net/ethernet/intel/e1000e/ethtool.c index 105d554ea9db..905e2147d918 100644 --- a/trunk/drivers/net/ethernet/intel/e1000e/ethtool.c +++ b/trunk/drivers/net/ethernet/intel/e1000e/ethtool.c @@ -1897,6 +1897,7 @@ static int e1000_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *ec) { struct e1000_adapter *adapter = netdev_priv(netdev); + struct e1000_hw *hw = &adapter->hw; if ((ec->rx_coalesce_usecs > E1000_MAX_ITR_USECS) || ((ec->rx_coalesce_usecs > 4) && @@ -1915,9 +1916,9 @@ static int e1000_set_coalesce(struct net_device *netdev, } if (adapter->itr_setting != 0) - e1000e_write_itr(adapter, adapter->itr); + ew32(ITR, 1000000000 / (adapter->itr * 256)); else - e1000e_write_itr(adapter, 0); + ew32(ITR, 0); return 0; } diff --git a/trunk/drivers/net/ethernet/intel/e1000e/netdev.c b/trunk/drivers/net/ethernet/intel/e1000e/netdev.c index 95b245310f17..ca477e87eb87 100644 --- a/trunk/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/trunk/drivers/net/ethernet/intel/e1000e/netdev.c @@ -2473,30 +2473,6 @@ static void e1000_set_itr(struct e1000_adapter *adapter) } } -/** - * e1000e_write_itr - write the ITR value to the appropriate registers - * @adapter: address of board private structure - * @itr: new ITR value to program - * - * e1000e_write_itr determines if the adapter is in MSI-X mode - * and, if so, writes the EITR registers with the ITR value. - * Otherwise, it writes the ITR value into the ITR register. - **/ -void e1000e_write_itr(struct e1000_adapter *adapter, u32 itr) -{ - struct e1000_hw *hw = &adapter->hw; - u32 new_itr = itr ? 1000000000 / (itr * 256) : 0; - - if (adapter->msix_entries) { - int vector; - - for (vector = 0; vector < adapter->num_vectors; vector++) - writel(new_itr, hw->hw_addr + E1000_EITR_82574(vector)); - } else { - ew32(ITR, new_itr); - } -} - /** * e1000_alloc_queues - Allocate memory for all rings * @adapter: board private structure to initialize @@ -3083,7 +3059,7 @@ static void e1000_configure_rx(struct e1000_adapter *adapter) /* irq moderation */ ew32(RADV, adapter->rx_abs_int_delay); if ((adapter->itr_setting != 0) && (adapter->itr != 0)) - e1000e_write_itr(adapter, adapter->itr); + ew32(ITR, 1000000000 / (adapter->itr * 256)); ctrl_ext = er32(CTRL_EXT); /* Auto-Mask interrupts upon ICR access */ @@ -3510,14 +3486,14 @@ void e1000e_reset(struct e1000_adapter *adapter) dev_info(&adapter->pdev->dev, "Interrupt Throttle Rate turned off\n"); adapter->flags2 |= FLAG2_DISABLE_AIM; - e1000e_write_itr(adapter, 0); + ew32(ITR, 0); } } else if (adapter->flags2 & FLAG2_DISABLE_AIM) { dev_info(&adapter->pdev->dev, "Interrupt Throttle Rate turned on\n"); adapter->flags2 &= ~FLAG2_DISABLE_AIM; adapter->itr = 20000; - e1000e_write_itr(adapter, adapter->itr); + ew32(ITR, 1000000000 / (adapter->itr * 256)); } } @@ -4600,7 +4576,7 @@ static void e1000_watchdog_task(struct work_struct *work) adapter->gorc - adapter->gotc) / 10000; u32 itr = goc > 0 ? (dif * 6000 / goc + 2000) : 8000; - e1000e_write_itr(adapter, itr); + ew32(ITR, 1000000000 / (itr * 256)); } /* Cause software interrupt to ensure Rx ring is cleaned */ diff --git a/trunk/drivers/net/ethernet/intel/igb/igb_main.c b/trunk/drivers/net/ethernet/intel/igb/igb_main.c index 8adeca9787ca..60e307548f4e 100644 --- a/trunk/drivers/net/ethernet/intel/igb/igb_main.c +++ b/trunk/drivers/net/ethernet/intel/igb/igb_main.c @@ -5008,7 +5008,7 @@ static int igb_vf_configure(struct igb_adapter *adapter, int vf) unsigned int device_id; u16 thisvf_devfn; - eth_random_addr(mac_addr); + random_ether_addr(mac_addr); igb_set_vf_mac(adapter, vf, mac_addr); switch (adapter->hw.mac.type) { @@ -5417,7 +5417,7 @@ static void igb_vf_reset_event(struct igb_adapter *adapter, u32 vf) /* generate a new mac address as we were hotplug removed/added */ if (!(adapter->vf_data[vf].flags & IGB_VF_FLAG_PF_SET_MAC)) - eth_random_addr(vf_mac); + random_ether_addr(vf_mac); /* process remaining reset events */ igb_vf_reset(adapter, vf); diff --git a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe.h index 5a75a9c8b813..2ffdc8f4c276 100644 --- a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe.h +++ b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe.h @@ -707,7 +707,6 @@ extern u8 ixgbe_fcoe_setapp(struct ixgbe_adapter *adapter, u8 up); extern int ixgbe_fcoe_get_wwn(struct net_device *netdev, u64 *wwn, int type); extern int ixgbe_fcoe_get_hbainfo(struct net_device *netdev, struct netdev_fcoe_hbainfo *info); -extern u8 ixgbe_fcoe_get_tc(struct ixgbe_adapter *adapter); #endif /* IXGBE_FCOE */ static inline struct netdev_queue *txring_txq(const struct ixgbe_ring *ring) diff --git a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb.c b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb.c index 5442b359141e..8bfaaee5ac5b 100644 --- a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb.c +++ b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb.c @@ -180,79 +180,67 @@ s32 ixgbe_dcb_calculate_tc_credits(struct ixgbe_hw *hw, void ixgbe_dcb_unpack_pfc(struct ixgbe_dcb_config *cfg, u8 *pfc_en) { - struct tc_configuration *tc_config = &cfg->tc_config[0]; - int tc; + int i; - for (*pfc_en = 0, tc = 0; tc < MAX_TRAFFIC_CLASS; tc++) { - if (tc_config[tc].dcb_pfc != pfc_disabled) - *pfc_en |= 1 << tc; - } + *pfc_en = 0; + for (i = 0; i < MAX_TRAFFIC_CLASS; i++) + *pfc_en |= !!(cfg->tc_config[i].dcb_pfc & 0xF) << i; } void ixgbe_dcb_unpack_refill(struct ixgbe_dcb_config *cfg, int direction, u16 *refill) { - struct tc_configuration *tc_config = &cfg->tc_config[0]; - int tc; + struct tc_bw_alloc *p; + int i; - for (tc = 0; tc < MAX_TRAFFIC_CLASS; tc++) - refill[tc] = tc_config[tc].path[direction].data_credits_refill; + for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { + p = &cfg->tc_config[i].path[direction]; + refill[i] = p->data_credits_refill; + } } void ixgbe_dcb_unpack_max(struct ixgbe_dcb_config *cfg, u16 *max) { - struct tc_configuration *tc_config = &cfg->tc_config[0]; - int tc; + int i; - for (tc = 0; tc < MAX_TRAFFIC_CLASS; tc++) - max[tc] = tc_config[tc].desc_credits_max; + for (i = 0; i < MAX_TRAFFIC_CLASS; i++) + max[i] = cfg->tc_config[i].desc_credits_max; } void ixgbe_dcb_unpack_bwgid(struct ixgbe_dcb_config *cfg, int direction, u8 *bwgid) { - struct tc_configuration *tc_config = &cfg->tc_config[0]; - int tc; + struct tc_bw_alloc *p; + int i; - for (tc = 0; tc < MAX_TRAFFIC_CLASS; tc++) - bwgid[tc] = tc_config[tc].path[direction].bwg_id; + for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { + p = &cfg->tc_config[i].path[direction]; + bwgid[i] = p->bwg_id; + } } void ixgbe_dcb_unpack_prio(struct ixgbe_dcb_config *cfg, int direction, u8 *ptype) { - struct tc_configuration *tc_config = &cfg->tc_config[0]; - int tc; - - for (tc = 0; tc < MAX_TRAFFIC_CLASS; tc++) - ptype[tc] = tc_config[tc].path[direction].prio_type; -} - -u8 ixgbe_dcb_get_tc_from_up(struct ixgbe_dcb_config *cfg, int direction, u8 up) -{ - struct tc_configuration *tc_config = &cfg->tc_config[0]; - u8 prio_mask = 1 << up; - u8 tc; + struct tc_bw_alloc *p; + int i; - /* - * Test for TCs 7 through 1 and report the first match we find. If - * we find no match we can assume that the TC is 0 since the TC must - * be set for all user priorities - */ - for (tc = MAX_TRAFFIC_CLASS - 1; tc; tc--) { - if (prio_mask & tc_config[tc].path[direction].up_to_tc_bitmap) - break; + for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { + p = &cfg->tc_config[i].path[direction]; + ptype[i] = p->prio_type; } - - return tc; } void ixgbe_dcb_unpack_map(struct ixgbe_dcb_config *cfg, int direction, u8 *map) { - u8 up; + int i, up; + unsigned long bitmap; - for (up = 0; up < MAX_USER_PRIORITY; up++) - map[up] = ixgbe_dcb_get_tc_from_up(cfg, direction, up); + for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { + bitmap = cfg->tc_config[i].path[direction].up_to_tc_bitmap; + for_each_set_bit(up, &bitmap, MAX_USER_PRIORITY) + map[up] = i; + } } /** diff --git a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb.h b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb.h index 1f4108ee154b..24333b718166 100644 --- a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb.h +++ b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb.h @@ -146,7 +146,6 @@ void ixgbe_dcb_unpack_max(struct ixgbe_dcb_config *, u16 *); void ixgbe_dcb_unpack_bwgid(struct ixgbe_dcb_config *, int, u8 *); void ixgbe_dcb_unpack_prio(struct ixgbe_dcb_config *, int, u8 *); void ixgbe_dcb_unpack_map(struct ixgbe_dcb_config *, int, u8 *); -u8 ixgbe_dcb_get_tc_from_up(struct ixgbe_dcb_config *, int, u8); /* DCB credits calculation */ s32 ixgbe_dcb_calculate_tc_credits(struct ixgbe_hw *, diff --git a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c index f1e002d5fa8f..5164a21b13ca 100644 --- a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c +++ b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c @@ -151,21 +151,34 @@ static u8 ixgbe_dcbnl_get_state(struct net_device *netdev) static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state) { - struct ixgbe_adapter *adapter = netdev_priv(netdev); int err = 0; + u8 prio_tc[MAX_USER_PRIORITY] = {0}; + int i; + struct ixgbe_adapter *adapter = netdev_priv(netdev); /* Fail command if not in CEE mode */ if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_CEE)) return 1; /* verify there is something to do, if not then exit */ - if (!state == !(adapter->flags & IXGBE_FLAG_DCB_ENABLED)) + if (!!state != !(adapter->flags & IXGBE_FLAG_DCB_ENABLED)) + goto out; + + if (state > 0) { + err = ixgbe_setup_tc(netdev, adapter->dcb_cfg.num_tcs.pg_tcs); + ixgbe_dcb_unpack_map(&adapter->dcb_cfg, DCB_TX_CONFIG, prio_tc); + } else { + err = ixgbe_setup_tc(netdev, 0); + } + + if (err) goto out; - err = ixgbe_setup_tc(netdev, - state ? adapter->dcb_cfg.num_tcs.pg_tcs : 0); + for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) + netdev_set_prio_tc_map(netdev, i, prio_tc[i]); + out: - return !!err; + return err ? 1 : 0; } static void ixgbe_dcbnl_get_perm_hw_addr(struct net_device *netdev, @@ -571,6 +584,9 @@ static int ixgbe_dcbnl_ieee_setets(struct net_device *dev, if (err) goto err_out; + for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) + netdev_set_prio_tc_map(dev, i, ets->prio_tc[i]); + err = ixgbe_dcb_hw_ets(&adapter->hw, ets, max_frame); err_out: return err; diff --git a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c index cc28c44a048c..0922ece4d853 100644 --- a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c +++ b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c @@ -960,18 +960,3 @@ int ixgbe_fcoe_get_hbainfo(struct net_device *netdev, return 0; } - -/** - * ixgbe_fcoe_get_tc - get the current TC that fcoe is mapped to - * @adapter - pointer to the device adapter structure - * - * Return : TC that FCoE is mapped to - */ -u8 ixgbe_fcoe_get_tc(struct ixgbe_adapter *adapter) -{ -#ifdef CONFIG_IXGBE_DCB - return netdev_get_prio_tc_map(adapter->netdev, adapter->fcoe.up); -#else - return 0; -#endif -} diff --git a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c index d308e7140171..83eadd019e6b 100644 --- a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c +++ b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c @@ -28,7 +28,29 @@ #include "ixgbe.h" #include "ixgbe_sriov.h" +/** + * ixgbe_cache_ring_rss - Descriptor ring to register mapping for RSS + * @adapter: board private structure to initialize + * + * Cache the descriptor ring offsets for RSS to the assigned rings. + * + **/ +static inline bool ixgbe_cache_ring_rss(struct ixgbe_adapter *adapter) +{ + int i; + + if (!(adapter->flags & IXGBE_FLAG_RSS_ENABLED)) + return false; + + for (i = 0; i < adapter->num_rx_queues; i++) + adapter->rx_ring[i]->reg_idx = i; + for (i = 0; i < adapter->num_tx_queues; i++) + adapter->tx_ring[i]->reg_idx = i; + + return true; +} #ifdef CONFIG_IXGBE_DCB + /* ixgbe_get_first_reg_idx - Return first register index associated with ring */ static void ixgbe_get_first_reg_idx(struct ixgbe_adapter *adapter, u8 tc, unsigned int *tx, unsigned int *rx) @@ -114,8 +136,39 @@ static inline bool ixgbe_cache_ring_dcb(struct ixgbe_adapter *adapter) return true; } - #endif + +#ifdef IXGBE_FCOE +/** + * ixgbe_cache_ring_fcoe - Descriptor ring to register mapping for the FCoE + * @adapter: board private structure to initialize + * + * Cache the descriptor ring offsets for FCoE mode to the assigned rings. + * + */ +static inline bool ixgbe_cache_ring_fcoe(struct ixgbe_adapter *adapter) +{ + struct ixgbe_ring_feature *f = &adapter->ring_feature[RING_F_FCOE]; + int i; + u8 fcoe_rx_i = 0, fcoe_tx_i = 0; + + if (!(adapter->flags & IXGBE_FLAG_FCOE_ENABLED)) + return false; + + if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) { + ixgbe_cache_ring_rss(adapter); + + fcoe_rx_i = f->offset; + fcoe_tx_i = f->offset; + } + for (i = 0; i < f->indices; i++, fcoe_rx_i++, fcoe_tx_i++) { + adapter->rx_ring[f->offset + i]->reg_idx = fcoe_rx_i; + adapter->tx_ring[f->offset + i]->reg_idx = fcoe_tx_i; + } + return true; +} + +#endif /* IXGBE_FCOE */ /** * ixgbe_cache_ring_sriov - Descriptor ring to register mapping for sriov * @adapter: board private structure to initialize @@ -134,28 +187,6 @@ static inline bool ixgbe_cache_ring_sriov(struct ixgbe_adapter *adapter) return false; } -/** - * ixgbe_cache_ring_rss - Descriptor ring to register mapping for RSS - * @adapter: board private structure to initialize - * - * Cache the descriptor ring offsets for RSS to the assigned rings. - * - **/ -static bool ixgbe_cache_ring_rss(struct ixgbe_adapter *adapter) -{ - int i; - - if (!(adapter->flags & IXGBE_FLAG_RSS_ENABLED)) - return false; - - for (i = 0; i < adapter->num_rx_queues; i++) - adapter->rx_ring[i]->reg_idx = i; - for (i = 0; i < adapter->num_tx_queues; i++) - adapter->tx_ring[i]->reg_idx = i; - - return true; -} - /** * ixgbe_cache_ring_register - Descriptor ring to register mapping * @adapter: board private structure to initialize @@ -181,7 +212,13 @@ static void ixgbe_cache_ring_register(struct ixgbe_adapter *adapter) return; #endif - ixgbe_cache_ring_rss(adapter); +#ifdef IXGBE_FCOE + if (ixgbe_cache_ring_fcoe(adapter)) + return; +#endif /* IXGBE_FCOE */ + + if (ixgbe_cache_ring_rss(adapter)) + return; } /** @@ -197,74 +234,6 @@ static inline bool ixgbe_set_sriov_queues(struct ixgbe_adapter *adapter) return false; } -#define IXGBE_RSS_16Q_MASK 0xF -#define IXGBE_RSS_8Q_MASK 0x7 -#define IXGBE_RSS_4Q_MASK 0x3 -#define IXGBE_RSS_2Q_MASK 0x1 -#define IXGBE_RSS_DISABLED_MASK 0x0 - -#ifdef CONFIG_IXGBE_DCB -static bool ixgbe_set_dcb_queues(struct ixgbe_adapter *adapter) -{ - struct net_device *dev = adapter->netdev; - struct ixgbe_ring_feature *f; - int rss_i, rss_m, i; - int tcs; - - /* Map queue offset and counts onto allocated tx queues */ - tcs = netdev_get_num_tc(dev); - - /* verify we have DCB queueing enabled before proceeding */ - if (tcs <= 1) - return false; - - /* determine the upper limit for our current DCB mode */ - rss_i = dev->num_tx_queues / tcs; - if (adapter->hw.mac.type == ixgbe_mac_82598EB) { - /* 8 TC w/ 4 queues per TC */ - rss_i = min_t(u16, rss_i, 4); - rss_m = IXGBE_RSS_4Q_MASK; - } else if (tcs > 4) { - /* 8 TC w/ 8 queues per TC */ - rss_i = min_t(u16, rss_i, 8); - rss_m = IXGBE_RSS_8Q_MASK; - } else { - /* 4 TC w/ 16 queues per TC */ - rss_i = min_t(u16, rss_i, 16); - rss_m = IXGBE_RSS_16Q_MASK; - } - - /* set RSS mask and indices */ - f = &adapter->ring_feature[RING_F_RSS]; - rss_i = min_t(int, rss_i, f->limit); - f->indices = rss_i; - f->mask = rss_m; - -#ifdef IXGBE_FCOE - /* FCoE enabled queues require special configuration indexed - * by feature specific indices and offset. Here we map FCoE - * indices onto the DCB queue pairs allowing FCoE to own - * configuration later. - */ - if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) { - u8 tc = ixgbe_fcoe_get_tc(adapter); - - f = &adapter->ring_feature[RING_F_FCOE]; - f->indices = min_t(u16, rss_i, f->limit); - f->offset = rss_i * tc; - } - -#endif /* IXGBE_FCOE */ - for (i = 0; i < tcs; i++) - netdev_set_tc_queue(dev, i, rss_i, rss_i * i); - - adapter->num_tx_queues = rss_i * tcs; - adapter->num_rx_queues = rss_i * tcs; - - return true; -} - -#endif /** * ixgbe_set_rss_queues - Allocate queues for RSS * @adapter: board private structure to initialize @@ -288,7 +257,7 @@ static bool ixgbe_set_rss_queues(struct ixgbe_adapter *adapter) rss_i = f->limit; f->indices = rss_i; - f->mask = IXGBE_RSS_16Q_MASK; + f->mask = 0xF; /* * Use Flow Director in addition to RSS to ensure the best @@ -302,41 +271,93 @@ static bool ixgbe_set_rss_queues(struct ixgbe_adapter *adapter) rss_i = max_t(u16, rss_i, f->indices); } + adapter->num_rx_queues = rss_i; + adapter->num_tx_queues = rss_i; + + return true; +} + #ifdef IXGBE_FCOE - /* - * FCoE can exist on the same rings as standard network traffic - * however it is preferred to avoid that if possible. In order - * to get the best performance we allocate as many FCoE queues - * as we can and we place them at the end of the ring array to - * avoid sharing queues with standard RSS on systems with 24 or - * more CPUs. - */ - if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) { - struct net_device *dev = adapter->netdev; - u16 fcoe_i; +/** + * ixgbe_set_fcoe_queues - Allocate queues for Fiber Channel over Ethernet (FCoE) + * @adapter: board private structure to initialize + * + * FCoE RX FCRETA can use up to 8 rx queues for up to 8 different exchanges. + * Offset is used as the index of the first rx queue used by FCoE. + **/ +static inline bool ixgbe_set_fcoe_queues(struct ixgbe_adapter *adapter) +{ + struct ixgbe_ring_feature *f = &adapter->ring_feature[RING_F_FCOE]; - f = &adapter->ring_feature[RING_F_FCOE]; + if (!(adapter->flags & IXGBE_FLAG_FCOE_ENABLED)) + return false; - /* merge FCoE queues with RSS queues */ - fcoe_i = min_t(u16, f->limit + rss_i, num_online_cpus()); - fcoe_i = min_t(u16, fcoe_i, dev->num_tx_queues); + f->indices = min_t(int, num_online_cpus(), f->limit); - /* limit indices to rss_i if MSI-X is disabled */ - if (!(adapter->flags & IXGBE_FLAG_MSIX_ENABLED)) - fcoe_i = rss_i; + adapter->num_rx_queues = 1; + adapter->num_tx_queues = 1; - /* attempt to reserve some queues for just FCoE */ - f->indices = min_t(u16, fcoe_i, f->limit); - f->offset = fcoe_i - f->indices; - rss_i = max_t(u16, fcoe_i, rss_i); + if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) { + e_info(probe, "FCoE enabled with RSS\n"); + ixgbe_set_rss_queues(adapter); } + /* adding FCoE rx rings to the end */ + f->offset = adapter->num_rx_queues; + adapter->num_rx_queues += f->indices; + adapter->num_tx_queues += f->indices; + + return true; +} #endif /* IXGBE_FCOE */ - adapter->num_rx_queues = rss_i; - adapter->num_tx_queues = rss_i; + +/* Artificial max queue cap per traffic class in DCB mode */ +#define DCB_QUEUE_CAP 8 + +#ifdef CONFIG_IXGBE_DCB +static inline bool ixgbe_set_dcb_queues(struct ixgbe_adapter *adapter) +{ + int per_tc_q, q, i, offset = 0; + struct net_device *dev = adapter->netdev; + int tcs = netdev_get_num_tc(dev); + + if (!tcs) + return false; + + /* Map queue offset and counts onto allocated tx queues */ + per_tc_q = min_t(unsigned int, dev->num_tx_queues / tcs, DCB_QUEUE_CAP); + q = min_t(int, num_online_cpus(), per_tc_q); + + for (i = 0; i < tcs; i++) { + netdev_set_tc_queue(dev, i, q, offset); + offset += q; + } + + adapter->num_tx_queues = q * tcs; + adapter->num_rx_queues = q * tcs; + +#ifdef IXGBE_FCOE + /* FCoE enabled queues require special configuration indexed + * by feature specific indices and offset. Here we map FCoE + * indices onto the DCB queue pairs allowing FCoE to own + * configuration later. + */ + if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) { + u8 prio_tc[MAX_USER_PRIORITY] = {0}; + int tc; + struct ixgbe_ring_feature *f = + &adapter->ring_feature[RING_F_FCOE]; + + ixgbe_dcb_unpack_map(&adapter->dcb_cfg, DCB_TX_CONFIG, prio_tc); + tc = prio_tc[adapter->fcoe.up]; + f->indices = dev->tc_to_txq[tc].count; + f->offset = dev->tc_to_txq[tc].offset; + } +#endif return true; } +#endif /** * ixgbe_set_num_queues - Allocate queues for device, feature dependent @@ -365,6 +386,11 @@ static int ixgbe_set_num_queues(struct ixgbe_adapter *adapter) goto done; #endif +#ifdef IXGBE_FCOE + if (ixgbe_set_fcoe_queues(adapter)) + goto done; + +#endif /* IXGBE_FCOE */ if (ixgbe_set_rss_queues(adapter)) goto done; diff --git a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index ee230f533ee3..d3cf8873d483 100644 --- a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -3610,17 +3610,16 @@ static void ixgbe_configure_dcb(struct ixgbe_adapter *adapter) if (hw->mac.type != ixgbe_mac_82598EB) { int i; u32 reg = 0; - u8 msb = 0; - u8 rss_i = adapter->netdev->tc_to_txq[0].count - 1; - while (rss_i) { - msb++; - rss_i >>= 1; - } + for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { + u8 msb = 0; + u8 cnt = adapter->netdev->tc_to_txq[i].count; - for (i = 0; i < MAX_TRAFFIC_CLASS; i++) - reg |= msb << IXGBE_RQTC_SHIFT_TC(i); + while (cnt >>= 1) + msb++; + reg |= msb << IXGBE_RQTC_SHIFT_TC(i); + } IXGBE_WRITE_REG(hw, IXGBE_RQTC, reg); } } @@ -3647,12 +3646,18 @@ static int ixgbe_hpbthresh(struct ixgbe_adapter *adapter, int pb) #ifdef IXGBE_FCOE /* FCoE traffic class uses FCOE jumbo frames */ - if ((dev->features & NETIF_F_FCOE_MTU) && - (tc < IXGBE_FCOE_JUMBO_FRAME_SIZE) && - (pb == ixgbe_fcoe_get_tc(adapter))) - tc = IXGBE_FCOE_JUMBO_FRAME_SIZE; + if (dev->features & NETIF_F_FCOE_MTU) { + int fcoe_pb = 0; + +#ifdef CONFIG_IXGBE_DCB + fcoe_pb = netdev_get_prio_tc_map(dev, adapter->fcoe.up); #endif + if (fcoe_pb == pb && tc < IXGBE_FCOE_JUMBO_FRAME_SIZE) + tc = IXGBE_FCOE_JUMBO_FRAME_SIZE; + } +#endif + /* Calculate delay value for device */ switch (hw->mac.type) { case ixgbe_mac_X540: @@ -6590,31 +6595,6 @@ static void ixgbe_validate_rtr(struct ixgbe_adapter *adapter, u8 tc) return; } -/** - * ixgbe_set_prio_tc_map - Configure netdev prio tc map - * @adapter: Pointer to adapter struct - * - * Populate the netdev user priority to tc map - */ -static void ixgbe_set_prio_tc_map(struct ixgbe_adapter *adapter) -{ - struct net_device *dev = adapter->netdev; - struct ixgbe_dcb_config *dcb_cfg = &adapter->dcb_cfg; - struct ieee_ets *ets = adapter->ixgbe_ieee_ets; - u8 prio; - - for (prio = 0; prio < MAX_USER_PRIORITY; prio++) { - u8 tc = 0; - - if (adapter->dcbx_cap & DCB_CAP_DCBX_VER_CEE) - tc = ixgbe_dcb_get_tc_from_up(dcb_cfg, 0, prio); - else if (ets) - tc = ets->prio_tc[prio]; - - netdev_set_prio_tc_map(dev, prio, tc); - } -} - /** * ixgbe_setup_tc - configure net_device for multiple traffic classes * @@ -6653,8 +6633,6 @@ int ixgbe_setup_tc(struct net_device *dev, u8 tc) if (tc) { netdev_set_num_tc(dev, tc); - ixgbe_set_prio_tc_map(adapter); - adapter->flags |= IXGBE_FLAG_DCB_ENABLED; adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE; @@ -6664,7 +6642,6 @@ int ixgbe_setup_tc(struct net_device *dev, u8 tc) } } else { netdev_reset_tc(dev); - if (adapter->hw.mac.type == ixgbe_mac_82598EB) adapter->hw.fc.requested_mode = adapter->last_lfc_mode; @@ -7028,11 +7005,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, #endif if (ii->mac == ixgbe_mac_82598EB) -#ifdef CONFIG_IXGBE_DCB - indices = min_t(unsigned int, indices, MAX_TRAFFIC_CLASS * 4); -#else indices = min_t(unsigned int, indices, IXGBE_MAX_RSS_INDICES); -#endif else indices = min_t(unsigned int, indices, IXGBE_MAX_FDIR_INDICES); diff --git a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c index eb3f67c854a7..2d971d18696e 100644 --- a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c +++ b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c @@ -467,7 +467,7 @@ int ixgbe_vf_configuration(struct pci_dev *pdev, unsigned int event_mask) bool enable = ((event_mask & 0x10000000U) != 0); if (enable) { - eth_random_addr(vf_mac_addr); + random_ether_addr(vf_mac_addr); e_info(probe, "IOV: VF %d is enabled MAC %pM\n", vfn, vf_mac_addr); /* diff --git a/trunk/drivers/net/ethernet/intel/ixgbevf/defines.h b/trunk/drivers/net/ethernet/intel/ixgbevf/defines.h index 10cede503fe8..e09a6cc633bb 100644 --- a/trunk/drivers/net/ethernet/intel/ixgbevf/defines.h +++ b/trunk/drivers/net/ethernet/intel/ixgbevf/defines.h @@ -264,9 +264,32 @@ struct ixgbe_adv_tx_context_desc { /* Interrupt register bitmasks */ +/* Extended Interrupt Cause Read */ +#define IXGBE_EICR_RTX_QUEUE 0x0000FFFF /* RTx Queue Interrupt */ +#define IXGBE_EICR_MAILBOX 0x00080000 /* VF to PF Mailbox Interrupt */ +#define IXGBE_EICR_OTHER 0x80000000 /* Interrupt Cause Active */ + +/* Extended Interrupt Cause Set */ +#define IXGBE_EICS_RTX_QUEUE IXGBE_EICR_RTX_QUEUE /* RTx Queue Interrupt */ +#define IXGBE_EICS_MAILBOX IXGBE_EICR_MAILBOX /* VF to PF Mailbox Int */ +#define IXGBE_EICS_OTHER IXGBE_EICR_OTHER /* INT Cause Active */ + +/* Extended Interrupt Mask Set */ +#define IXGBE_EIMS_RTX_QUEUE IXGBE_EICR_RTX_QUEUE /* RTx Queue Interrupt */ +#define IXGBE_EIMS_MAILBOX IXGBE_EICR_MAILBOX /* VF to PF Mailbox Int */ +#define IXGBE_EIMS_OTHER IXGBE_EICR_OTHER /* INT Cause Active */ + +/* Extended Interrupt Mask Clear */ +#define IXGBE_EIMC_RTX_QUEUE IXGBE_EICR_RTX_QUEUE /* RTx Queue Interrupt */ +#define IXGBE_EIMC_MAILBOX IXGBE_EICR_MAILBOX /* VF to PF Mailbox Int */ +#define IXGBE_EIMC_OTHER IXGBE_EICR_OTHER /* INT Cause Active */ + +#define IXGBE_EIMS_ENABLE_MASK ( \ + IXGBE_EIMS_RTX_QUEUE | \ + IXGBE_EIMS_MAILBOX | \ + IXGBE_EIMS_OTHER) + #define IXGBE_EITR_CNT_WDIS 0x80000000 -#define IXGBE_MAX_EITR 0x00000FF8 -#define IXGBE_MIN_EITR 8 /* Error Codes */ #define IXGBE_ERR_INVALID_MAC_ADDR -1 diff --git a/trunk/drivers/net/ethernet/intel/ixgbevf/ethtool.c b/trunk/drivers/net/ethernet/intel/ixgbevf/ethtool.c index 15947c9122e1..e8dddf572d38 100644 --- a/trunk/drivers/net/ethernet/intel/ixgbevf/ethtool.c +++ b/trunk/drivers/net/ethernet/intel/ixgbevf/ethtool.c @@ -43,6 +43,7 @@ #define IXGBE_ALL_RAR_ENTRIES 16 +#ifdef ETHTOOL_GSTATS struct ixgbe_stats { char stat_string[ETH_GSTRING_LEN]; int sizeof_stat; @@ -74,17 +75,21 @@ static const struct ixgbe_stats ixgbe_gstrings_stats[] = { zero_base)}, {"tx_csum_offload_ctxt", IXGBEVF_STAT(hw_csum_tx_good, zero_base, zero_base)}, + {"rx_header_split", IXGBEVF_STAT(rx_hdr_split, zero_base, zero_base)}, }; #define IXGBE_QUEUE_STATS_LEN 0 #define IXGBE_GLOBAL_STATS_LEN ARRAY_SIZE(ixgbe_gstrings_stats) #define IXGBEVF_STATS_LEN (IXGBE_GLOBAL_STATS_LEN + IXGBE_QUEUE_STATS_LEN) +#endif /* ETHTOOL_GSTATS */ +#ifdef ETHTOOL_TEST static const char ixgbe_gstrings_test[][ETH_GSTRING_LEN] = { "Register test (offline)", "Link test (on/offline)" }; #define IXGBE_TEST_LEN (sizeof(ixgbe_gstrings_test) / ETH_GSTRING_LEN) +#endif /* ETHTOOL_TEST */ static int ixgbevf_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) @@ -364,6 +369,7 @@ static int ixgbevf_set_ringparam(struct net_device *netdev, } goto err_tx_ring_setup; } + tx_ring[i].v_idx = adapter->tx_ring[i].v_idx; } memcpy(rx_ring, adapter->rx_ring, @@ -379,6 +385,7 @@ static int ixgbevf_set_ringparam(struct net_device *netdev, } goto err_rx_ring_setup; } + rx_ring[i].v_idx = adapter->rx_ring[i].v_idx; } /* @@ -667,8 +674,10 @@ static int ixgbevf_nway_reset(struct net_device *netdev) { struct ixgbevf_adapter *adapter = netdev_priv(netdev); - if (netif_running(netdev)) - ixgbevf_reinit_locked(adapter); + if (netif_running(netdev)) { + if (!adapter->dev_closed) + ixgbevf_reinit_locked(adapter); + } return 0; } diff --git a/trunk/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h b/trunk/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h index f92daca249f8..0a1b99240d43 100644 --- a/trunk/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h +++ b/trunk/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h @@ -52,10 +52,12 @@ struct ixgbevf_tx_buffer { struct ixgbevf_rx_buffer { struct sk_buff *skb; dma_addr_t dma; + struct page *page; + dma_addr_t page_dma; + unsigned int page_offset; }; struct ixgbevf_ring { - struct ixgbevf_ring *next; struct ixgbevf_adapter *adapter; /* backlink */ void *desc; /* descriptor ring memory */ dma_addr_t dma; /* phys. address of descriptor ring */ @@ -81,9 +83,29 @@ struct ixgbevf_ring { * offset associated with this ring, which is different * for DCB and RSS modes */ +#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) + /* cpu for tx queue */ + int cpu; +#endif + + u64 v_idx; /* maps directly to the index for this ring in the hardware + * vector array, can also be used for finding the bit in EICR + * and friends that represents the vector for this ring */ + + u16 work_limit; /* max work per interrupt */ u16 rx_buf_len; }; +enum ixgbevf_ring_f_enum { + RING_F_NONE = 0, + RING_F_ARRAY_SIZE /* must be last in enum set */ +}; + +struct ixgbevf_ring_feature { + int indices; + int mask; +}; + /* How many Rx Buffers do we bundle into one write to the hardware ? */ #define IXGBEVF_RX_BUFFER_WRITE 16 /* Must be power of 2 */ @@ -98,6 +120,8 @@ struct ixgbevf_ring { #define IXGBEVF_MIN_RXD 64 /* Supported Rx Buffer Sizes */ +#define IXGBEVF_RXBUFFER_64 64 /* Used for packet split */ +#define IXGBEVF_RXBUFFER_128 128 /* Used for packet split */ #define IXGBEVF_RXBUFFER_256 256 /* Used for packet split */ #define IXGBEVF_RXBUFFER_2048 2048 #define IXGBEVF_MAX_RXBUFFER 16384 /* largest size for single descriptor */ @@ -116,42 +140,22 @@ struct ixgbevf_ring { #define IXGBE_TX_FLAGS_VLAN_PRIO_MASK 0x0000e000 #define IXGBE_TX_FLAGS_VLAN_SHIFT 16 -struct ixgbevf_ring_container { - struct ixgbevf_ring *ring; /* pointer to linked list of rings */ - unsigned int total_bytes; /* total bytes processed this int */ - unsigned int total_packets; /* total packets processed this int */ - u8 count; /* total number of rings in vector */ - u8 itr; /* current ITR setting for ring */ -}; - -/* iterator for handling rings in ring container */ -#define ixgbevf_for_each_ring(pos, head) \ - for (pos = (head).ring; pos != NULL; pos = pos->next) - /* MAX_MSIX_Q_VECTORS of these are allocated, * but we only use one per queue-specific vector. */ struct ixgbevf_q_vector { struct ixgbevf_adapter *adapter; - u16 v_idx; /* index of q_vector within array, also used for - * finding the bit in EICR and friends that - * represents the vector for this ring */ - u16 itr; /* Interrupt throttle rate written to EITR */ struct napi_struct napi; - struct ixgbevf_ring_container rx, tx; - char name[IFNAMSIZ + 9]; + DECLARE_BITMAP(rxr_idx, MAX_RX_QUEUES); /* Rx ring indices */ + DECLARE_BITMAP(txr_idx, MAX_TX_QUEUES); /* Tx ring indices */ + u8 rxr_count; /* Rx ring count assigned to this vector */ + u8 txr_count; /* Tx ring count assigned to this vector */ + u8 tx_itr; + u8 rx_itr; + u32 eitr; + int v_idx; /* vector index in list */ }; -/* - * microsecond values for various ITR rates shifted by 2 to fit itr register - * with the first 3 bits reserved 0 - */ -#define IXGBE_MIN_RSC_ITR 24 -#define IXGBE_100K_ITR 40 -#define IXGBE_20K_ITR 200 -#define IXGBE_10K_ITR 400 -#define IXGBE_8K_ITR 500 - /* Helper macros to switch between ints/sec and what the register uses. * And yes, it's the same math going both ways. The lowest value * supported by all of the ixgbe hardware is 8. @@ -177,8 +181,9 @@ struct ixgbevf_q_vector { #define NON_Q_VECTORS (OTHER_VECTOR) #define MAX_MSIX_Q_VECTORS 2 +#define MAX_MSIX_COUNT 2 -#define MIN_MSIX_Q_VECTORS 1 +#define MIN_MSIX_Q_VECTORS 2 #define MIN_MSIX_COUNT (MIN_MSIX_Q_VECTORS + NON_Q_VECTORS) /* board specific private data structure */ @@ -188,14 +193,12 @@ struct ixgbevf_adapter { u16 bd_number; struct work_struct reset_task; struct ixgbevf_q_vector *q_vector[MAX_MSIX_Q_VECTORS]; + char name[MAX_MSIX_COUNT][IFNAMSIZ + 9]; /* Interrupt Throttle Rate */ - u16 rx_itr_setting; - u16 tx_itr_setting; - - /* interrupt masks */ - u32 eims_enable_mask; - u32 eims_other; + u32 itr_setting; + u16 eitr_low; + u16 eitr_high; /* TX */ struct ixgbevf_ring *tx_ring; /* One per active queue */ @@ -210,13 +213,18 @@ struct ixgbevf_adapter { /* RX */ struct ixgbevf_ring *rx_ring; /* One per active queue */ int num_rx_queues; + int num_rx_pools; /* == num_rx_queues in 82598 */ + int num_rx_queues_per_pool; /* 1 if 82598, can be many if 82599 */ u64 hw_csum_rx_error; u64 hw_rx_no_dma_resources; u64 hw_csum_rx_good; u64 non_eop_descs; int num_msix_vectors; + int max_msix_q_vectors; /* true count of q_vectors for device */ + struct ixgbevf_ring_feature ring_feature[RING_F_ARRAY_SIZE]; struct msix_entry *msix_entries; + u64 rx_hdr_split; u32 alloc_rx_page_failed; u32 alloc_rx_buff_failed; @@ -224,8 +232,15 @@ struct ixgbevf_adapter { * thus the additional *_CAPABLE flags. */ u32 flags; -#define IXGBE_FLAG_IN_WATCHDOG_TASK (u32)(1) - +#define IXGBE_FLAG_RX_CSUM_ENABLED (u32)(1) +#define IXGBE_FLAG_RX_1BUF_CAPABLE (u32)(1 << 1) +#define IXGBE_FLAG_RX_PS_CAPABLE (u32)(1 << 2) +#define IXGBE_FLAG_RX_PS_ENABLED (u32)(1 << 3) +#define IXGBE_FLAG_IN_NETPOLL (u32)(1 << 4) +#define IXGBE_FLAG_IMIR_ENABLED (u32)(1 << 5) +#define IXGBE_FLAG_MQ_CAPABLE (u32)(1 << 6) +#define IXGBE_FLAG_NEED_LINK_UPDATE (u32)(1 << 7) +#define IXGBE_FLAG_IN_WATCHDOG_TASK (u32)(1 << 8) /* OS defined structs */ struct net_device *netdev; struct pci_dev *pdev; @@ -239,14 +254,18 @@ struct ixgbevf_adapter { u32 eitr_param; unsigned long state; + u32 *config_space; u64 tx_busy; unsigned int tx_ring_count; unsigned int rx_ring_count; u32 link_speed; bool link_up; + unsigned long link_check_timeout; struct work_struct watchdog_task; + bool netdev_registered; + bool dev_closed; }; enum ixbgevf_state_t { @@ -282,9 +301,11 @@ extern void ixgbevf_free_rx_resources(struct ixgbevf_adapter *, extern void ixgbevf_free_tx_resources(struct ixgbevf_adapter *, struct ixgbevf_ring *); extern void ixgbevf_update_stats(struct ixgbevf_adapter *adapter); -void ixgbevf_write_eitr(struct ixgbevf_q_vector *); + +#ifdef ETHTOOL_OPS_COMPAT extern int ethtool_ioctl(struct ifreq *ifr); +#endif extern void ixgbe_napi_add_all(struct ixgbevf_adapter *adapter); extern void ixgbe_napi_del_all(struct ixgbevf_adapter *adapter); diff --git a/trunk/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/trunk/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c index 8e022c6f4b90..0368160286f9 100644 --- a/trunk/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +++ b/trunk/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c @@ -97,7 +97,9 @@ module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)"); /* forward decls */ -static void ixgbevf_set_itr(struct ixgbevf_q_vector *q_vector); +static void ixgbevf_set_itr_msix(struct ixgbevf_q_vector *q_vector); +static void ixgbevf_write_eitr(struct ixgbevf_adapter *adapter, int v_idx, + u32 itr_reg); static inline void ixgbevf_release_rx_desc(struct ixgbe_hw *hw, struct ixgbevf_ring *rx_ring, @@ -173,21 +175,27 @@ static void ixgbevf_unmap_and_free_tx_resource(struct ixgbevf_adapter *adapter, #define IXGBE_MAX_DATA_PER_TXD (1 << IXGBE_MAX_TXD_PWR) /* Tx Descriptors needed, worst case */ -#define TXD_USE_COUNT(S) DIV_ROUND_UP((S), IXGBE_MAX_DATA_PER_TXD) -#define DESC_NEEDED (MAX_SKB_FRAGS + 4) +#define TXD_USE_COUNT(S) (((S) >> IXGBE_MAX_TXD_PWR) + \ + (((S) & (IXGBE_MAX_DATA_PER_TXD - 1)) ? 1 : 0)) +#ifdef MAX_SKB_FRAGS +#define DESC_NEEDED (TXD_USE_COUNT(IXGBE_MAX_DATA_PER_TXD) /* skb->data */ + \ + MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE) + 1) /* for context */ +#else +#define DESC_NEEDED TXD_USE_COUNT(IXGBE_MAX_DATA_PER_TXD) +#endif static void ixgbevf_tx_timeout(struct net_device *netdev); /** * ixgbevf_clean_tx_irq - Reclaim resources after transmit completes - * @q_vector: board private structure + * @adapter: board private structure * @tx_ring: tx ring to clean **/ -static bool ixgbevf_clean_tx_irq(struct ixgbevf_q_vector *q_vector, +static bool ixgbevf_clean_tx_irq(struct ixgbevf_adapter *adapter, struct ixgbevf_ring *tx_ring) { - struct ixgbevf_adapter *adapter = q_vector->adapter; struct net_device *netdev = adapter->netdev; + struct ixgbe_hw *hw = &adapter->hw; union ixgbe_adv_tx_desc *tx_desc, *eop_desc; struct ixgbevf_tx_buffer *tx_buffer_info; unsigned int i, eop, count = 0; @@ -198,7 +206,7 @@ static bool ixgbevf_clean_tx_irq(struct ixgbevf_q_vector *q_vector, eop_desc = IXGBE_TX_DESC_ADV(*tx_ring, eop); while ((eop_desc->wb.status & cpu_to_le32(IXGBE_TXD_STAT_DD)) && - (count < tx_ring->count)) { + (count < tx_ring->work_limit)) { bool cleaned = false; rmb(); /* read buffer_info after eop_desc */ /* eop could change between read and DD-check */ @@ -247,11 +255,25 @@ static bool ixgbevf_clean_tx_irq(struct ixgbevf_q_vector *q_vector, * sees the new next_to_clean. */ smp_mb(); +#ifdef HAVE_TX_MQ if (__netif_subqueue_stopped(netdev, tx_ring->queue_index) && !test_bit(__IXGBEVF_DOWN, &adapter->state)) { netif_wake_subqueue(netdev, tx_ring->queue_index); ++adapter->restart_queue; } +#else + if (netif_queue_stopped(netdev) && + !test_bit(__IXGBEVF_DOWN, &adapter->state)) { + netif_wake_queue(netdev); + ++adapter->restart_queue; + } +#endif + } + + /* re-arm the interrupt */ + if ((count >= tx_ring->work_limit) && + (!test_bit(__IXGBEVF_DOWN, &adapter->state))) { + IXGBE_WRITE_REG(hw, IXGBE_VTEICS, tx_ring->v_idx); } u64_stats_update_begin(&tx_ring->syncp); @@ -259,7 +281,7 @@ static bool ixgbevf_clean_tx_irq(struct ixgbevf_q_vector *q_vector, tx_ring->total_packets += total_packets; u64_stats_update_end(&tx_ring->syncp); - return count < tx_ring->count; + return count < tx_ring->work_limit; } /** @@ -282,7 +304,10 @@ static void ixgbevf_receive_skb(struct ixgbevf_q_vector *q_vector, if (is_vlan && test_bit(tag, adapter->active_vlans)) __vlan_hwaccel_put_tag(skb, tag); - napi_gro_receive(&q_vector->napi, skb); + if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL)) + napi_gro_receive(&q_vector->napi, skb); + else + netif_rx(skb); } /** @@ -297,7 +322,7 @@ static inline void ixgbevf_rx_checksum(struct ixgbevf_adapter *adapter, skb_checksum_none_assert(skb); /* Rx csum disabled */ - if (!(adapter->netdev->features & NETIF_F_RXCSUM)) + if (!(adapter->flags & IXGBE_FLAG_RX_CSUM_ENABLED)) return; /* if IP and error */ @@ -340,6 +365,27 @@ static void ixgbevf_alloc_rx_buffers(struct ixgbevf_adapter *adapter, while (cleaned_count--) { rx_desc = IXGBE_RX_DESC_ADV(*rx_ring, i); + + if (!bi->page_dma && + (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED)) { + if (!bi->page) { + bi->page = alloc_page(GFP_ATOMIC | __GFP_COLD); + if (!bi->page) { + adapter->alloc_rx_page_failed++; + goto no_buffers; + } + bi->page_offset = 0; + } else { + /* use a half page if we're re-using */ + bi->page_offset ^= (PAGE_SIZE / 2); + } + + bi->page_dma = dma_map_page(&pdev->dev, bi->page, + bi->page_offset, + (PAGE_SIZE / 2), + DMA_FROM_DEVICE); + } + skb = bi->skb; if (!skb) { skb = netdev_alloc_skb(adapter->netdev, @@ -364,7 +410,14 @@ static void ixgbevf_alloc_rx_buffers(struct ixgbevf_adapter *adapter, rx_ring->rx_buf_len, DMA_FROM_DEVICE); } - rx_desc->read.pkt_addr = cpu_to_le64(bi->dma); + /* Refresh the desc even if buffer_addrs didn't change because + * each write-back erases this info. */ + if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) { + rx_desc->read.pkt_addr = cpu_to_le64(bi->page_dma); + rx_desc->read.hdr_addr = cpu_to_le64(bi->dma); + } else { + rx_desc->read.pkt_addr = cpu_to_le64(bi->dma); + } i++; if (i == rx_ring->count) @@ -383,16 +436,28 @@ static void ixgbevf_alloc_rx_buffers(struct ixgbevf_adapter *adapter, } static inline void ixgbevf_irq_enable_queues(struct ixgbevf_adapter *adapter, - u32 qmask) + u64 qmask) { + u32 mask; struct ixgbe_hw *hw = &adapter->hw; - IXGBE_WRITE_REG(hw, IXGBE_VTEIMS, qmask); + mask = (qmask & 0xFFFFFFFF); + IXGBE_WRITE_REG(hw, IXGBE_VTEIMS, mask); +} + +static inline u16 ixgbevf_get_hdr_info(union ixgbe_adv_rx_desc *rx_desc) +{ + return rx_desc->wb.lower.lo_dword.hs_rss.hdr_info; +} + +static inline u16 ixgbevf_get_pkt_info(union ixgbe_adv_rx_desc *rx_desc) +{ + return rx_desc->wb.lower.lo_dword.hs_rss.pkt_info; } static bool ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector, struct ixgbevf_ring *rx_ring, - int budget) + int *work_done, int work_to_do) { struct ixgbevf_adapter *adapter = q_vector->adapter; struct pci_dev *pdev = adapter->pdev; @@ -401,6 +466,8 @@ static bool ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector, struct sk_buff *skb; unsigned int i; u32 len, staterr; + u16 hdr_info; + bool cleaned = false; int cleaned_count = 0; unsigned int total_rx_bytes = 0, total_rx_packets = 0; @@ -410,12 +477,25 @@ static bool ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector, rx_buffer_info = &rx_ring->rx_buffer_info[i]; while (staterr & IXGBE_RXD_STAT_DD) { - if (!budget) + u32 upper_len = 0; + if (*work_done >= work_to_do) break; - budget--; + (*work_done)++; rmb(); /* read descriptor and rx_buffer_info after status DD */ - len = le16_to_cpu(rx_desc->wb.upper.length); + if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) { + hdr_info = le16_to_cpu(ixgbevf_get_hdr_info(rx_desc)); + len = (hdr_info & IXGBE_RXDADV_HDRBUFLEN_MASK) >> + IXGBE_RXDADV_HDRBUFLEN_SHIFT; + if (hdr_info & IXGBE_RXDADV_SPH) + adapter->rx_hdr_split++; + if (len > IXGBEVF_RX_HDR_SIZE) + len = IXGBEVF_RX_HDR_SIZE; + upper_len = le16_to_cpu(rx_desc->wb.upper.length); + } else { + len = le16_to_cpu(rx_desc->wb.upper.length); + } + cleaned = true; skb = rx_buffer_info->skb; prefetch(skb->data - NET_IP_ALIGN); rx_buffer_info->skb = NULL; @@ -428,6 +508,26 @@ static bool ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector, skb_put(skb, len); } + if (upper_len) { + dma_unmap_page(&pdev->dev, rx_buffer_info->page_dma, + PAGE_SIZE / 2, DMA_FROM_DEVICE); + rx_buffer_info->page_dma = 0; + skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags, + rx_buffer_info->page, + rx_buffer_info->page_offset, + upper_len); + + if ((rx_ring->rx_buf_len > (PAGE_SIZE / 2)) || + (page_count(rx_buffer_info->page) != 1)) + rx_buffer_info->page = NULL; + else + get_page(rx_buffer_info->page); + + skb->len += upper_len; + skb->data_len += upper_len; + skb->truesize += upper_len; + } + i++; if (i == rx_ring->count) i = 0; @@ -439,8 +539,15 @@ static bool ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector, next_buffer = &rx_ring->rx_buffer_info[i]; if (!(staterr & IXGBE_RXD_STAT_EOP)) { - skb->next = next_buffer->skb; - skb->next->prev = skb; + if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) { + rx_buffer_info->skb = next_buffer->skb; + rx_buffer_info->dma = next_buffer->dma; + next_buffer->skb = skb; + next_buffer->dma = 0; + } else { + skb->next = next_buffer->skb; + skb->next->prev = skb; + } adapter->non_eop_descs++; goto next_desc; } @@ -498,52 +605,92 @@ static bool ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector, rx_ring->total_bytes += total_rx_bytes; u64_stats_update_end(&rx_ring->syncp); - return !!budget; + return cleaned; } /** - * ixgbevf_poll - NAPI polling calback + * ixgbevf_clean_rxonly - msix (aka one shot) rx clean routine * @napi: napi struct with our devices info in it * @budget: amount of work driver is allowed to do this pass, in packets * - * This function will clean more than one or more rings associated with a - * q_vector. + * This function is optimized for cleaning one queue only on a single + * q_vector!!! **/ -static int ixgbevf_poll(struct napi_struct *napi, int budget) +static int ixgbevf_clean_rxonly(struct napi_struct *napi, int budget) { struct ixgbevf_q_vector *q_vector = container_of(napi, struct ixgbevf_q_vector, napi); struct ixgbevf_adapter *adapter = q_vector->adapter; - struct ixgbevf_ring *ring; - int per_ring_budget; - bool clean_complete = true; + struct ixgbevf_ring *rx_ring = NULL; + int work_done = 0; + long r_idx; + + r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues); + rx_ring = &(adapter->rx_ring[r_idx]); + + ixgbevf_clean_rx_irq(q_vector, rx_ring, &work_done, budget); + + /* If all Rx work done, exit the polling mode */ + if (work_done < budget) { + napi_complete(napi); + if (adapter->itr_setting & 1) + ixgbevf_set_itr_msix(q_vector); + if (!test_bit(__IXGBEVF_DOWN, &adapter->state)) + ixgbevf_irq_enable_queues(adapter, rx_ring->v_idx); + } - ixgbevf_for_each_ring(ring, q_vector->tx) - clean_complete &= ixgbevf_clean_tx_irq(q_vector, ring); + return work_done; +} + +/** + * ixgbevf_clean_rxonly_many - msix (aka one shot) rx clean routine + * @napi: napi struct with our devices info in it + * @budget: amount of work driver is allowed to do this pass, in packets + * + * This function will clean more than one rx queue associated with a + * q_vector. + **/ +static int ixgbevf_clean_rxonly_many(struct napi_struct *napi, int budget) +{ + struct ixgbevf_q_vector *q_vector = + container_of(napi, struct ixgbevf_q_vector, napi); + struct ixgbevf_adapter *adapter = q_vector->adapter; + struct ixgbevf_ring *rx_ring = NULL; + int work_done = 0, i; + long r_idx; + u64 enable_mask = 0; /* attempt to distribute budget to each queue fairly, but don't allow * the budget to go below 1 because we'll exit polling */ - if (q_vector->rx.count > 1) - per_ring_budget = max(budget/q_vector->rx.count, 1); - else - per_ring_budget = budget; - - ixgbevf_for_each_ring(ring, q_vector->rx) - clean_complete &= ixgbevf_clean_rx_irq(q_vector, ring, - per_ring_budget); - - /* If all work not completed, return budget and keep polling */ - if (!clean_complete) - return budget; - /* all work done, exit the polling mode */ - napi_complete(napi); - if (adapter->rx_itr_setting & 1) - ixgbevf_set_itr(q_vector); - if (!test_bit(__IXGBEVF_DOWN, &adapter->state)) - ixgbevf_irq_enable_queues(adapter, - 1 << q_vector->v_idx); + budget /= (q_vector->rxr_count ?: 1); + budget = max(budget, 1); + r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues); + for (i = 0; i < q_vector->rxr_count; i++) { + rx_ring = &(adapter->rx_ring[r_idx]); + ixgbevf_clean_rx_irq(q_vector, rx_ring, &work_done, budget); + enable_mask |= rx_ring->v_idx; + r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues, + r_idx + 1); + } - return 0; +#ifndef HAVE_NETDEV_NAPI_LIST + if (!netif_running(adapter->netdev)) + work_done = 0; + +#endif + r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues); + rx_ring = &(adapter->rx_ring[r_idx]); + + /* If all Rx work done, exit the polling mode */ + if (work_done < budget) { + napi_complete(napi); + if (adapter->itr_setting & 1) + ixgbevf_set_itr_msix(q_vector); + if (!test_bit(__IXGBEVF_DOWN, &adapter->state)) + ixgbevf_irq_enable_queues(adapter, enable_mask); + } + + return work_done; } @@ -557,49 +704,56 @@ static int ixgbevf_poll(struct napi_struct *napi, int budget) static void ixgbevf_configure_msix(struct ixgbevf_adapter *adapter) { struct ixgbevf_q_vector *q_vector; - int q_vectors, v_idx; + struct ixgbe_hw *hw = &adapter->hw; + int i, j, q_vectors, v_idx, r_idx; + u32 mask; q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS; - adapter->eims_enable_mask = 0; /* * Populate the IVAR table and set the ITR values to the * corresponding register. */ for (v_idx = 0; v_idx < q_vectors; v_idx++) { - struct ixgbevf_ring *ring; q_vector = adapter->q_vector[v_idx]; - - ixgbevf_for_each_ring(ring, q_vector->rx) - ixgbevf_set_ivar(adapter, 0, ring->reg_idx, v_idx); - - ixgbevf_for_each_ring(ring, q_vector->tx) - ixgbevf_set_ivar(adapter, 1, ring->reg_idx, v_idx); - - if (q_vector->tx.ring && !q_vector->rx.ring) { - /* tx only vector */ - if (adapter->tx_itr_setting == 1) - q_vector->itr = IXGBE_10K_ITR; - else - q_vector->itr = adapter->tx_itr_setting; - } else { - /* rx or rx/tx vector */ - if (adapter->rx_itr_setting == 1) - q_vector->itr = IXGBE_20K_ITR; - else - q_vector->itr = adapter->rx_itr_setting; + /* XXX for_each_set_bit(...) */ + r_idx = find_first_bit(q_vector->rxr_idx, + adapter->num_rx_queues); + + for (i = 0; i < q_vector->rxr_count; i++) { + j = adapter->rx_ring[r_idx].reg_idx; + ixgbevf_set_ivar(adapter, 0, j, v_idx); + r_idx = find_next_bit(q_vector->rxr_idx, + adapter->num_rx_queues, + r_idx + 1); + } + r_idx = find_first_bit(q_vector->txr_idx, + adapter->num_tx_queues); + + for (i = 0; i < q_vector->txr_count; i++) { + j = adapter->tx_ring[r_idx].reg_idx; + ixgbevf_set_ivar(adapter, 1, j, v_idx); + r_idx = find_next_bit(q_vector->txr_idx, + adapter->num_tx_queues, + r_idx + 1); } - /* add q_vector eims value to global eims_enable_mask */ - adapter->eims_enable_mask |= 1 << v_idx; + /* if this is a tx only vector halve the interrupt rate */ + if (q_vector->txr_count && !q_vector->rxr_count) + q_vector->eitr = (adapter->eitr_param >> 1); + else if (q_vector->rxr_count) + /* rx only */ + q_vector->eitr = adapter->eitr_param; - ixgbevf_write_eitr(q_vector); + ixgbevf_write_eitr(adapter, v_idx, q_vector->eitr); } ixgbevf_set_ivar(adapter, -1, 1, v_idx); - /* setup eims_other and add value to global eims_enable_mask */ - adapter->eims_other = 1 << v_idx; - adapter->eims_enable_mask |= adapter->eims_other; + + /* set up to autoclear timer, and the vectors */ + mask = IXGBE_EIMS_ENABLE_MASK; + mask &= ~IXGBE_EIMS_OTHER; + IXGBE_WRITE_REG(hw, IXGBE_VTEIAC, mask); } enum latency_range { @@ -611,8 +765,11 @@ enum latency_range { /** * ixgbevf_update_itr - update the dynamic ITR value based on statistics - * @q_vector: structure containing interrupt and ring information - * @ring_container: structure containing ring performance data + * @adapter: pointer to adapter + * @eitr: eitr setting (ints per sec) to give last timeslice + * @itr_setting: current throttle rate in ints/second + * @packets: the number of packets during this measurement interval + * @bytes: the number of bytes during this measurement interval * * Stores a new ITR value based on packets and byte * counts during the last interrupt. The advantage of per interrupt @@ -622,17 +779,17 @@ enum latency_range { * on testing data as well as attempting to minimize response time * while increasing bulk throughput. **/ -static void ixgbevf_update_itr(struct ixgbevf_q_vector *q_vector, - struct ixgbevf_ring_container *ring_container) +static u8 ixgbevf_update_itr(struct ixgbevf_adapter *adapter, + u32 eitr, u8 itr_setting, + int packets, int bytes) { - int bytes = ring_container->total_bytes; - int packets = ring_container->total_packets; + unsigned int retval = itr_setting; u32 timepassed_us; u64 bytes_perint; - u8 itr_setting = ring_container->itr; if (packets == 0) - return; + goto update_itr_done; + /* simple throttlerate management * 0-20MB/s lowest (100000 ints/s) @@ -640,48 +797,46 @@ static void ixgbevf_update_itr(struct ixgbevf_q_vector *q_vector, * 100-1249MB/s bulk (8000 ints/s) */ /* what was last interrupt timeslice? */ - timepassed_us = q_vector->itr >> 2; + timepassed_us = 1000000/eitr; bytes_perint = bytes / timepassed_us; /* bytes/usec */ switch (itr_setting) { case lowest_latency: - if (bytes_perint > 10) - itr_setting = low_latency; + if (bytes_perint > adapter->eitr_low) + retval = low_latency; break; case low_latency: - if (bytes_perint > 20) - itr_setting = bulk_latency; - else if (bytes_perint <= 10) - itr_setting = lowest_latency; + if (bytes_perint > adapter->eitr_high) + retval = bulk_latency; + else if (bytes_perint <= adapter->eitr_low) + retval = lowest_latency; break; case bulk_latency: - if (bytes_perint <= 20) - itr_setting = low_latency; + if (bytes_perint <= adapter->eitr_high) + retval = low_latency; break; } - /* clear work counters since we have the values we need */ - ring_container->total_bytes = 0; - ring_container->total_packets = 0; - - /* write updated itr to ring container */ - ring_container->itr = itr_setting; +update_itr_done: + return retval; } /** * ixgbevf_write_eitr - write VTEITR register in hardware specific way - * @q_vector: structure containing interrupt and ring information + * @adapter: pointer to adapter struct + * @v_idx: vector index into q_vector array + * @itr_reg: new value to be written in *register* format, not ints/s * * This function is made to be called by ethtool and by the driver * when it needs to update VTEITR registers at runtime. Hardware * specific quirks/differences are taken care of here. */ -void ixgbevf_write_eitr(struct ixgbevf_q_vector *q_vector) +static void ixgbevf_write_eitr(struct ixgbevf_adapter *adapter, int v_idx, + u32 itr_reg) { - struct ixgbevf_adapter *adapter = q_vector->adapter; struct ixgbe_hw *hw = &adapter->hw; - int v_idx = q_vector->v_idx; - u32 itr_reg = q_vector->itr & IXGBE_MAX_EITR; + + itr_reg = EITR_INTS_PER_SEC_TO_REG(itr_reg); /* * set the WDIS bit to not clear the timer bits and cause an @@ -692,49 +847,84 @@ void ixgbevf_write_eitr(struct ixgbevf_q_vector *q_vector) IXGBE_WRITE_REG(hw, IXGBE_VTEITR(v_idx), itr_reg); } -static void ixgbevf_set_itr(struct ixgbevf_q_vector *q_vector) +static void ixgbevf_set_itr_msix(struct ixgbevf_q_vector *q_vector) { - u32 new_itr = q_vector->itr; - u8 current_itr; - - ixgbevf_update_itr(q_vector, &q_vector->tx); - ixgbevf_update_itr(q_vector, &q_vector->rx); - - current_itr = max(q_vector->rx.itr, q_vector->tx.itr); + struct ixgbevf_adapter *adapter = q_vector->adapter; + u32 new_itr; + u8 current_itr, ret_itr; + int i, r_idx, v_idx = q_vector->v_idx; + struct ixgbevf_ring *rx_ring, *tx_ring; + + r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues); + for (i = 0; i < q_vector->txr_count; i++) { + tx_ring = &(adapter->tx_ring[r_idx]); + ret_itr = ixgbevf_update_itr(adapter, q_vector->eitr, + q_vector->tx_itr, + tx_ring->total_packets, + tx_ring->total_bytes); + /* if the result for this queue would decrease interrupt + * rate for this vector then use that result */ + q_vector->tx_itr = ((q_vector->tx_itr > ret_itr) ? + q_vector->tx_itr - 1 : ret_itr); + r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues, + r_idx + 1); + } + + r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues); + for (i = 0; i < q_vector->rxr_count; i++) { + rx_ring = &(adapter->rx_ring[r_idx]); + ret_itr = ixgbevf_update_itr(adapter, q_vector->eitr, + q_vector->rx_itr, + rx_ring->total_packets, + rx_ring->total_bytes); + /* if the result for this queue would decrease interrupt + * rate for this vector then use that result */ + q_vector->rx_itr = ((q_vector->rx_itr > ret_itr) ? + q_vector->rx_itr - 1 : ret_itr); + r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues, + r_idx + 1); + } + + current_itr = max(q_vector->rx_itr, q_vector->tx_itr); switch (current_itr) { /* counts and packets in update_itr are dependent on these numbers */ case lowest_latency: - new_itr = IXGBE_100K_ITR; + new_itr = 100000; break; case low_latency: - new_itr = IXGBE_20K_ITR; + new_itr = 20000; /* aka hwitr = ~200 */ break; case bulk_latency: default: - new_itr = IXGBE_8K_ITR; + new_itr = 8000; break; } - if (new_itr != q_vector->itr) { - /* do an exponential smoothing */ - new_itr = (10 * new_itr * q_vector->itr) / - ((9 * new_itr) + q_vector->itr); - - /* save the algorithm value here */ - q_vector->itr = new_itr; + if (new_itr != q_vector->eitr) { + u32 itr_reg; - ixgbevf_write_eitr(q_vector); + /* save the algorithm value here, not the smoothed one */ + q_vector->eitr = new_itr; + /* do an exponential smoothing */ + new_itr = ((q_vector->eitr * 90)/100) + ((new_itr * 10)/100); + itr_reg = EITR_INTS_PER_SEC_TO_REG(new_itr); + ixgbevf_write_eitr(adapter, v_idx, itr_reg); } } static irqreturn_t ixgbevf_msix_mbx(int irq, void *data) { - struct ixgbevf_adapter *adapter = data; + struct net_device *netdev = data; + struct ixgbevf_adapter *adapter = netdev_priv(netdev); struct ixgbe_hw *hw = &adapter->hw; + u32 eicr; u32 msg; bool got_ack = false; + eicr = IXGBE_READ_REG(hw, IXGBE_VTEICS); + IXGBE_WRITE_REG(hw, IXGBE_VTEICR, eicr); + if (!hw->mbx.ops.check_for_ack(hw)) got_ack = true; @@ -763,24 +953,75 @@ static irqreturn_t ixgbevf_msix_mbx(int irq, void *data) if (got_ack) hw->mbx.v2p_mailbox |= IXGBE_VFMAILBOX_PFACK; - IXGBE_WRITE_REG(hw, IXGBE_VTEIMS, adapter->eims_other); - return IRQ_HANDLED; } +static irqreturn_t ixgbevf_msix_clean_tx(int irq, void *data) +{ + struct ixgbevf_q_vector *q_vector = data; + struct ixgbevf_adapter *adapter = q_vector->adapter; + struct ixgbevf_ring *tx_ring; + int i, r_idx; + + if (!q_vector->txr_count) + return IRQ_HANDLED; + + r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues); + for (i = 0; i < q_vector->txr_count; i++) { + tx_ring = &(adapter->tx_ring[r_idx]); + tx_ring->total_bytes = 0; + tx_ring->total_packets = 0; + ixgbevf_clean_tx_irq(adapter, tx_ring); + r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues, + r_idx + 1); + } + + if (adapter->itr_setting & 1) + ixgbevf_set_itr_msix(q_vector); + + return IRQ_HANDLED; +} /** - * ixgbevf_msix_clean_rings - single unshared vector rx clean (all queues) + * ixgbevf_msix_clean_rx - single unshared vector rx clean (all queues) * @irq: unused * @data: pointer to our q_vector struct for this interrupt vector **/ -static irqreturn_t ixgbevf_msix_clean_rings(int irq, void *data) +static irqreturn_t ixgbevf_msix_clean_rx(int irq, void *data) { struct ixgbevf_q_vector *q_vector = data; + struct ixgbevf_adapter *adapter = q_vector->adapter; + struct ixgbe_hw *hw = &adapter->hw; + struct ixgbevf_ring *rx_ring; + int r_idx; + int i; + + r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues); + for (i = 0; i < q_vector->rxr_count; i++) { + rx_ring = &(adapter->rx_ring[r_idx]); + rx_ring->total_bytes = 0; + rx_ring->total_packets = 0; + r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues, + r_idx + 1); + } + + if (!q_vector->rxr_count) + return IRQ_HANDLED; + + r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues); + rx_ring = &(adapter->rx_ring[r_idx]); + /* disable interrupts on this vector only */ + IXGBE_WRITE_REG(hw, IXGBE_VTEIMC, rx_ring->v_idx); + napi_schedule(&q_vector->napi); - /* EIAM disabled interrupts (on this vector) for us */ - if (q_vector->rx.ring || q_vector->tx.ring) - napi_schedule(&q_vector->napi); + + return IRQ_HANDLED; +} + +static irqreturn_t ixgbevf_msix_clean_many(int irq, void *data) +{ + ixgbevf_msix_clean_rx(irq, data); + ixgbevf_msix_clean_tx(irq, data); return IRQ_HANDLED; } @@ -790,9 +1031,9 @@ static inline void map_vector_to_rxq(struct ixgbevf_adapter *a, int v_idx, { struct ixgbevf_q_vector *q_vector = a->q_vector[v_idx]; - a->rx_ring[r_idx].next = q_vector->rx.ring; - q_vector->rx.ring = &a->rx_ring[r_idx]; - q_vector->rx.count++; + set_bit(r_idx, q_vector->rxr_idx); + q_vector->rxr_count++; + a->rx_ring[r_idx].v_idx = 1 << v_idx; } static inline void map_vector_to_txq(struct ixgbevf_adapter *a, int v_idx, @@ -800,9 +1041,9 @@ static inline void map_vector_to_txq(struct ixgbevf_adapter *a, int v_idx, { struct ixgbevf_q_vector *q_vector = a->q_vector[v_idx]; - a->tx_ring[t_idx].next = q_vector->tx.ring; - q_vector->tx.ring = &a->tx_ring[t_idx]; - q_vector->tx.count++; + set_bit(t_idx, q_vector->txr_idx); + q_vector->txr_count++; + a->tx_ring[t_idx].v_idx = 1 << v_idx; } /** @@ -878,30 +1119,37 @@ static int ixgbevf_map_rings_to_vectors(struct ixgbevf_adapter *adapter) static int ixgbevf_request_msix_irqs(struct ixgbevf_adapter *adapter) { struct net_device *netdev = adapter->netdev; - int q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS; - int vector, err; + irqreturn_t (*handler)(int, void *); + int i, vector, q_vectors, err; int ri = 0, ti = 0; + /* Decrement for Other and TCP Timer vectors */ + q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS; + +#define SET_HANDLER(_v) (((_v)->rxr_count && (_v)->txr_count) \ + ? &ixgbevf_msix_clean_many : \ + (_v)->rxr_count ? &ixgbevf_msix_clean_rx : \ + (_v)->txr_count ? &ixgbevf_msix_clean_tx : \ + NULL) for (vector = 0; vector < q_vectors; vector++) { - struct ixgbevf_q_vector *q_vector = adapter->q_vector[vector]; - struct msix_entry *entry = &adapter->msix_entries[vector]; - - if (q_vector->tx.ring && q_vector->rx.ring) { - snprintf(q_vector->name, sizeof(q_vector->name) - 1, - "%s-%s-%d", netdev->name, "TxRx", ri++); - ti++; - } else if (q_vector->rx.ring) { - snprintf(q_vector->name, sizeof(q_vector->name) - 1, - "%s-%s-%d", netdev->name, "rx", ri++); - } else if (q_vector->tx.ring) { - snprintf(q_vector->name, sizeof(q_vector->name) - 1, - "%s-%s-%d", netdev->name, "tx", ti++); + handler = SET_HANDLER(adapter->q_vector[vector]); + + if (handler == &ixgbevf_msix_clean_rx) { + sprintf(adapter->name[vector], "%s-%s-%d", + netdev->name, "rx", ri++); + } else if (handler == &ixgbevf_msix_clean_tx) { + sprintf(adapter->name[vector], "%s-%s-%d", + netdev->name, "tx", ti++); + } else if (handler == &ixgbevf_msix_clean_many) { + sprintf(adapter->name[vector], "%s-%s-%d", + netdev->name, "TxRx", vector); } else { /* skip this unused q_vector */ continue; } - err = request_irq(entry->vector, &ixgbevf_msix_clean_rings, 0, - q_vector->name, q_vector); + err = request_irq(adapter->msix_entries[vector].vector, + handler, 0, adapter->name[vector], + adapter->q_vector[vector]); if (err) { hw_dbg(&adapter->hw, "request_irq failed for MSIX interrupt " @@ -910,8 +1158,9 @@ static int ixgbevf_request_msix_irqs(struct ixgbevf_adapter *adapter) } } + sprintf(adapter->name[vector], "%s:mbx", netdev->name); err = request_irq(adapter->msix_entries[vector].vector, - &ixgbevf_msix_mbx, 0, netdev->name, adapter); + &ixgbevf_msix_mbx, 0, adapter->name[vector], netdev); if (err) { hw_dbg(&adapter->hw, "request_irq for msix_mbx failed: %d\n", err); @@ -921,11 +1170,9 @@ static int ixgbevf_request_msix_irqs(struct ixgbevf_adapter *adapter) return 0; free_queue_irqs: - while (vector) { - vector--; - free_irq(adapter->msix_entries[vector].vector, - adapter->q_vector[vector]); - } + for (i = vector - 1; i >= 0; i--) + free_irq(adapter->msix_entries[--vector].vector, + &(adapter->q_vector[i])); pci_disable_msix(adapter->pdev); kfree(adapter->msix_entries); adapter->msix_entries = NULL; @@ -938,10 +1185,11 @@ static inline void ixgbevf_reset_q_vectors(struct ixgbevf_adapter *adapter) for (i = 0; i < q_vectors; i++) { struct ixgbevf_q_vector *q_vector = adapter->q_vector[i]; - q_vector->rx.ring = NULL; - q_vector->tx.ring = NULL; - q_vector->rx.count = 0; - q_vector->tx.count = 0; + bitmap_zero(q_vector->rxr_idx, MAX_RX_QUEUES); + bitmap_zero(q_vector->txr_idx, MAX_TX_QUEUES); + q_vector->rxr_count = 0; + q_vector->txr_count = 0; + q_vector->eitr = adapter->eitr_param; } } @@ -967,20 +1215,17 @@ static int ixgbevf_request_irq(struct ixgbevf_adapter *adapter) static void ixgbevf_free_irq(struct ixgbevf_adapter *adapter) { + struct net_device *netdev = adapter->netdev; int i, q_vectors; q_vectors = adapter->num_msix_vectors; + i = q_vectors - 1; - free_irq(adapter->msix_entries[i].vector, adapter); + free_irq(adapter->msix_entries[i].vector, netdev); i--; for (; i >= 0; i--) { - /* free only the irqs that were actually requested */ - if (!adapter->q_vector[i]->rx.ring && - !adapter->q_vector[i]->tx.ring) - continue; - free_irq(adapter->msix_entries[i].vector, adapter->q_vector[i]); } @@ -994,12 +1239,10 @@ static void ixgbevf_free_irq(struct ixgbevf_adapter *adapter) **/ static inline void ixgbevf_irq_disable(struct ixgbevf_adapter *adapter) { - struct ixgbe_hw *hw = &adapter->hw; int i; + struct ixgbe_hw *hw = &adapter->hw; - IXGBE_WRITE_REG(hw, IXGBE_VTEIAM, 0); IXGBE_WRITE_REG(hw, IXGBE_VTEIMC, ~0); - IXGBE_WRITE_REG(hw, IXGBE_VTEIAC, 0); IXGBE_WRITE_FLUSH(hw); @@ -1011,13 +1254,23 @@ static inline void ixgbevf_irq_disable(struct ixgbevf_adapter *adapter) * ixgbevf_irq_enable - Enable default interrupt generation settings * @adapter: board private structure **/ -static inline void ixgbevf_irq_enable(struct ixgbevf_adapter *adapter) +static inline void ixgbevf_irq_enable(struct ixgbevf_adapter *adapter, + bool queues, bool flush) { struct ixgbe_hw *hw = &adapter->hw; + u32 mask; + u64 qmask; - IXGBE_WRITE_REG(hw, IXGBE_VTEIAM, adapter->eims_enable_mask); - IXGBE_WRITE_REG(hw, IXGBE_VTEIAC, adapter->eims_enable_mask); - IXGBE_WRITE_REG(hw, IXGBE_VTEIMS, adapter->eims_enable_mask); + mask = (IXGBE_EIMS_ENABLE_MASK & ~IXGBE_EIMS_RTX_QUEUE); + qmask = ~0; + + IXGBE_WRITE_REG(hw, IXGBE_VTEIMS, mask); + + if (queues) + ixgbevf_irq_enable_queues(adapter, qmask); + + if (flush) + IXGBE_WRITE_FLUSH(hw); } /** @@ -1067,14 +1320,29 @@ static void ixgbevf_configure_srrctl(struct ixgbevf_adapter *adapter, int index) srrctl = IXGBE_SRRCTL_DROP_EN; - srrctl |= IXGBE_SRRCTL_DESCTYPE_ADV_ONEBUF; + if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) { + u16 bufsz = IXGBEVF_RXBUFFER_2048; + /* grow the amount we can receive on large page machines */ + if (bufsz < (PAGE_SIZE / 2)) + bufsz = (PAGE_SIZE / 2); + /* cap the bufsz at our largest descriptor size */ + bufsz = min((u16)IXGBEVF_MAX_RXBUFFER, bufsz); + + srrctl |= bufsz >> IXGBE_SRRCTL_BSIZEPKT_SHIFT; + srrctl |= IXGBE_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS; + srrctl |= ((IXGBEVF_RX_HDR_SIZE << + IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT) & + IXGBE_SRRCTL_BSIZEHDR_MASK); + } else { + srrctl |= IXGBE_SRRCTL_DESCTYPE_ADV_ONEBUF; - if (rx_ring->rx_buf_len == MAXIMUM_ETHERNET_VLAN_SIZE) - srrctl |= IXGBEVF_RXBUFFER_2048 >> - IXGBE_SRRCTL_BSIZEPKT_SHIFT; - else - srrctl |= rx_ring->rx_buf_len >> - IXGBE_SRRCTL_BSIZEPKT_SHIFT; + if (rx_ring->rx_buf_len == MAXIMUM_ETHERNET_VLAN_SIZE) + srrctl |= IXGBEVF_RXBUFFER_2048 >> + IXGBE_SRRCTL_BSIZEPKT_SHIFT; + else + srrctl |= rx_ring->rx_buf_len >> + IXGBE_SRRCTL_BSIZEPKT_SHIFT; + } IXGBE_WRITE_REG(hw, IXGBE_VFSRRCTL(index), srrctl); } @@ -1094,12 +1362,36 @@ static void ixgbevf_configure_rx(struct ixgbevf_adapter *adapter) u32 rdlen; int rx_buf_len; - /* PSRTYPE must be initialized in 82599 */ - IXGBE_WRITE_REG(hw, IXGBE_VFPSRTYPE, 0); - if (netdev->mtu <= ETH_DATA_LEN) - rx_buf_len = MAXIMUM_ETHERNET_VLAN_SIZE; - else - rx_buf_len = ALIGN(max_frame, 1024); + /* Decide whether to use packet split mode or not */ + if (netdev->mtu > ETH_DATA_LEN) { + if (adapter->flags & IXGBE_FLAG_RX_PS_CAPABLE) + adapter->flags |= IXGBE_FLAG_RX_PS_ENABLED; + else + adapter->flags &= ~IXGBE_FLAG_RX_PS_ENABLED; + } else { + if (adapter->flags & IXGBE_FLAG_RX_1BUF_CAPABLE) + adapter->flags &= ~IXGBE_FLAG_RX_PS_ENABLED; + else + adapter->flags |= IXGBE_FLAG_RX_PS_ENABLED; + } + + /* Set the RX buffer length according to the mode */ + if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) { + /* PSRTYPE must be initialized in 82599 */ + u32 psrtype = IXGBE_PSRTYPE_TCPHDR | + IXGBE_PSRTYPE_UDPHDR | + IXGBE_PSRTYPE_IPV4HDR | + IXGBE_PSRTYPE_IPV6HDR | + IXGBE_PSRTYPE_L2HDR; + IXGBE_WRITE_REG(hw, IXGBE_VFPSRTYPE, psrtype); + rx_buf_len = IXGBEVF_RX_HDR_SIZE; + } else { + IXGBE_WRITE_REG(hw, IXGBE_VFPSRTYPE, 0); + if (netdev->mtu <= ETH_DATA_LEN) + rx_buf_len = MAXIMUM_ETHERNET_VLAN_SIZE; + else + rx_buf_len = ALIGN(max_frame, 1024); + } rdlen = adapter->rx_ring[0].count * sizeof(union ixgbe_adv_rx_desc); /* Setup the HW Rx Head and Tail Descriptor Pointers and @@ -1210,8 +1502,15 @@ static void ixgbevf_napi_enable_all(struct ixgbevf_adapter *adapter) int q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS; for (q_idx = 0; q_idx < q_vectors; q_idx++) { + struct napi_struct *napi; q_vector = adapter->q_vector[q_idx]; - napi_enable(&q_vector->napi); + if (!q_vector->rxr_count) + continue; + napi = &q_vector->napi; + if (q_vector->rxr_count > 1) + napi->poll = &ixgbevf_clean_rxonly_many; + + napi_enable(napi); } } @@ -1223,6 +1522,8 @@ static void ixgbevf_napi_disable_all(struct ixgbevf_adapter *adapter) for (q_idx = 0; q_idx < q_vectors; q_idx++) { q_vector = adapter->q_vector[q_idx]; + if (!q_vector->rxr_count) + continue; napi_disable(&q_vector->napi); } } @@ -1366,6 +1667,10 @@ static void ixgbevf_up_complete(struct ixgbevf_adapter *adapter) ixgbevf_save_reset_stats(adapter); ixgbevf_init_last_counter_stats(adapter); + /* bring the link up in the watchdog, this could race with our first + * link up interrupt but shouldn't be a problem */ + adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE; + adapter->link_check_timeout = jiffies; mod_timer(&adapter->watchdog_timer, jiffies); } @@ -1380,7 +1685,7 @@ void ixgbevf_up(struct ixgbevf_adapter *adapter) /* clear any pending interrupts, may auto mask */ IXGBE_READ_REG(hw, IXGBE_VTEICR); - ixgbevf_irq_enable(adapter); + ixgbevf_irq_enable(adapter, true, true); } /** @@ -1418,6 +1723,14 @@ static void ixgbevf_clean_rx_ring(struct ixgbevf_adapter *adapter, dev_kfree_skb(this); } while (skb); } + if (!rx_buffer_info->page) + continue; + dma_unmap_page(&pdev->dev, rx_buffer_info->page_dma, + PAGE_SIZE / 2, DMA_FROM_DEVICE); + rx_buffer_info->page_dma = 0; + put_page(rx_buffer_info->page); + rx_buffer_info->page = NULL; + rx_buffer_info->page_offset = 0; } size = sizeof(struct ixgbevf_rx_buffer) * rx_ring->count; @@ -1587,9 +1900,10 @@ static void ixgbevf_acquire_msix_vectors(struct ixgbevf_adapter *adapter, { int err, vector_threshold; - /* We'll want at least 2 (vector_threshold): - * 1) TxQ[0] + RxQ[0] handler - * 2) Other (Link Status Change, etc.) + /* We'll want at least 3 (vector_threshold): + * 1) TxQ[0] Cleanup + * 2) RxQ[0] Cleanup + * 3) Other (Link Status Change, etc.) */ vector_threshold = MIN_MSIX_COUNT; @@ -1644,6 +1958,8 @@ static void ixgbevf_set_num_queues(struct ixgbevf_adapter *adapter) /* Start with base case */ adapter->num_rx_queues = 1; adapter->num_tx_queues = 1; + adapter->num_rx_pools = adapter->num_rx_queues; + adapter->num_rx_queues_per_pool = 1; } /** @@ -1704,12 +2020,10 @@ static int ixgbevf_set_interrupt_capability(struct ixgbevf_adapter *adapter) * It's easy to be greedy for MSI-X vectors, but it really * doesn't do us much good if we have a lot more vectors * than CPU's. So let's be conservative and only ask for - * (roughly) the same number of vectors as there are CPU's. - * The default is to use pairs of vectors. + * (roughly) twice the number of vectors as there are CPU's. */ - v_budget = max(adapter->num_rx_queues, adapter->num_tx_queues); - v_budget = min_t(int, v_budget, num_online_cpus()); - v_budget += NON_Q_VECTORS; + v_budget = min(adapter->num_rx_queues + adapter->num_tx_queues, + (int)(num_online_cpus() * 2)) + NON_Q_VECTORS; /* A failure in MSI-X entry allocation isn't fatal, but it does * mean we disable MSI-X capabilities of the adapter. */ @@ -1740,8 +2054,12 @@ static int ixgbevf_alloc_q_vectors(struct ixgbevf_adapter *adapter) { int q_idx, num_q_vectors; struct ixgbevf_q_vector *q_vector; + int napi_vectors; + int (*poll)(struct napi_struct *, int); num_q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS; + napi_vectors = adapter->num_rx_queues; + poll = &ixgbevf_clean_rxonly; for (q_idx = 0; q_idx < num_q_vectors; q_idx++) { q_vector = kzalloc(sizeof(struct ixgbevf_q_vector), GFP_KERNEL); @@ -1749,8 +2067,10 @@ static int ixgbevf_alloc_q_vectors(struct ixgbevf_adapter *adapter) goto err_out; q_vector->adapter = adapter; q_vector->v_idx = q_idx; - netif_napi_add(adapter->netdev, &q_vector->napi, - ixgbevf_poll, 64); + q_vector->eitr = adapter->eitr_param; + if (q_idx < napi_vectors) + netif_napi_add(adapter->netdev, &q_vector->napi, + (*poll), 64); adapter->q_vector[q_idx] = q_vector; } @@ -1897,13 +2217,20 @@ static int __devinit ixgbevf_sw_init(struct ixgbevf_adapter *adapter) } /* Enable dynamic interrupt throttling rates */ - adapter->rx_itr_setting = 1; - adapter->tx_itr_setting = 1; + adapter->eitr_param = 20000; + adapter->itr_setting = 1; + + /* set defaults for eitr in MegaBytes */ + adapter->eitr_low = 10; + adapter->eitr_high = 20; /* set default ring sizes */ adapter->tx_ring_count = IXGBEVF_DEFAULT_TXD; adapter->rx_ring_count = IXGBEVF_DEFAULT_RXD; + /* enable rx csum by default */ + adapter->flags |= IXGBE_FLAG_RX_CSUM_ENABLED; + set_bit(__IXGBEVF_DOWN, &adapter->state); return 0; @@ -1963,7 +2290,7 @@ static void ixgbevf_watchdog(unsigned long data) { struct ixgbevf_adapter *adapter = (struct ixgbevf_adapter *)data; struct ixgbe_hw *hw = &adapter->hw; - u32 eics = 0; + u64 eics = 0; int i; /* @@ -1977,11 +2304,11 @@ static void ixgbevf_watchdog(unsigned long data) /* get one bit for every active tx/rx interrupt vector */ for (i = 0; i < adapter->num_msix_vectors - NON_Q_VECTORS; i++) { struct ixgbevf_q_vector *qv = adapter->q_vector[i]; - if (qv->rx.ring || qv->tx.ring) - eics |= 1 << i; + if (qv->rxr_count || qv->txr_count) + eics |= (1 << i); } - IXGBE_WRITE_REG(hw, IXGBE_VTEICS, eics); + IXGBE_WRITE_REG(hw, IXGBE_VTEICS, (u32)eics); watchdog_short_circuit: schedule_work(&adapter->watchdog_task); @@ -2151,6 +2478,7 @@ int ixgbevf_setup_tx_resources(struct ixgbevf_adapter *adapter, tx_ring->next_to_use = 0; tx_ring->next_to_clean = 0; + tx_ring->work_limit = tx_ring->count; return 0; err: @@ -2354,7 +2682,7 @@ static int ixgbevf_open(struct net_device *netdev) if (err) goto err_req_irq; - ixgbevf_irq_enable(adapter); + ixgbevf_irq_enable(adapter, true, true); return 0; @@ -2762,30 +3090,11 @@ static int ixgbevf_xmit_frame(struct sk_buff *skb, struct net_device *netdev) unsigned int tx_flags = 0; u8 hdr_len = 0; int r_idx = 0, tso; - u16 count = TXD_USE_COUNT(skb_headlen(skb)); -#if PAGE_SIZE > IXGBE_MAX_DATA_PER_TXD - unsigned short f; -#endif + int count = 0; - tx_ring = &adapter->tx_ring[r_idx]; + unsigned int f; - /* - * need: 1 descriptor per page * PAGE_SIZE/IXGBE_MAX_DATA_PER_TXD, - * + 1 desc for skb_headlen/IXGBE_MAX_DATA_PER_TXD, - * + 2 desc gap to keep tail from touching head, - * + 1 desc for context descriptor, - * otherwise try next time - */ -#if PAGE_SIZE > IXGBE_MAX_DATA_PER_TXD - for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) - count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size); -#else - count += skb_shinfo(skb)->nr_frags; -#endif - if (ixgbevf_maybe_stop_tx(netdev, tx_ring, count + 3)) { - adapter->tx_busy++; - return NETDEV_TX_BUSY; - } + tx_ring = &adapter->tx_ring[r_idx]; if (vlan_tx_tag_present(skb)) { tx_flags |= vlan_tx_tag_get(skb); @@ -2793,6 +3102,21 @@ static int ixgbevf_xmit_frame(struct sk_buff *skb, struct net_device *netdev) tx_flags |= IXGBE_TX_FLAGS_VLAN; } + /* four things can cause us to need a context descriptor */ + if (skb_is_gso(skb) || + (skb->ip_summed == CHECKSUM_PARTIAL) || + (tx_flags & IXGBE_TX_FLAGS_VLAN)) + count++; + + count += TXD_USE_COUNT(skb_headlen(skb)); + for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) + count += TXD_USE_COUNT(skb_frag_size(&skb_shinfo(skb)->frags[f])); + + if (ixgbevf_maybe_stop_tx(netdev, tx_ring, count)) { + adapter->tx_busy++; + return NETDEV_TX_BUSY; + } + first = tx_ring->next_to_use; if (skb->protocol == htons(ETH_P_IP)) @@ -2896,7 +3220,9 @@ static void ixgbevf_shutdown(struct pci_dev *pdev) ixgbevf_free_all_rx_resources(adapter); } +#ifdef CONFIG_PM pci_save_state(pdev); +#endif pci_disable_device(pdev); } @@ -2939,6 +3265,19 @@ static struct rtnl_link_stats64 *ixgbevf_get_stats(struct net_device *netdev, return stats; } +static int ixgbevf_set_features(struct net_device *netdev, + netdev_features_t features) +{ + struct ixgbevf_adapter *adapter = netdev_priv(netdev); + + if (features & NETIF_F_RXCSUM) + adapter->flags |= IXGBE_FLAG_RX_CSUM_ENABLED; + else + adapter->flags &= ~IXGBE_FLAG_RX_CSUM_ENABLED; + + return 0; +} + static const struct net_device_ops ixgbe_netdev_ops = { .ndo_open = ixgbevf_open, .ndo_stop = ixgbevf_close, @@ -2951,6 +3290,7 @@ static const struct net_device_ops ixgbe_netdev_ops = { .ndo_tx_timeout = ixgbevf_tx_timeout, .ndo_vlan_rx_add_vid = ixgbevf_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = ixgbevf_vlan_rx_kill_vid, + .ndo_set_features = ixgbevf_set_features, }; static void ixgbevf_assign_netdev_ops(struct net_device *dev) @@ -3010,8 +3350,12 @@ static int __devinit ixgbevf_probe(struct pci_dev *pdev, pci_set_master(pdev); +#ifdef HAVE_TX_MQ netdev = alloc_etherdev_mq(sizeof(struct ixgbevf_adapter), MAX_TX_QUEUES); +#else + netdev = alloc_etherdev(sizeof(struct ixgbevf_adapter)); +#endif if (!netdev) { err = -ENOMEM; goto err_alloc_etherdev; @@ -3052,6 +3396,10 @@ static int __devinit ixgbevf_probe(struct pci_dev *pdev, memcpy(&hw->mbx.ops, &ixgbevf_mbx_ops, sizeof(struct ixgbe_mbx_operations)); + adapter->flags &= ~IXGBE_FLAG_RX_PS_CAPABLE; + adapter->flags &= ~IXGBE_FLAG_RX_PS_ENABLED; + adapter->flags |= IXGBE_FLAG_RX_1BUF_CAPABLE; + /* setup the private structure */ err = ixgbevf_sw_init(adapter); if (err) @@ -3110,6 +3458,8 @@ static int __devinit ixgbevf_probe(struct pci_dev *pdev, if (err) goto err_register; + adapter->netdev_registered = true; + netif_carrier_off(netdev); ixgbevf_init_last_counter_stats(adapter); @@ -3119,6 +3469,8 @@ static int __devinit ixgbevf_probe(struct pci_dev *pdev, hw_dbg(hw, "MAC: %d\n", hw->mac.type); + hw_dbg(hw, "LRO is disabled\n"); + hw_dbg(hw, "Intel(R) 82599 Virtual Function\n"); cards_found++; return 0; @@ -3158,8 +3510,10 @@ static void __devexit ixgbevf_remove(struct pci_dev *pdev) cancel_work_sync(&adapter->reset_task); cancel_work_sync(&adapter->watchdog_task); - if (netdev->reg_state == NETREG_REGISTERED) + if (adapter->netdev_registered) { unregister_netdev(netdev); + adapter->netdev_registered = false; + } ixgbevf_reset_interrupt_capability(adapter); diff --git a/trunk/drivers/net/ethernet/lantiq_etop.c b/trunk/drivers/net/ethernet/lantiq_etop.c index 003c5bc7189f..9fa39ebf545d 100644 --- a/trunk/drivers/net/ethernet/lantiq_etop.c +++ b/trunk/drivers/net/ethernet/lantiq_etop.c @@ -645,7 +645,7 @@ ltq_etop_init(struct net_device *dev) memcpy(&mac, &priv->pldata->mac, sizeof(struct sockaddr)); if (!is_valid_ether_addr(mac.sa_data)) { pr_warn("etop: invalid MAC, using random\n"); - eth_random_addr(mac.sa_data); + random_ether_addr(mac.sa_data); random_mac = true; } diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/trunk/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index 4ce5ca81a010..94375a8c6d42 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/en_netdev.c @@ -503,7 +503,9 @@ static void mlx4_en_do_set_multicast(struct work_struct *work) /* remove from list */ list_del(&mclist->list); kfree(mclist); - } else if (mclist->action == MCLIST_ADD) { + } + + if (mclist->action == MCLIST_ADD) { /* attach the address */ memcpy(&mc_list[10], mclist->addr, ETH_ALEN); /* needed for B0 steering support */ diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/mcg.c b/trunk/drivers/net/ethernet/mellanox/mlx4/mcg.c index 5bac0dfafbd8..bc62f536ffae 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/mcg.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/mcg.c @@ -773,7 +773,7 @@ static int parse_trans_rule(struct mlx4_dev *dev, struct mlx4_spec_list *spec, [MLX4_NET_TRANS_RULE_ID_UDP] = sizeof(struct mlx4_net_trans_rule_hw_tcp_udp) }; - if (spec->id >= MLX4_NET_TRANS_RULE_NUM) { + if (spec->id > MLX4_NET_TRANS_RULE_NUM) { mlx4_err(dev, "Invalid network rule id. id = %d\n", spec->id); return -EINVAL; } diff --git a/trunk/drivers/net/ethernet/micrel/ks8851.c b/trunk/drivers/net/ethernet/micrel/ks8851.c index 1540ebeb8669..5e313e9a252f 100644 --- a/trunk/drivers/net/ethernet/micrel/ks8851.c +++ b/trunk/drivers/net/ethernet/micrel/ks8851.c @@ -422,7 +422,7 @@ static void ks8851_read_mac_addr(struct net_device *dev) * * Get or create the initial mac address for the device and then set that * into the station address register. If there is an EEPROM present, then - * we try that. If no valid mac address is found we use eth_random_addr() + * we try that. If no valid mac address is found we use random_ether_addr() * to create a new one. */ static void ks8851_init_mac(struct ks8851_net *ks) diff --git a/trunk/drivers/net/ethernet/micrel/ks8851_mll.c b/trunk/drivers/net/ethernet/micrel/ks8851_mll.c index 38529edfe350..59ef568d5dd5 100644 --- a/trunk/drivers/net/ethernet/micrel/ks8851_mll.c +++ b/trunk/drivers/net/ethernet/micrel/ks8851_mll.c @@ -1609,7 +1609,7 @@ static int __devinit ks8851_probe(struct platform_device *pdev) memcpy(ks->mac_addr, pdata->mac_addr, 6); if (!is_valid_ether_addr(ks->mac_addr)) { /* Use random MAC address if none passed */ - eth_random_addr(ks->mac_addr); + random_ether_addr(ks->mac_addr); netdev_info(netdev, "Using random mac address\n"); } netdev_info(netdev, "Mac address is: %pM\n", ks->mac_addr); diff --git a/trunk/drivers/net/ethernet/nxp/lpc_eth.c b/trunk/drivers/net/ethernet/nxp/lpc_eth.c index 4069edab229e..e7d2496a4738 100644 --- a/trunk/drivers/net/ethernet/nxp/lpc_eth.c +++ b/trunk/drivers/net/ethernet/nxp/lpc_eth.c @@ -44,6 +44,7 @@ #include #include +#include #include #include #include diff --git a/trunk/drivers/net/ethernet/smsc/smsc911x.c b/trunk/drivers/net/ethernet/smsc/smsc911x.c index 62d1baf111ea..54ca99dbb406 100644 --- a/trunk/drivers/net/ethernet/smsc/smsc911x.c +++ b/trunk/drivers/net/ethernet/smsc/smsc911x.c @@ -2488,7 +2488,7 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev) eth_hw_addr_random(dev); smsc911x_set_hw_mac_address(pdata, dev->dev_addr); SMSC_TRACE(pdata, probe, - "MAC Address is set to eth_random_addr"); + "MAC Address is set to random_ether_addr"); } } diff --git a/trunk/drivers/net/ethernet/ti/cpsw.c b/trunk/drivers/net/ethernet/ti/cpsw.c index ca381d3f9fa8..6685bbb5705a 100644 --- a/trunk/drivers/net/ethernet/ti/cpsw.c +++ b/trunk/drivers/net/ethernet/ti/cpsw.c @@ -748,7 +748,7 @@ static int __devinit cpsw_probe(struct platform_device *pdev) memcpy(priv->mac_addr, data->slave_data[0].mac_addr, ETH_ALEN); pr_info("Detected MACID = %pM", priv->mac_addr); } else { - eth_random_addr(priv->mac_addr); + random_ether_addr(priv->mac_addr); pr_info("Random MACID = %pM", priv->mac_addr); } diff --git a/trunk/drivers/net/ethernet/tile/tilegx.c b/trunk/drivers/net/ethernet/tile/tilegx.c index 7f500288f6b3..83b4b388ad49 100644 --- a/trunk/drivers/net/ethernet/tile/tilegx.c +++ b/trunk/drivers/net/ethernet/tile/tilegx.c @@ -1844,7 +1844,7 @@ static void tile_net_dev_init(const char *name, const uint8_t *mac) memcpy(dev->dev_addr, mac, 6); dev->addr_len = 6; } else { - eth_random_addr(dev->dev_addr); + random_ether_addr(dev->dev_addr); } /* Register the network device. */ diff --git a/trunk/drivers/net/ethernet/wiznet/w5100.c b/trunk/drivers/net/ethernet/wiznet/w5100.c index a5826a3111a6..a75e9ef5a4ce 100644 --- a/trunk/drivers/net/ethernet/wiznet/w5100.c +++ b/trunk/drivers/net/ethernet/wiznet/w5100.c @@ -637,7 +637,7 @@ static int __devinit w5100_hw_probe(struct platform_device *pdev) if (data && is_valid_ether_addr(data->mac_addr)) { memcpy(ndev->dev_addr, data->mac_addr, ETH_ALEN); } else { - eth_random_addr(ndev->dev_addr); + random_ether_addr(ndev->dev_addr); ndev->addr_assign_type |= NET_ADDR_RANDOM; } diff --git a/trunk/drivers/net/ethernet/wiznet/w5300.c b/trunk/drivers/net/ethernet/wiznet/w5300.c index bdd8891c215a..3306a20ec211 100644 --- a/trunk/drivers/net/ethernet/wiznet/w5300.c +++ b/trunk/drivers/net/ethernet/wiznet/w5300.c @@ -557,7 +557,7 @@ static int __devinit w5300_hw_probe(struct platform_device *pdev) if (data && is_valid_ether_addr(data->mac_addr)) { memcpy(ndev->dev_addr, data->mac_addr, ETH_ALEN); } else { - eth_random_addr(ndev->dev_addr); + random_ether_addr(ndev->dev_addr); ndev->addr_assign_type |= NET_ADDR_RANDOM; } diff --git a/trunk/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/trunk/drivers/net/ethernet/xilinx/xilinx_axienet_main.c index 0793299bd39e..9c365e192a31 100644 --- a/trunk/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +++ b/trunk/drivers/net/ethernet/xilinx/xilinx_axienet_main.c @@ -312,7 +312,7 @@ static void axienet_set_mac_address(struct net_device *ndev, void *address) if (address) memcpy(ndev->dev_addr, address, ETH_ALEN); if (!is_valid_ether_addr(ndev->dev_addr)) - eth_random_addr(ndev->dev_addr); + random_ether_addr(ndev->dev_addr); /* Set up unicast MAC address filter set its mac address */ axienet_iow(lp, XAE_UAW0_OFFSET, diff --git a/trunk/drivers/net/hyperv/hyperv_net.h b/trunk/drivers/net/hyperv/hyperv_net.h index 95ceb3593043..2857ab078aac 100644 --- a/trunk/drivers/net/hyperv/hyperv_net.h +++ b/trunk/drivers/net/hyperv/hyperv_net.h @@ -131,7 +131,6 @@ int rndis_filter_send(struct hv_device *dev, struct hv_netvsc_packet *pkt); int rndis_filter_set_packet_filter(struct rndis_device *dev, u32 new_filter); -int rndis_filter_set_device_mac(struct hv_device *hdev, char *mac); #define NVSP_INVALID_PROTOCOL_VERSION ((u32)0xFFFFFFFF) diff --git a/trunk/drivers/net/hyperv/netvsc_drv.c b/trunk/drivers/net/hyperv/netvsc_drv.c index 8e23c084c4a7..8f8ed3320425 100644 --- a/trunk/drivers/net/hyperv/netvsc_drv.c +++ b/trunk/drivers/net/hyperv/netvsc_drv.c @@ -341,34 +341,6 @@ static int netvsc_change_mtu(struct net_device *ndev, int mtu) return 0; } - -static int netvsc_set_mac_addr(struct net_device *ndev, void *p) -{ - struct net_device_context *ndevctx = netdev_priv(ndev); - struct hv_device *hdev = ndevctx->device_ctx; - struct sockaddr *addr = p; - char save_adr[14]; - unsigned char save_aatype; - int err; - - memcpy(save_adr, ndev->dev_addr, ETH_ALEN); - save_aatype = ndev->addr_assign_type; - - err = eth_mac_addr(ndev, p); - if (err != 0) - return err; - - err = rndis_filter_set_device_mac(hdev, addr->sa_data); - if (err != 0) { - /* roll back to saved MAC */ - memcpy(ndev->dev_addr, save_adr, ETH_ALEN); - ndev->addr_assign_type = save_aatype; - } - - return err; -} - - static const struct ethtool_ops ethtool_ops = { .get_drvinfo = netvsc_get_drvinfo, .get_link = ethtool_op_get_link, @@ -381,7 +353,7 @@ static const struct net_device_ops device_ops = { .ndo_set_rx_mode = netvsc_set_multicast_list, .ndo_change_mtu = netvsc_change_mtu, .ndo_validate_addr = eth_validate_addr, - .ndo_set_mac_address = netvsc_set_mac_addr, + .ndo_set_mac_address = eth_mac_addr, }; /* diff --git a/trunk/drivers/net/hyperv/rndis_filter.c b/trunk/drivers/net/hyperv/rndis_filter.c index fbf539468205..981ebb115637 100644 --- a/trunk/drivers/net/hyperv/rndis_filter.c +++ b/trunk/drivers/net/hyperv/rndis_filter.c @@ -27,7 +27,6 @@ #include #include #include -#include #include "hyperv_net.h" @@ -48,7 +47,6 @@ struct rndis_request { struct hv_page_buffer buf; /* FIXME: We assumed a fixed size request here. */ struct rndis_message request_msg; - u8 ext[100]; }; static void rndis_filter_send_completion(void *ctx); @@ -513,83 +511,6 @@ static int rndis_filter_query_device_mac(struct rndis_device *dev) dev->hw_mac_adr, &size); } -#define NWADR_STR "NetworkAddress" -#define NWADR_STRLEN 14 - -int rndis_filter_set_device_mac(struct hv_device *hdev, char *mac) -{ - struct netvsc_device *nvdev = hv_get_drvdata(hdev); - struct rndis_device *rdev = nvdev->extension; - struct net_device *ndev = nvdev->ndev; - struct rndis_request *request; - struct rndis_set_request *set; - struct rndis_config_parameter_info *cpi; - wchar_t *cfg_nwadr, *cfg_mac; - struct rndis_set_complete *set_complete; - char macstr[2*ETH_ALEN+1]; - u32 extlen = sizeof(struct rndis_config_parameter_info) + - 2*NWADR_STRLEN + 4*ETH_ALEN; - int ret, t; - - request = get_rndis_request(rdev, RNDIS_MSG_SET, - RNDIS_MESSAGE_SIZE(struct rndis_set_request) + extlen); - if (!request) - return -ENOMEM; - - set = &request->request_msg.msg.set_req; - set->oid = RNDIS_OID_GEN_RNDIS_CONFIG_PARAMETER; - set->info_buflen = extlen; - set->info_buf_offset = sizeof(struct rndis_set_request); - set->dev_vc_handle = 0; - - cpi = (struct rndis_config_parameter_info *)((ulong)set + - set->info_buf_offset); - cpi->parameter_name_offset = - sizeof(struct rndis_config_parameter_info); - /* Multiply by 2 because host needs 2 bytes (utf16) for each char */ - cpi->parameter_name_length = 2*NWADR_STRLEN; - cpi->parameter_type = RNDIS_CONFIG_PARAM_TYPE_STRING; - cpi->parameter_value_offset = - cpi->parameter_name_offset + cpi->parameter_name_length; - /* Multiply by 4 because each MAC byte displayed as 2 utf16 chars */ - cpi->parameter_value_length = 4*ETH_ALEN; - - cfg_nwadr = (wchar_t *)((ulong)cpi + cpi->parameter_name_offset); - cfg_mac = (wchar_t *)((ulong)cpi + cpi->parameter_value_offset); - ret = utf8s_to_utf16s(NWADR_STR, NWADR_STRLEN, UTF16_HOST_ENDIAN, - cfg_nwadr, NWADR_STRLEN); - if (ret < 0) - goto cleanup; - snprintf(macstr, 2*ETH_ALEN+1, "%pm", mac); - ret = utf8s_to_utf16s(macstr, 2*ETH_ALEN, UTF16_HOST_ENDIAN, - cfg_mac, 2*ETH_ALEN); - if (ret < 0) - goto cleanup; - - ret = rndis_filter_send_request(rdev, request); - if (ret != 0) - goto cleanup; - - t = wait_for_completion_timeout(&request->wait_event, 5*HZ); - if (t == 0) { - netdev_err(ndev, "timeout before we got a set response...\n"); - /* - * can't put_rndis_request, since we may still receive a - * send-completion. - */ - return -EBUSY; - } else { - set_complete = &request->response_msg.msg.set_complete; - if (set_complete->status != RNDIS_STATUS_SUCCESS) - ret = -EINVAL; - } - -cleanup: - put_rndis_request(rdev, request); - return ret; -} - - static int rndis_filter_query_device_link_status(struct rndis_device *dev) { u32 size = sizeof(u32); diff --git a/trunk/drivers/net/team/team.c b/trunk/drivers/net/team/team.c index 1a13470dee07..3620c63f9345 100644 --- a/trunk/drivers/net/team/team.c +++ b/trunk/drivers/net/team/team.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include @@ -788,58 +787,6 @@ static void team_port_leave(struct team *team, struct team_port *port) dev_put(team->dev); } -#ifdef CONFIG_NET_POLL_CONTROLLER -static int team_port_enable_netpoll(struct team *team, struct team_port *port) -{ - struct netpoll *np; - int err; - - np = kzalloc(sizeof(*np), GFP_KERNEL); - if (!np) - return -ENOMEM; - - err = __netpoll_setup(np, port->dev); - if (err) { - kfree(np); - return err; - } - port->np = np; - return err; -} - -static void team_port_disable_netpoll(struct team_port *port) -{ - struct netpoll *np = port->np; - - if (!np) - return; - port->np = NULL; - - /* Wait for transmitting packets to finish before freeing. */ - synchronize_rcu_bh(); - __netpoll_cleanup(np); - kfree(np); -} - -static struct netpoll_info *team_netpoll_info(struct team *team) -{ - return team->dev->npinfo; -} - -#else -static int team_port_enable_netpoll(struct team *team, struct team_port *port) -{ - return 0; -} -static void team_port_disable_netpoll(struct team_port *port) -{ -} -static struct netpoll_info *team_netpoll_info(struct team *team) -{ - return NULL; -} -#endif - static void __team_port_change_check(struct team_port *port, bool linkup); static int team_port_add(struct team *team, struct net_device *port_dev) @@ -906,15 +853,6 @@ static int team_port_add(struct team *team, struct net_device *port_dev) goto err_vids_add; } - if (team_netpoll_info(team)) { - err = team_port_enable_netpoll(team, port); - if (err) { - netdev_err(dev, "Failed to enable netpoll on device %s\n", - portname); - goto err_enable_netpoll; - } - } - err = netdev_set_master(port_dev, dev); if (err) { netdev_err(dev, "Device %s failed to set master\n", portname); @@ -954,9 +892,6 @@ static int team_port_add(struct team *team, struct net_device *port_dev) netdev_set_master(port_dev, NULL); err_set_master: - team_port_disable_netpoll(port); - -err_enable_netpoll: vlan_vids_del_by_dev(port_dev, dev); err_vids_add: @@ -997,7 +932,6 @@ static int team_port_del(struct team *team, struct net_device *port_dev) list_del_rcu(&port->list); netdev_rx_handler_unregister(port_dev); netdev_set_master(port_dev, NULL); - team_port_disable_netpoll(port); vlan_vids_del_by_dev(port_dev, dev); dev_close(port_dev); team_port_leave(team, port); @@ -1373,48 +1307,6 @@ static int team_vlan_rx_kill_vid(struct net_device *dev, uint16_t vid) return 0; } -#ifdef CONFIG_NET_POLL_CONTROLLER -static void team_poll_controller(struct net_device *dev) -{ -} - -static void __team_netpoll_cleanup(struct team *team) -{ - struct team_port *port; - - list_for_each_entry(port, &team->port_list, list) - team_port_disable_netpoll(port); -} - -static void team_netpoll_cleanup(struct net_device *dev) -{ - struct team *team = netdev_priv(dev); - - mutex_lock(&team->lock); - __team_netpoll_cleanup(team); - mutex_unlock(&team->lock); -} - -static int team_netpoll_setup(struct net_device *dev, - struct netpoll_info *npifo) -{ - struct team *team = netdev_priv(dev); - struct team_port *port; - int err; - - mutex_lock(&team->lock); - list_for_each_entry(port, &team->port_list, list) { - err = team_port_enable_netpoll(team, port); - if (err) { - __team_netpoll_cleanup(team); - break; - } - } - mutex_unlock(&team->lock); - return err; -} -#endif - static int team_add_slave(struct net_device *dev, struct net_device *port_dev) { struct team *team = netdev_priv(dev); @@ -1471,11 +1363,6 @@ static const struct net_device_ops team_netdev_ops = { .ndo_get_stats64 = team_get_stats64, .ndo_vlan_rx_add_vid = team_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = team_vlan_rx_kill_vid, -#ifdef CONFIG_NET_POLL_CONTROLLER - .ndo_poll_controller = team_poll_controller, - .ndo_netpoll_setup = team_netpoll_setup, - .ndo_netpoll_cleanup = team_netpoll_cleanup, -#endif .ndo_add_slave = team_add_slave, .ndo_del_slave = team_del_slave, .ndo_fix_features = team_fix_features, diff --git a/trunk/drivers/net/team/team_mode_activebackup.c b/trunk/drivers/net/team/team_mode_activebackup.c index 6262b4defd93..253b8a5f3427 100644 --- a/trunk/drivers/net/team/team_mode_activebackup.c +++ b/trunk/drivers/net/team/team_mode_activebackup.c @@ -43,7 +43,8 @@ static bool ab_transmit(struct team *team, struct sk_buff *skb) active_port = rcu_dereference_bh(ab_priv(team)->active_port); if (unlikely(!active_port)) goto drop; - if (team_dev_queue_xmit(team, active_port, skb)) + skb->dev = active_port->dev; + if (dev_queue_xmit(skb)) return false; return true; diff --git a/trunk/drivers/net/team/team_mode_broadcast.c b/trunk/drivers/net/team/team_mode_broadcast.c index c96e4d2967f0..5562345e9cef 100644 --- a/trunk/drivers/net/team/team_mode_broadcast.c +++ b/trunk/drivers/net/team/team_mode_broadcast.c @@ -29,8 +29,8 @@ static bool bc_transmit(struct team *team, struct sk_buff *skb) if (last) { skb2 = skb_clone(skb, GFP_ATOMIC); if (skb2) { - ret = team_dev_queue_xmit(team, last, - skb2); + skb2->dev = last->dev; + ret = dev_queue_xmit(skb2); if (!sum_ret) sum_ret = ret; } @@ -39,7 +39,8 @@ static bool bc_transmit(struct team *team, struct sk_buff *skb) } } if (last) { - ret = team_dev_queue_xmit(team, last, skb); + skb->dev = last->dev; + ret = dev_queue_xmit(skb); if (!sum_ret) sum_ret = ret; } diff --git a/trunk/drivers/net/team/team_mode_loadbalance.c b/trunk/drivers/net/team/team_mode_loadbalance.c index cdc31b5ea15e..51a4b199c75c 100644 --- a/trunk/drivers/net/team/team_mode_loadbalance.c +++ b/trunk/drivers/net/team/team_mode_loadbalance.c @@ -217,7 +217,8 @@ static bool lb_transmit(struct team *team, struct sk_buff *skb) port = select_tx_port_func(team, lb_priv, skb, hash); if (unlikely(!port)) goto drop; - if (team_dev_queue_xmit(team, port, skb)) + skb->dev = port->dev; + if (dev_queue_xmit(skb)) return false; lb_update_tx_stats(tx_bytes, lb_priv, get_lb_port_priv(port), hash); return true; diff --git a/trunk/drivers/net/team/team_mode_roundrobin.c b/trunk/drivers/net/team/team_mode_roundrobin.c index ad7ed0ec544c..0cf38e9b9d26 100644 --- a/trunk/drivers/net/team/team_mode_roundrobin.c +++ b/trunk/drivers/net/team/team_mode_roundrobin.c @@ -55,7 +55,8 @@ static bool rr_transmit(struct team *team, struct sk_buff *skb) port = __get_first_port_up(team, port); if (unlikely(!port)) goto drop; - if (team_dev_queue_xmit(team, port, skb)) + skb->dev = port->dev; + if (dev_queue_xmit(skb)) return false; return true; diff --git a/trunk/drivers/net/tun.c b/trunk/drivers/net/tun.c index 961fad1f7053..987aeefbc774 100644 --- a/trunk/drivers/net/tun.c +++ b/trunk/drivers/net/tun.c @@ -22,7 +22,7 @@ * Add TUNSETLINK ioctl to set the link encapsulation * * Mark Smith - * Use eth_random_addr() for tap MAC address. + * Use random_ether_addr() for tap MAC address. * * Harald Roelle 2004/04/20 * Fixes in packet dropping, queue length setting and queue wakeup. diff --git a/trunk/drivers/net/usb/Makefile b/trunk/drivers/net/usb/Makefile index bf063008c1af..a2e2d72c52a0 100644 --- a/trunk/drivers/net/usb/Makefile +++ b/trunk/drivers/net/usb/Makefile @@ -8,7 +8,6 @@ obj-$(CONFIG_USB_PEGASUS) += pegasus.o obj-$(CONFIG_USB_RTL8150) += rtl8150.o obj-$(CONFIG_USB_HSO) += hso.o obj-$(CONFIG_USB_NET_AX8817X) += asix.o -asix-y := asix_devices.o asix_common.o ax88172a.o obj-$(CONFIG_USB_NET_CDCETHER) += cdc_ether.o obj-$(CONFIG_USB_NET_CDC_EEM) += cdc_eem.o obj-$(CONFIG_USB_NET_DM9601) += dm9601.o diff --git a/trunk/drivers/net/usb/asix_devices.c b/trunk/drivers/net/usb/asix.c similarity index 61% rename from trunk/drivers/net/usb/asix_devices.c rename to trunk/drivers/net/usb/asix.c index ed9403b0c437..6564c32d3af0 100644 --- a/trunk/drivers/net/usb/asix_devices.c +++ b/trunk/drivers/net/usb/asix.c @@ -20,7 +20,137 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "asix.h" +// #define DEBUG // error path messages, extra info +// #define VERBOSE // more; success messages + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRIVER_VERSION "22-Dec-2011" +#define DRIVER_NAME "asix" + +/* ASIX AX8817X based USB 2.0 Ethernet Devices */ + +#define AX_CMD_SET_SW_MII 0x06 +#define AX_CMD_READ_MII_REG 0x07 +#define AX_CMD_WRITE_MII_REG 0x08 +#define AX_CMD_SET_HW_MII 0x0a +#define AX_CMD_READ_EEPROM 0x0b +#define AX_CMD_WRITE_EEPROM 0x0c +#define AX_CMD_WRITE_ENABLE 0x0d +#define AX_CMD_WRITE_DISABLE 0x0e +#define AX_CMD_READ_RX_CTL 0x0f +#define AX_CMD_WRITE_RX_CTL 0x10 +#define AX_CMD_READ_IPG012 0x11 +#define AX_CMD_WRITE_IPG0 0x12 +#define AX_CMD_WRITE_IPG1 0x13 +#define AX_CMD_READ_NODE_ID 0x13 +#define AX_CMD_WRITE_NODE_ID 0x14 +#define AX_CMD_WRITE_IPG2 0x14 +#define AX_CMD_WRITE_MULTI_FILTER 0x16 +#define AX88172_CMD_READ_NODE_ID 0x17 +#define AX_CMD_READ_PHY_ID 0x19 +#define AX_CMD_READ_MEDIUM_STATUS 0x1a +#define AX_CMD_WRITE_MEDIUM_MODE 0x1b +#define AX_CMD_READ_MONITOR_MODE 0x1c +#define AX_CMD_WRITE_MONITOR_MODE 0x1d +#define AX_CMD_READ_GPIOS 0x1e +#define AX_CMD_WRITE_GPIOS 0x1f +#define AX_CMD_SW_RESET 0x20 +#define AX_CMD_SW_PHY_STATUS 0x21 +#define AX_CMD_SW_PHY_SELECT 0x22 + +#define AX_MONITOR_MODE 0x01 +#define AX_MONITOR_LINK 0x02 +#define AX_MONITOR_MAGIC 0x04 +#define AX_MONITOR_HSFS 0x10 + +/* AX88172 Medium Status Register values */ +#define AX88172_MEDIUM_FD 0x02 +#define AX88172_MEDIUM_TX 0x04 +#define AX88172_MEDIUM_FC 0x10 +#define AX88172_MEDIUM_DEFAULT \ + ( AX88172_MEDIUM_FD | AX88172_MEDIUM_TX | AX88172_MEDIUM_FC ) + +#define AX_MCAST_FILTER_SIZE 8 +#define AX_MAX_MCAST 64 + +#define AX_SWRESET_CLEAR 0x00 +#define AX_SWRESET_RR 0x01 +#define AX_SWRESET_RT 0x02 +#define AX_SWRESET_PRTE 0x04 +#define AX_SWRESET_PRL 0x08 +#define AX_SWRESET_BZ 0x10 +#define AX_SWRESET_IPRL 0x20 +#define AX_SWRESET_IPPD 0x40 + +#define AX88772_IPG0_DEFAULT 0x15 +#define AX88772_IPG1_DEFAULT 0x0c +#define AX88772_IPG2_DEFAULT 0x12 + +/* AX88772 & AX88178 Medium Mode Register */ +#define AX_MEDIUM_PF 0x0080 +#define AX_MEDIUM_JFE 0x0040 +#define AX_MEDIUM_TFC 0x0020 +#define AX_MEDIUM_RFC 0x0010 +#define AX_MEDIUM_ENCK 0x0008 +#define AX_MEDIUM_AC 0x0004 +#define AX_MEDIUM_FD 0x0002 +#define AX_MEDIUM_GM 0x0001 +#define AX_MEDIUM_SM 0x1000 +#define AX_MEDIUM_SBP 0x0800 +#define AX_MEDIUM_PS 0x0200 +#define AX_MEDIUM_RE 0x0100 + +#define AX88178_MEDIUM_DEFAULT \ + (AX_MEDIUM_PS | AX_MEDIUM_FD | AX_MEDIUM_AC | \ + AX_MEDIUM_RFC | AX_MEDIUM_TFC | AX_MEDIUM_JFE | \ + AX_MEDIUM_RE) + +#define AX88772_MEDIUM_DEFAULT \ + (AX_MEDIUM_FD | AX_MEDIUM_RFC | \ + AX_MEDIUM_TFC | AX_MEDIUM_PS | \ + AX_MEDIUM_AC | AX_MEDIUM_RE) + +/* AX88772 & AX88178 RX_CTL values */ +#define AX_RX_CTL_SO 0x0080 +#define AX_RX_CTL_AP 0x0020 +#define AX_RX_CTL_AM 0x0010 +#define AX_RX_CTL_AB 0x0008 +#define AX_RX_CTL_SEP 0x0004 +#define AX_RX_CTL_AMALL 0x0002 +#define AX_RX_CTL_PRO 0x0001 +#define AX_RX_CTL_MFB_2048 0x0000 +#define AX_RX_CTL_MFB_4096 0x0100 +#define AX_RX_CTL_MFB_8192 0x0200 +#define AX_RX_CTL_MFB_16384 0x0300 + +#define AX_DEFAULT_RX_CTL (AX_RX_CTL_SO | AX_RX_CTL_AB) + +/* GPIO 0 .. 2 toggles */ +#define AX_GPIO_GPO0EN 0x01 /* GPIO0 Output enable */ +#define AX_GPIO_GPO_0 0x02 /* GPIO0 Output value */ +#define AX_GPIO_GPO1EN 0x04 /* GPIO1 Output enable */ +#define AX_GPIO_GPO_1 0x08 /* GPIO1 Output value */ +#define AX_GPIO_GPO2EN 0x10 /* GPIO2 Output enable */ +#define AX_GPIO_GPO_2 0x20 /* GPIO2 Output value */ +#define AX_GPIO_RESERVED 0x40 /* Reserved */ +#define AX_GPIO_RSE 0x80 /* Reload serial EEPROM */ + +#define AX_EEPROM_MAGIC 0xdeadbeef +#define AX88172_EEPROM_LEN 0x40 +#define AX88772_EEPROM_LEN 0xff #define PHY_MODE_MARVELL 0x0000 #define MII_MARVELL_LED_CTRL 0x0018 @@ -36,6 +166,15 @@ #define PHY_MODE_RTL8211CL 0x000C +/* This structure cannot exceed sizeof(unsigned long [5]) AKA 20 bytes */ +struct asix_data { + u8 multi_filter[AX_MCAST_FILTER_SIZE]; + u8 mac_addr[ETH_ALEN]; + u8 phymode; + u8 ledmode; + u8 eeprom_len; +}; + struct ax88172_int_data { __le16 res1; u8 link; @@ -44,6 +183,225 @@ struct ax88172_int_data { __le16 res3; } __packed; +static int asix_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, + u16 size, void *data) +{ + void *buf; + int err = -ENOMEM; + + netdev_dbg(dev->net, "asix_read_cmd() cmd=0x%02x value=0x%04x index=0x%04x size=%d\n", + cmd, value, index, size); + + buf = kmalloc(size, GFP_KERNEL); + if (!buf) + goto out; + + err = usb_control_msg( + dev->udev, + usb_rcvctrlpipe(dev->udev, 0), + cmd, + USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + value, + index, + buf, + size, + USB_CTRL_GET_TIMEOUT); + if (err == size) + memcpy(data, buf, size); + else if (err >= 0) + err = -EINVAL; + kfree(buf); + +out: + return err; +} + +static int asix_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, + u16 size, void *data) +{ + void *buf = NULL; + int err = -ENOMEM; + + netdev_dbg(dev->net, "asix_write_cmd() cmd=0x%02x value=0x%04x index=0x%04x size=%d\n", + cmd, value, index, size); + + if (data) { + buf = kmemdup(data, size, GFP_KERNEL); + if (!buf) + goto out; + } + + err = usb_control_msg( + dev->udev, + usb_sndctrlpipe(dev->udev, 0), + cmd, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + value, + index, + buf, + size, + USB_CTRL_SET_TIMEOUT); + kfree(buf); + +out: + return err; +} + +static void asix_async_cmd_callback(struct urb *urb) +{ + struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)urb->context; + int status = urb->status; + + if (status < 0) + printk(KERN_DEBUG "asix_async_cmd_callback() failed with %d", + status); + + kfree(req); + usb_free_urb(urb); +} + +static void +asix_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, u16 index, + u16 size, void *data) +{ + struct usb_ctrlrequest *req; + int status; + struct urb *urb; + + netdev_dbg(dev->net, "asix_write_cmd_async() cmd=0x%02x value=0x%04x index=0x%04x size=%d\n", + cmd, value, index, size); + + urb = usb_alloc_urb(0, GFP_ATOMIC); + if (!urb) { + netdev_err(dev->net, "Error allocating URB in write_cmd_async!\n"); + return; + } + + req = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC); + if (!req) { + netdev_err(dev->net, "Failed to allocate memory for control request\n"); + usb_free_urb(urb); + return; + } + + req->bRequestType = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE; + req->bRequest = cmd; + req->wValue = cpu_to_le16(value); + req->wIndex = cpu_to_le16(index); + req->wLength = cpu_to_le16(size); + + usb_fill_control_urb(urb, dev->udev, + usb_sndctrlpipe(dev->udev, 0), + (void *)req, data, size, + asix_async_cmd_callback, req); + + status = usb_submit_urb(urb, GFP_ATOMIC); + if (status < 0) { + netdev_err(dev->net, "Error submitting the control message: status=%d\n", + status); + kfree(req); + usb_free_urb(urb); + } +} + +static int asix_rx_fixup(struct usbnet *dev, struct sk_buff *skb) +{ + int offset = 0; + + while (offset + sizeof(u32) < skb->len) { + struct sk_buff *ax_skb; + u16 size; + u32 header = get_unaligned_le32(skb->data + offset); + + offset += sizeof(u32); + + /* get the packet length */ + size = (u16) (header & 0x7ff); + if (size != ((~header >> 16) & 0x07ff)) { + netdev_err(dev->net, "asix_rx_fixup() Bad Header Length\n"); + return 0; + } + + if ((size > dev->net->mtu + ETH_HLEN + VLAN_HLEN) || + (size + offset > skb->len)) { + netdev_err(dev->net, "asix_rx_fixup() Bad RX Length %d\n", + size); + return 0; + } + ax_skb = netdev_alloc_skb_ip_align(dev->net, size); + if (!ax_skb) + return 0; + + skb_put(ax_skb, size); + memcpy(ax_skb->data, skb->data + offset, size); + usbnet_skb_return(dev, ax_skb); + + offset += (size + 1) & 0xfffe; + } + + if (skb->len != offset) { + netdev_err(dev->net, "asix_rx_fixup() Bad SKB Length %d\n", + skb->len); + return 0; + } + return 1; +} + +static struct sk_buff *asix_tx_fixup(struct usbnet *dev, struct sk_buff *skb, + gfp_t flags) +{ + int padlen; + int headroom = skb_headroom(skb); + int tailroom = skb_tailroom(skb); + u32 packet_len; + u32 padbytes = 0xffff0000; + + padlen = ((skb->len + 4) & (dev->maxpacket - 1)) ? 0 : 4; + + /* We need to push 4 bytes in front of frame (packet_len) + * and maybe add 4 bytes after the end (if padlen is 4) + * + * Avoid skb_copy_expand() expensive call, using following rules : + * - We are allowed to push 4 bytes in headroom if skb_header_cloned() + * is false (and if we have 4 bytes of headroom) + * - We are allowed to put 4 bytes at tail if skb_cloned() + * is false (and if we have 4 bytes of tailroom) + * + * TCP packets for example are cloned, but skb_header_release() + * was called in tcp stack, allowing us to use headroom for our needs. + */ + if (!skb_header_cloned(skb) && + !(padlen && skb_cloned(skb)) && + headroom + tailroom >= 4 + padlen) { + /* following should not happen, but better be safe */ + if (headroom < 4 || + tailroom < padlen) { + skb->data = memmove(skb->head + 4, skb->data, skb->len); + skb_set_tail_pointer(skb, skb->len); + } + } else { + struct sk_buff *skb2; + + skb2 = skb_copy_expand(skb, 4, padlen, flags); + dev_kfree_skb_any(skb); + skb = skb2; + if (!skb) + return NULL; + } + + packet_len = ((skb->len ^ 0x0000ffff) << 16) + skb->len; + skb_push(skb, 4); + cpu_to_le32s(&packet_len); + skb_copy_to_linear_data(skb, &packet_len, sizeof(packet_len)); + + if (padlen) { + cpu_to_le32s(&padbytes); + memcpy(skb_tail_pointer(skb), &padbytes, sizeof(padbytes)); + skb_put(skb, sizeof(padbytes)); + } + return skb; +} + static void asix_status(struct usbnet *dev, struct urb *urb) { struct ax88172_int_data *event; @@ -64,6 +422,200 @@ static void asix_status(struct usbnet *dev, struct urb *urb) } } +static inline int asix_set_sw_mii(struct usbnet *dev) +{ + int ret; + ret = asix_write_cmd(dev, AX_CMD_SET_SW_MII, 0x0000, 0, 0, NULL); + if (ret < 0) + netdev_err(dev->net, "Failed to enable software MII access\n"); + return ret; +} + +static inline int asix_set_hw_mii(struct usbnet *dev) +{ + int ret; + ret = asix_write_cmd(dev, AX_CMD_SET_HW_MII, 0x0000, 0, 0, NULL); + if (ret < 0) + netdev_err(dev->net, "Failed to enable hardware MII access\n"); + return ret; +} + +static inline int asix_get_phy_addr(struct usbnet *dev) +{ + u8 buf[2]; + int ret = asix_read_cmd(dev, AX_CMD_READ_PHY_ID, 0, 0, 2, buf); + + netdev_dbg(dev->net, "asix_get_phy_addr()\n"); + + if (ret < 0) { + netdev_err(dev->net, "Error reading PHYID register: %02x\n", ret); + goto out; + } + netdev_dbg(dev->net, "asix_get_phy_addr() returning 0x%04x\n", + *((__le16 *)buf)); + ret = buf[1]; + +out: + return ret; +} + +static int asix_sw_reset(struct usbnet *dev, u8 flags) +{ + int ret; + + ret = asix_write_cmd(dev, AX_CMD_SW_RESET, flags, 0, 0, NULL); + if (ret < 0) + netdev_err(dev->net, "Failed to send software reset: %02x\n", ret); + + return ret; +} + +static u16 asix_read_rx_ctl(struct usbnet *dev) +{ + __le16 v; + int ret = asix_read_cmd(dev, AX_CMD_READ_RX_CTL, 0, 0, 2, &v); + + if (ret < 0) { + netdev_err(dev->net, "Error reading RX_CTL register: %02x\n", ret); + goto out; + } + ret = le16_to_cpu(v); +out: + return ret; +} + +static int asix_write_rx_ctl(struct usbnet *dev, u16 mode) +{ + int ret; + + netdev_dbg(dev->net, "asix_write_rx_ctl() - mode = 0x%04x\n", mode); + ret = asix_write_cmd(dev, AX_CMD_WRITE_RX_CTL, mode, 0, 0, NULL); + if (ret < 0) + netdev_err(dev->net, "Failed to write RX_CTL mode to 0x%04x: %02x\n", + mode, ret); + + return ret; +} + +static u16 asix_read_medium_status(struct usbnet *dev) +{ + __le16 v; + int ret = asix_read_cmd(dev, AX_CMD_READ_MEDIUM_STATUS, 0, 0, 2, &v); + + if (ret < 0) { + netdev_err(dev->net, "Error reading Medium Status register: %02x\n", + ret); + return ret; /* TODO: callers not checking for error ret */ + } + + return le16_to_cpu(v); + +} + +static int asix_write_medium_mode(struct usbnet *dev, u16 mode) +{ + int ret; + + netdev_dbg(dev->net, "asix_write_medium_mode() - mode = 0x%04x\n", mode); + ret = asix_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, mode, 0, 0, NULL); + if (ret < 0) + netdev_err(dev->net, "Failed to write Medium Mode mode to 0x%04x: %02x\n", + mode, ret); + + return ret; +} + +static int asix_write_gpio(struct usbnet *dev, u16 value, int sleep) +{ + int ret; + + netdev_dbg(dev->net, "asix_write_gpio() - value = 0x%04x\n", value); + ret = asix_write_cmd(dev, AX_CMD_WRITE_GPIOS, value, 0, 0, NULL); + if (ret < 0) + netdev_err(dev->net, "Failed to write GPIO value 0x%04x: %02x\n", + value, ret); + + if (sleep) + msleep(sleep); + + return ret; +} + +/* + * AX88772 & AX88178 have a 16-bit RX_CTL value + */ +static void asix_set_multicast(struct net_device *net) +{ + struct usbnet *dev = netdev_priv(net); + struct asix_data *data = (struct asix_data *)&dev->data; + u16 rx_ctl = AX_DEFAULT_RX_CTL; + + if (net->flags & IFF_PROMISC) { + rx_ctl |= AX_RX_CTL_PRO; + } else if (net->flags & IFF_ALLMULTI || + netdev_mc_count(net) > AX_MAX_MCAST) { + rx_ctl |= AX_RX_CTL_AMALL; + } else if (netdev_mc_empty(net)) { + /* just broadcast and directed */ + } else { + /* We use the 20 byte dev->data + * for our 8 byte filter buffer + * to avoid allocating memory that + * is tricky to free later */ + struct netdev_hw_addr *ha; + u32 crc_bits; + + memset(data->multi_filter, 0, AX_MCAST_FILTER_SIZE); + + /* Build the multicast hash filter. */ + netdev_for_each_mc_addr(ha, net) { + crc_bits = ether_crc(ETH_ALEN, ha->addr) >> 26; + data->multi_filter[crc_bits >> 3] |= + 1 << (crc_bits & 7); + } + + asix_write_cmd_async(dev, AX_CMD_WRITE_MULTI_FILTER, 0, 0, + AX_MCAST_FILTER_SIZE, data->multi_filter); + + rx_ctl |= AX_RX_CTL_AM; + } + + asix_write_cmd_async(dev, AX_CMD_WRITE_RX_CTL, rx_ctl, 0, 0, NULL); +} + +static int asix_mdio_read(struct net_device *netdev, int phy_id, int loc) +{ + struct usbnet *dev = netdev_priv(netdev); + __le16 res; + + mutex_lock(&dev->phy_mutex); + asix_set_sw_mii(dev); + asix_read_cmd(dev, AX_CMD_READ_MII_REG, phy_id, + (__u16)loc, 2, &res); + asix_set_hw_mii(dev); + mutex_unlock(&dev->phy_mutex); + + netdev_dbg(dev->net, "asix_mdio_read() phy_id=0x%02x, loc=0x%02x, returns=0x%04x\n", + phy_id, loc, le16_to_cpu(res)); + + return le16_to_cpu(res); +} + +static void +asix_mdio_write(struct net_device *netdev, int phy_id, int loc, int val) +{ + struct usbnet *dev = netdev_priv(netdev); + __le16 res = cpu_to_le16(val); + + netdev_dbg(dev->net, "asix_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x\n", + phy_id, loc, val); + mutex_lock(&dev->phy_mutex); + asix_set_sw_mii(dev); + asix_write_cmd(dev, AX_CMD_WRITE_MII_REG, phy_id, (__u16)loc, 2, &res); + asix_set_hw_mii(dev); + mutex_unlock(&dev->phy_mutex); +} + /* Get the PHY Identifier from the PHYSID1 & PHYSID2 MII registers */ static u32 asix_get_phyid(struct usbnet *dev) { @@ -93,6 +645,88 @@ static u32 asix_get_phyid(struct usbnet *dev) return phy_id; } +static void +asix_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) +{ + struct usbnet *dev = netdev_priv(net); + u8 opt; + + if (asix_read_cmd(dev, AX_CMD_READ_MONITOR_MODE, 0, 0, 1, &opt) < 0) { + wolinfo->supported = 0; + wolinfo->wolopts = 0; + return; + } + wolinfo->supported = WAKE_PHY | WAKE_MAGIC; + wolinfo->wolopts = 0; + if (opt & AX_MONITOR_LINK) + wolinfo->wolopts |= WAKE_PHY; + if (opt & AX_MONITOR_MAGIC) + wolinfo->wolopts |= WAKE_MAGIC; +} + +static int +asix_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) +{ + struct usbnet *dev = netdev_priv(net); + u8 opt = 0; + + if (wolinfo->wolopts & WAKE_PHY) + opt |= AX_MONITOR_LINK; + if (wolinfo->wolopts & WAKE_MAGIC) + opt |= AX_MONITOR_MAGIC; + + if (asix_write_cmd(dev, AX_CMD_WRITE_MONITOR_MODE, + opt, 0, 0, NULL) < 0) + return -EINVAL; + + return 0; +} + +static int asix_get_eeprom_len(struct net_device *net) +{ + struct usbnet *dev = netdev_priv(net); + struct asix_data *data = (struct asix_data *)&dev->data; + + return data->eeprom_len; +} + +static int asix_get_eeprom(struct net_device *net, + struct ethtool_eeprom *eeprom, u8 *data) +{ + struct usbnet *dev = netdev_priv(net); + __le16 *ebuf = (__le16 *)data; + int i; + + /* Crude hack to ensure that we don't overwrite memory + * if an odd length is supplied + */ + if (eeprom->len % 2) + return -EINVAL; + + eeprom->magic = AX_EEPROM_MAGIC; + + /* ax8817x returns 2 bytes from eeprom on read */ + for (i=0; i < eeprom->len / 2; i++) { + if (asix_read_cmd(dev, AX_CMD_READ_EEPROM, + eeprom->offset + i, 0, 2, &ebuf[i]) < 0) + return -EINVAL; + } + return 0; +} + +static void asix_get_drvinfo (struct net_device *net, + struct ethtool_drvinfo *info) +{ + struct usbnet *dev = netdev_priv(net); + struct asix_data *data = (struct asix_data *)&dev->data; + + /* Inherit standard device info */ + usbnet_get_drvinfo(net, info); + strncpy (info->driver, DRIVER_NAME, sizeof info->driver); + strncpy (info->version, DRIVER_VERSION, sizeof info->version); + info->eedump_len = data->eeprom_len; +} + static u32 asix_get_link(struct net_device *net) { struct usbnet *dev = netdev_priv(net); @@ -107,6 +741,30 @@ static int asix_ioctl (struct net_device *net, struct ifreq *rq, int cmd) return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL); } +static int asix_set_mac_address(struct net_device *net, void *p) +{ + struct usbnet *dev = netdev_priv(net); + struct asix_data *data = (struct asix_data *)&dev->data; + struct sockaddr *addr = p; + + if (netif_running(net)) + return -EBUSY; + if (!is_valid_ether_addr(addr->sa_data)) + return -EADDRNOTAVAIL; + + memcpy(net->dev_addr, addr->sa_data, ETH_ALEN); + + /* We use the 20 byte dev->data + * for our 6 byte mac buffer + * to avoid allocating memory that + * is tricky to free later */ + memcpy(data->mac_addr, addr->sa_data, ETH_ALEN); + asix_write_cmd_async(dev, AX_CMD_WRITE_NODE_ID, 0, 0, ETH_ALEN, + data->mac_addr); + + return 0; +} + /* We need to override some ethtool_ops so we require our own structure so we don't interfere with other usbnet devices that may be connected at the same time. */ @@ -872,8 +1530,6 @@ static const struct driver_info ax88178_info = { .tx_fixup = asix_tx_fixup, }; -extern const struct driver_info ax88172a_info; - static const struct usb_device_id products [] = { { // Linksys USB200M @@ -999,10 +1655,6 @@ static const struct usb_device_id products [] = { // Asus USB Ethernet Adapter USB_DEVICE (0x0b95, 0x7e2b), .driver_info = (unsigned long) &ax88772_info, -}, { - /* ASIX 88172a demo board */ - USB_DEVICE(0x0b95, 0x172a), - .driver_info = (unsigned long) &ax88172a_info, }, { }, // END }; diff --git a/trunk/drivers/net/usb/asix.h b/trunk/drivers/net/usb/asix.h deleted file mode 100644 index 77d9e4c1e235..000000000000 --- a/trunk/drivers/net/usb/asix.h +++ /dev/null @@ -1,217 +0,0 @@ -/* - * ASIX AX8817X based USB 2.0 Ethernet Devices - * Copyright (C) 2003-2006 David Hollis - * Copyright (C) 2005 Phil Chang - * Copyright (C) 2006 James Painter - * Copyright (c) 2002-2003 TiVo Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _ASIX_H -#define _ASIX_H - -// #define DEBUG // error path messages, extra info -// #define VERBOSE // more; success messages - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DRIVER_VERSION "22-Dec-2011" -#define DRIVER_NAME "asix" - -/* ASIX AX8817X based USB 2.0 Ethernet Devices */ - -#define AX_CMD_SET_SW_MII 0x06 -#define AX_CMD_READ_MII_REG 0x07 -#define AX_CMD_WRITE_MII_REG 0x08 -#define AX_CMD_SET_HW_MII 0x0a -#define AX_CMD_READ_EEPROM 0x0b -#define AX_CMD_WRITE_EEPROM 0x0c -#define AX_CMD_WRITE_ENABLE 0x0d -#define AX_CMD_WRITE_DISABLE 0x0e -#define AX_CMD_READ_RX_CTL 0x0f -#define AX_CMD_WRITE_RX_CTL 0x10 -#define AX_CMD_READ_IPG012 0x11 -#define AX_CMD_WRITE_IPG0 0x12 -#define AX_CMD_WRITE_IPG1 0x13 -#define AX_CMD_READ_NODE_ID 0x13 -#define AX_CMD_WRITE_NODE_ID 0x14 -#define AX_CMD_WRITE_IPG2 0x14 -#define AX_CMD_WRITE_MULTI_FILTER 0x16 -#define AX88172_CMD_READ_NODE_ID 0x17 -#define AX_CMD_READ_PHY_ID 0x19 -#define AX_CMD_READ_MEDIUM_STATUS 0x1a -#define AX_CMD_WRITE_MEDIUM_MODE 0x1b -#define AX_CMD_READ_MONITOR_MODE 0x1c -#define AX_CMD_WRITE_MONITOR_MODE 0x1d -#define AX_CMD_READ_GPIOS 0x1e -#define AX_CMD_WRITE_GPIOS 0x1f -#define AX_CMD_SW_RESET 0x20 -#define AX_CMD_SW_PHY_STATUS 0x21 -#define AX_CMD_SW_PHY_SELECT 0x22 - -#define AX_PHY_SELECT_MASK (BIT(3) | BIT(2)) -#define AX_PHY_SELECT_INTERNAL 0 -#define AX_PHY_SELECT_EXTERNAL BIT(2) - -#define AX_MONITOR_MODE 0x01 -#define AX_MONITOR_LINK 0x02 -#define AX_MONITOR_MAGIC 0x04 -#define AX_MONITOR_HSFS 0x10 - -/* AX88172 Medium Status Register values */ -#define AX88172_MEDIUM_FD 0x02 -#define AX88172_MEDIUM_TX 0x04 -#define AX88172_MEDIUM_FC 0x10 -#define AX88172_MEDIUM_DEFAULT \ - ( AX88172_MEDIUM_FD | AX88172_MEDIUM_TX | AX88172_MEDIUM_FC ) - -#define AX_MCAST_FILTER_SIZE 8 -#define AX_MAX_MCAST 64 - -#define AX_SWRESET_CLEAR 0x00 -#define AX_SWRESET_RR 0x01 -#define AX_SWRESET_RT 0x02 -#define AX_SWRESET_PRTE 0x04 -#define AX_SWRESET_PRL 0x08 -#define AX_SWRESET_BZ 0x10 -#define AX_SWRESET_IPRL 0x20 -#define AX_SWRESET_IPPD 0x40 - -#define AX88772_IPG0_DEFAULT 0x15 -#define AX88772_IPG1_DEFAULT 0x0c -#define AX88772_IPG2_DEFAULT 0x12 - -/* AX88772 & AX88178 Medium Mode Register */ -#define AX_MEDIUM_PF 0x0080 -#define AX_MEDIUM_JFE 0x0040 -#define AX_MEDIUM_TFC 0x0020 -#define AX_MEDIUM_RFC 0x0010 -#define AX_MEDIUM_ENCK 0x0008 -#define AX_MEDIUM_AC 0x0004 -#define AX_MEDIUM_FD 0x0002 -#define AX_MEDIUM_GM 0x0001 -#define AX_MEDIUM_SM 0x1000 -#define AX_MEDIUM_SBP 0x0800 -#define AX_MEDIUM_PS 0x0200 -#define AX_MEDIUM_RE 0x0100 - -#define AX88178_MEDIUM_DEFAULT \ - (AX_MEDIUM_PS | AX_MEDIUM_FD | AX_MEDIUM_AC | \ - AX_MEDIUM_RFC | AX_MEDIUM_TFC | AX_MEDIUM_JFE | \ - AX_MEDIUM_RE) - -#define AX88772_MEDIUM_DEFAULT \ - (AX_MEDIUM_FD | AX_MEDIUM_RFC | \ - AX_MEDIUM_TFC | AX_MEDIUM_PS | \ - AX_MEDIUM_AC | AX_MEDIUM_RE) - -/* AX88772 & AX88178 RX_CTL values */ -#define AX_RX_CTL_SO 0x0080 -#define AX_RX_CTL_AP 0x0020 -#define AX_RX_CTL_AM 0x0010 -#define AX_RX_CTL_AB 0x0008 -#define AX_RX_CTL_SEP 0x0004 -#define AX_RX_CTL_AMALL 0x0002 -#define AX_RX_CTL_PRO 0x0001 -#define AX_RX_CTL_MFB_2048 0x0000 -#define AX_RX_CTL_MFB_4096 0x0100 -#define AX_RX_CTL_MFB_8192 0x0200 -#define AX_RX_CTL_MFB_16384 0x0300 - -#define AX_DEFAULT_RX_CTL (AX_RX_CTL_SO | AX_RX_CTL_AB) - -/* GPIO 0 .. 2 toggles */ -#define AX_GPIO_GPO0EN 0x01 /* GPIO0 Output enable */ -#define AX_GPIO_GPO_0 0x02 /* GPIO0 Output value */ -#define AX_GPIO_GPO1EN 0x04 /* GPIO1 Output enable */ -#define AX_GPIO_GPO_1 0x08 /* GPIO1 Output value */ -#define AX_GPIO_GPO2EN 0x10 /* GPIO2 Output enable */ -#define AX_GPIO_GPO_2 0x20 /* GPIO2 Output value */ -#define AX_GPIO_RESERVED 0x40 /* Reserved */ -#define AX_GPIO_RSE 0x80 /* Reload serial EEPROM */ - -#define AX_EEPROM_MAGIC 0xdeadbeef -#define AX88172_EEPROM_LEN 0x40 -#define AX88772_EEPROM_LEN 0xff - -/* This structure cannot exceed sizeof(unsigned long [5]) AKA 20 bytes */ -struct asix_data { - u8 multi_filter[AX_MCAST_FILTER_SIZE]; - u8 mac_addr[ETH_ALEN]; - u8 phymode; - u8 ledmode; - u8 eeprom_len; -}; - -int asix_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, - u16 size, void *data); - -int asix_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, - u16 size, void *data); - -void asix_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, - u16 index, u16 size, void *data); - -int asix_rx_fixup(struct usbnet *dev, struct sk_buff *skb); - -struct sk_buff *asix_tx_fixup(struct usbnet *dev, struct sk_buff *skb, - gfp_t flags); - -int asix_set_sw_mii(struct usbnet *dev); -int asix_set_hw_mii(struct usbnet *dev); - -int asix_read_phy_addr(struct usbnet *dev, int internal); -int asix_get_phy_addr(struct usbnet *dev); - -int asix_sw_reset(struct usbnet *dev, u8 flags); - -u16 asix_read_rx_ctl(struct usbnet *dev); -int asix_write_rx_ctl(struct usbnet *dev, u16 mode); - -u16 asix_read_medium_status(struct usbnet *dev); -int asix_write_medium_mode(struct usbnet *dev, u16 mode); - -int asix_write_gpio(struct usbnet *dev, u16 value, int sleep); - -void asix_set_multicast(struct net_device *net); - -int asix_mdio_read(struct net_device *netdev, int phy_id, int loc); -void asix_mdio_write(struct net_device *netdev, int phy_id, int loc, int val); - -void asix_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo); -int asix_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo); - -int asix_get_eeprom_len(struct net_device *net); -int asix_get_eeprom(struct net_device *net, struct ethtool_eeprom *eeprom, - u8 *data); - -void asix_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *info); - -int asix_set_mac_address(struct net_device *net, void *p); - -#endif /* _ASIX_H */ diff --git a/trunk/drivers/net/usb/asix_common.c b/trunk/drivers/net/usb/asix_common.c deleted file mode 100644 index 336f75567091..000000000000 --- a/trunk/drivers/net/usb/asix_common.c +++ /dev/null @@ -1,545 +0,0 @@ -/* - * ASIX AX8817X based USB 2.0 Ethernet Devices - * Copyright (C) 2003-2006 David Hollis - * Copyright (C) 2005 Phil Chang - * Copyright (C) 2006 James Painter - * Copyright (c) 2002-2003 TiVo Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "asix.h" - -int asix_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, - u16 size, void *data) -{ - void *buf; - int err = -ENOMEM; - - netdev_dbg(dev->net, "asix_read_cmd() cmd=0x%02x value=0x%04x index=0x%04x size=%d\n", - cmd, value, index, size); - - buf = kmalloc(size, GFP_KERNEL); - if (!buf) - goto out; - - err = usb_control_msg( - dev->udev, - usb_rcvctrlpipe(dev->udev, 0), - cmd, - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - value, - index, - buf, - size, - USB_CTRL_GET_TIMEOUT); - if (err == size) - memcpy(data, buf, size); - else if (err >= 0) - err = -EINVAL; - kfree(buf); - -out: - return err; -} - -int asix_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, - u16 size, void *data) -{ - void *buf = NULL; - int err = -ENOMEM; - - netdev_dbg(dev->net, "asix_write_cmd() cmd=0x%02x value=0x%04x index=0x%04x size=%d\n", - cmd, value, index, size); - - if (data) { - buf = kmemdup(data, size, GFP_KERNEL); - if (!buf) - goto out; - } - - err = usb_control_msg( - dev->udev, - usb_sndctrlpipe(dev->udev, 0), - cmd, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - value, - index, - buf, - size, - USB_CTRL_SET_TIMEOUT); - kfree(buf); - -out: - return err; -} - -static void asix_async_cmd_callback(struct urb *urb) -{ - struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)urb->context; - int status = urb->status; - - if (status < 0) - printk(KERN_DEBUG "asix_async_cmd_callback() failed with %d", - status); - - kfree(req); - usb_free_urb(urb); -} - -void asix_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, u16 index, - u16 size, void *data) -{ - struct usb_ctrlrequest *req; - int status; - struct urb *urb; - - netdev_dbg(dev->net, "asix_write_cmd_async() cmd=0x%02x value=0x%04x index=0x%04x size=%d\n", - cmd, value, index, size); - - urb = usb_alloc_urb(0, GFP_ATOMIC); - if (!urb) { - netdev_err(dev->net, "Error allocating URB in write_cmd_async!\n"); - return; - } - - req = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC); - if (!req) { - netdev_err(dev->net, "Failed to allocate memory for control request\n"); - usb_free_urb(urb); - return; - } - - req->bRequestType = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE; - req->bRequest = cmd; - req->wValue = cpu_to_le16(value); - req->wIndex = cpu_to_le16(index); - req->wLength = cpu_to_le16(size); - - usb_fill_control_urb(urb, dev->udev, - usb_sndctrlpipe(dev->udev, 0), - (void *)req, data, size, - asix_async_cmd_callback, req); - - status = usb_submit_urb(urb, GFP_ATOMIC); - if (status < 0) { - netdev_err(dev->net, "Error submitting the control message: status=%d\n", - status); - kfree(req); - usb_free_urb(urb); - } -} - -int asix_rx_fixup(struct usbnet *dev, struct sk_buff *skb) -{ - int offset = 0; - - while (offset + sizeof(u32) < skb->len) { - struct sk_buff *ax_skb; - u16 size; - u32 header = get_unaligned_le32(skb->data + offset); - - offset += sizeof(u32); - - /* get the packet length */ - size = (u16) (header & 0x7ff); - if (size != ((~header >> 16) & 0x07ff)) { - netdev_err(dev->net, "asix_rx_fixup() Bad Header Length\n"); - return 0; - } - - if ((size > dev->net->mtu + ETH_HLEN + VLAN_HLEN) || - (size + offset > skb->len)) { - netdev_err(dev->net, "asix_rx_fixup() Bad RX Length %d\n", - size); - return 0; - } - ax_skb = netdev_alloc_skb_ip_align(dev->net, size); - if (!ax_skb) - return 0; - - skb_put(ax_skb, size); - memcpy(ax_skb->data, skb->data + offset, size); - usbnet_skb_return(dev, ax_skb); - - offset += (size + 1) & 0xfffe; - } - - if (skb->len != offset) { - netdev_err(dev->net, "asix_rx_fixup() Bad SKB Length %d\n", - skb->len); - return 0; - } - return 1; -} - -struct sk_buff *asix_tx_fixup(struct usbnet *dev, struct sk_buff *skb, - gfp_t flags) -{ - int padlen; - int headroom = skb_headroom(skb); - int tailroom = skb_tailroom(skb); - u32 packet_len; - u32 padbytes = 0xffff0000; - - padlen = ((skb->len + 4) & (dev->maxpacket - 1)) ? 0 : 4; - - /* We need to push 4 bytes in front of frame (packet_len) - * and maybe add 4 bytes after the end (if padlen is 4) - * - * Avoid skb_copy_expand() expensive call, using following rules : - * - We are allowed to push 4 bytes in headroom if skb_header_cloned() - * is false (and if we have 4 bytes of headroom) - * - We are allowed to put 4 bytes at tail if skb_cloned() - * is false (and if we have 4 bytes of tailroom) - * - * TCP packets for example are cloned, but skb_header_release() - * was called in tcp stack, allowing us to use headroom for our needs. - */ - if (!skb_header_cloned(skb) && - !(padlen && skb_cloned(skb)) && - headroom + tailroom >= 4 + padlen) { - /* following should not happen, but better be safe */ - if (headroom < 4 || - tailroom < padlen) { - skb->data = memmove(skb->head + 4, skb->data, skb->len); - skb_set_tail_pointer(skb, skb->len); - } - } else { - struct sk_buff *skb2; - - skb2 = skb_copy_expand(skb, 4, padlen, flags); - dev_kfree_skb_any(skb); - skb = skb2; - if (!skb) - return NULL; - } - - packet_len = ((skb->len ^ 0x0000ffff) << 16) + skb->len; - skb_push(skb, 4); - cpu_to_le32s(&packet_len); - skb_copy_to_linear_data(skb, &packet_len, sizeof(packet_len)); - - if (padlen) { - cpu_to_le32s(&padbytes); - memcpy(skb_tail_pointer(skb), &padbytes, sizeof(padbytes)); - skb_put(skb, sizeof(padbytes)); - } - return skb; -} - -int asix_set_sw_mii(struct usbnet *dev) -{ - int ret; - ret = asix_write_cmd(dev, AX_CMD_SET_SW_MII, 0x0000, 0, 0, NULL); - if (ret < 0) - netdev_err(dev->net, "Failed to enable software MII access\n"); - return ret; -} - -int asix_set_hw_mii(struct usbnet *dev) -{ - int ret; - ret = asix_write_cmd(dev, AX_CMD_SET_HW_MII, 0x0000, 0, 0, NULL); - if (ret < 0) - netdev_err(dev->net, "Failed to enable hardware MII access\n"); - return ret; -} - -int asix_read_phy_addr(struct usbnet *dev, int internal) -{ - int offset = (internal ? 1 : 0); - u8 buf[2]; - int ret = asix_read_cmd(dev, AX_CMD_READ_PHY_ID, 0, 0, 2, buf); - - netdev_dbg(dev->net, "asix_get_phy_addr()\n"); - - if (ret < 0) { - netdev_err(dev->net, "Error reading PHYID register: %02x\n", ret); - goto out; - } - netdev_dbg(dev->net, "asix_get_phy_addr() returning 0x%04x\n", - *((__le16 *)buf)); - ret = buf[offset]; - -out: - return ret; -} - -int asix_get_phy_addr(struct usbnet *dev) -{ - /* return the address of the internal phy */ - return asix_read_phy_addr(dev, 1); -} - - -int asix_sw_reset(struct usbnet *dev, u8 flags) -{ - int ret; - - ret = asix_write_cmd(dev, AX_CMD_SW_RESET, flags, 0, 0, NULL); - if (ret < 0) - netdev_err(dev->net, "Failed to send software reset: %02x\n", ret); - - return ret; -} - -u16 asix_read_rx_ctl(struct usbnet *dev) -{ - __le16 v; - int ret = asix_read_cmd(dev, AX_CMD_READ_RX_CTL, 0, 0, 2, &v); - - if (ret < 0) { - netdev_err(dev->net, "Error reading RX_CTL register: %02x\n", ret); - goto out; - } - ret = le16_to_cpu(v); -out: - return ret; -} - -int asix_write_rx_ctl(struct usbnet *dev, u16 mode) -{ - int ret; - - netdev_dbg(dev->net, "asix_write_rx_ctl() - mode = 0x%04x\n", mode); - ret = asix_write_cmd(dev, AX_CMD_WRITE_RX_CTL, mode, 0, 0, NULL); - if (ret < 0) - netdev_err(dev->net, "Failed to write RX_CTL mode to 0x%04x: %02x\n", - mode, ret); - - return ret; -} - -u16 asix_read_medium_status(struct usbnet *dev) -{ - __le16 v; - int ret = asix_read_cmd(dev, AX_CMD_READ_MEDIUM_STATUS, 0, 0, 2, &v); - - if (ret < 0) { - netdev_err(dev->net, "Error reading Medium Status register: %02x\n", - ret); - return ret; /* TODO: callers not checking for error ret */ - } - - return le16_to_cpu(v); - -} - -int asix_write_medium_mode(struct usbnet *dev, u16 mode) -{ - int ret; - - netdev_dbg(dev->net, "asix_write_medium_mode() - mode = 0x%04x\n", mode); - ret = asix_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, mode, 0, 0, NULL); - if (ret < 0) - netdev_err(dev->net, "Failed to write Medium Mode mode to 0x%04x: %02x\n", - mode, ret); - - return ret; -} - -int asix_write_gpio(struct usbnet *dev, u16 value, int sleep) -{ - int ret; - - netdev_dbg(dev->net, "asix_write_gpio() - value = 0x%04x\n", value); - ret = asix_write_cmd(dev, AX_CMD_WRITE_GPIOS, value, 0, 0, NULL); - if (ret < 0) - netdev_err(dev->net, "Failed to write GPIO value 0x%04x: %02x\n", - value, ret); - - if (sleep) - msleep(sleep); - - return ret; -} - -/* - * AX88772 & AX88178 have a 16-bit RX_CTL value - */ -void asix_set_multicast(struct net_device *net) -{ - struct usbnet *dev = netdev_priv(net); - struct asix_data *data = (struct asix_data *)&dev->data; - u16 rx_ctl = AX_DEFAULT_RX_CTL; - - if (net->flags & IFF_PROMISC) { - rx_ctl |= AX_RX_CTL_PRO; - } else if (net->flags & IFF_ALLMULTI || - netdev_mc_count(net) > AX_MAX_MCAST) { - rx_ctl |= AX_RX_CTL_AMALL; - } else if (netdev_mc_empty(net)) { - /* just broadcast and directed */ - } else { - /* We use the 20 byte dev->data - * for our 8 byte filter buffer - * to avoid allocating memory that - * is tricky to free later */ - struct netdev_hw_addr *ha; - u32 crc_bits; - - memset(data->multi_filter, 0, AX_MCAST_FILTER_SIZE); - - /* Build the multicast hash filter. */ - netdev_for_each_mc_addr(ha, net) { - crc_bits = ether_crc(ETH_ALEN, ha->addr) >> 26; - data->multi_filter[crc_bits >> 3] |= - 1 << (crc_bits & 7); - } - - asix_write_cmd_async(dev, AX_CMD_WRITE_MULTI_FILTER, 0, 0, - AX_MCAST_FILTER_SIZE, data->multi_filter); - - rx_ctl |= AX_RX_CTL_AM; - } - - asix_write_cmd_async(dev, AX_CMD_WRITE_RX_CTL, rx_ctl, 0, 0, NULL); -} - -int asix_mdio_read(struct net_device *netdev, int phy_id, int loc) -{ - struct usbnet *dev = netdev_priv(netdev); - __le16 res; - - mutex_lock(&dev->phy_mutex); - asix_set_sw_mii(dev); - asix_read_cmd(dev, AX_CMD_READ_MII_REG, phy_id, - (__u16)loc, 2, &res); - asix_set_hw_mii(dev); - mutex_unlock(&dev->phy_mutex); - - netdev_dbg(dev->net, "asix_mdio_read() phy_id=0x%02x, loc=0x%02x, returns=0x%04x\n", - phy_id, loc, le16_to_cpu(res)); - - return le16_to_cpu(res); -} - -void asix_mdio_write(struct net_device *netdev, int phy_id, int loc, int val) -{ - struct usbnet *dev = netdev_priv(netdev); - __le16 res = cpu_to_le16(val); - - netdev_dbg(dev->net, "asix_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x\n", - phy_id, loc, val); - mutex_lock(&dev->phy_mutex); - asix_set_sw_mii(dev); - asix_write_cmd(dev, AX_CMD_WRITE_MII_REG, phy_id, (__u16)loc, 2, &res); - asix_set_hw_mii(dev); - mutex_unlock(&dev->phy_mutex); -} - -void asix_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) -{ - struct usbnet *dev = netdev_priv(net); - u8 opt; - - if (asix_read_cmd(dev, AX_CMD_READ_MONITOR_MODE, 0, 0, 1, &opt) < 0) { - wolinfo->supported = 0; - wolinfo->wolopts = 0; - return; - } - wolinfo->supported = WAKE_PHY | WAKE_MAGIC; - wolinfo->wolopts = 0; - if (opt & AX_MONITOR_LINK) - wolinfo->wolopts |= WAKE_PHY; - if (opt & AX_MONITOR_MAGIC) - wolinfo->wolopts |= WAKE_MAGIC; -} - -int asix_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) -{ - struct usbnet *dev = netdev_priv(net); - u8 opt = 0; - - if (wolinfo->wolopts & WAKE_PHY) - opt |= AX_MONITOR_LINK; - if (wolinfo->wolopts & WAKE_MAGIC) - opt |= AX_MONITOR_MAGIC; - - if (asix_write_cmd(dev, AX_CMD_WRITE_MONITOR_MODE, - opt, 0, 0, NULL) < 0) - return -EINVAL; - - return 0; -} - -int asix_get_eeprom_len(struct net_device *net) -{ - struct usbnet *dev = netdev_priv(net); - struct asix_data *data = (struct asix_data *)&dev->data; - - return data->eeprom_len; -} - -int asix_get_eeprom(struct net_device *net, struct ethtool_eeprom *eeprom, - u8 *data) -{ - struct usbnet *dev = netdev_priv(net); - __le16 *ebuf = (__le16 *)data; - int i; - - /* Crude hack to ensure that we don't overwrite memory - * if an odd length is supplied - */ - if (eeprom->len % 2) - return -EINVAL; - - eeprom->magic = AX_EEPROM_MAGIC; - - /* ax8817x returns 2 bytes from eeprom on read */ - for (i=0; i < eeprom->len / 2; i++) { - if (asix_read_cmd(dev, AX_CMD_READ_EEPROM, - eeprom->offset + i, 0, 2, &ebuf[i]) < 0) - return -EINVAL; - } - return 0; -} - -void asix_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *info) -{ - struct usbnet *dev = netdev_priv(net); - struct asix_data *data = (struct asix_data *)&dev->data; - - /* Inherit standard device info */ - usbnet_get_drvinfo(net, info); - strncpy (info->driver, DRIVER_NAME, sizeof info->driver); - strncpy (info->version, DRIVER_VERSION, sizeof info->version); - info->eedump_len = data->eeprom_len; -} - -int asix_set_mac_address(struct net_device *net, void *p) -{ - struct usbnet *dev = netdev_priv(net); - struct asix_data *data = (struct asix_data *)&dev->data; - struct sockaddr *addr = p; - - if (netif_running(net)) - return -EBUSY; - if (!is_valid_ether_addr(addr->sa_data)) - return -EADDRNOTAVAIL; - - memcpy(net->dev_addr, addr->sa_data, ETH_ALEN); - - /* We use the 20 byte dev->data - * for our 6 byte mac buffer - * to avoid allocating memory that - * is tricky to free later */ - memcpy(data->mac_addr, addr->sa_data, ETH_ALEN); - asix_write_cmd_async(dev, AX_CMD_WRITE_NODE_ID, 0, 0, ETH_ALEN, - data->mac_addr); - - return 0; -} diff --git a/trunk/drivers/net/usb/ax88172a.c b/trunk/drivers/net/usb/ax88172a.c deleted file mode 100644 index 534a144bd9e7..000000000000 --- a/trunk/drivers/net/usb/ax88172a.c +++ /dev/null @@ -1,415 +0,0 @@ -/* - * ASIX AX88172A based USB 2.0 Ethernet Devices - * Copyright (C) 2012 OMICRON electronics GmbH - * - * Supports external PHYs via phylib. Based on the driver for the - * AX88772. Original copyrights follow: - * - * Copyright (C) 2003-2006 David Hollis - * Copyright (C) 2005 Phil Chang - * Copyright (C) 2006 James Painter - * Copyright (c) 2002-2003 TiVo Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "asix.h" -#include - -struct ax88172a_private { - struct mii_bus *mdio; - struct phy_device *phydev; - char phy_name[20]; - u16 phy_addr; - u16 oldmode; - int use_embdphy; -}; - -/* MDIO read and write wrappers for phylib */ -static int asix_mdio_bus_read(struct mii_bus *bus, int phy_id, int regnum) -{ - return asix_mdio_read(((struct usbnet *)bus->priv)->net, phy_id, - regnum); -} - -static int asix_mdio_bus_write(struct mii_bus *bus, int phy_id, int regnum, - u16 val) -{ - asix_mdio_write(((struct usbnet *)bus->priv)->net, phy_id, regnum, val); - return 0; -} - -static int ax88172a_ioctl(struct net_device *net, struct ifreq *rq, int cmd) -{ - if (!netif_running(net)) - return -EINVAL; - - if (!net->phydev) - return -ENODEV; - - return phy_mii_ioctl(net->phydev, rq, cmd); -} - -/* set MAC link settings according to information from phylib */ -static void ax88172a_adjust_link(struct net_device *netdev) -{ - struct phy_device *phydev = netdev->phydev; - struct usbnet *dev = netdev_priv(netdev); - struct ax88172a_private *priv = dev->driver_priv; - u16 mode = 0; - - if (phydev->link) { - mode = AX88772_MEDIUM_DEFAULT; - - if (phydev->duplex == DUPLEX_HALF) - mode &= ~AX_MEDIUM_FD; - - if (phydev->speed != SPEED_100) - mode &= ~AX_MEDIUM_PS; - } - - if (mode != priv->oldmode) { - asix_write_medium_mode(dev, mode); - priv->oldmode = mode; - netdev_dbg(netdev, "speed %u duplex %d, setting mode to 0x%04x\n", - phydev->speed, phydev->duplex, mode); - phy_print_status(phydev); - } -} - -static void ax88172a_status(struct usbnet *dev, struct urb *urb) -{ - /* link changes are detected by polling the phy */ -} - -/* use phylib infrastructure */ -static int ax88172a_init_mdio(struct usbnet *dev) -{ - struct ax88172a_private *priv = dev->driver_priv; - int ret, i; - - priv->mdio = mdiobus_alloc(); - if (!priv->mdio) { - netdev_err(dev->net, "Could not allocate MDIO bus\n"); - return -ENOMEM; - } - - priv->mdio->priv = (void *)dev; - priv->mdio->read = &asix_mdio_bus_read; - priv->mdio->write = &asix_mdio_bus_write; - priv->mdio->name = "Asix MDIO Bus"; - /* mii bus name is usb-- */ - snprintf(priv->mdio->id, MII_BUS_ID_SIZE, "usb-%03d:%03d", - dev->udev->bus->busnum, dev->udev->devnum); - - priv->mdio->irq = kzalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL); - if (!priv->mdio->irq) { - netdev_err(dev->net, "Could not allocate mdio->irq\n"); - ret = -ENOMEM; - goto mfree; - } - for (i = 0; i < PHY_MAX_ADDR; i++) - priv->mdio->irq[i] = PHY_POLL; - - ret = mdiobus_register(priv->mdio); - if (ret) { - netdev_err(dev->net, "Could not register MDIO bus\n"); - goto ifree; - } - - netdev_info(dev->net, "registered mdio bus %s\n", priv->mdio->id); - return 0; - -ifree: - kfree(priv->mdio->irq); -mfree: - mdiobus_free(priv->mdio); - return ret; -} - -static void ax88172a_remove_mdio(struct usbnet *dev) -{ - struct ax88172a_private *priv = dev->driver_priv; - - netdev_info(dev->net, "deregistering mdio bus %s\n", priv->mdio->id); - mdiobus_unregister(priv->mdio); - kfree(priv->mdio->irq); - mdiobus_free(priv->mdio); -} - -static const struct net_device_ops ax88172a_netdev_ops = { - .ndo_open = usbnet_open, - .ndo_stop = usbnet_stop, - .ndo_start_xmit = usbnet_start_xmit, - .ndo_tx_timeout = usbnet_tx_timeout, - .ndo_change_mtu = usbnet_change_mtu, - .ndo_set_mac_address = asix_set_mac_address, - .ndo_validate_addr = eth_validate_addr, - .ndo_do_ioctl = ax88172a_ioctl, - .ndo_set_rx_mode = asix_set_multicast, -}; - -int ax88172a_get_settings(struct net_device *net, struct ethtool_cmd *cmd) -{ - if (!net->phydev) - return -ENODEV; - - return phy_ethtool_gset(net->phydev, cmd); -} - -int ax88172a_set_settings(struct net_device *net, struct ethtool_cmd *cmd) -{ - if (!net->phydev) - return -ENODEV; - - return phy_ethtool_sset(net->phydev, cmd); -} - -int ax88172a_nway_reset(struct net_device *net) -{ - if (!net->phydev) - return -ENODEV; - - return phy_start_aneg(net->phydev); -} - -static const struct ethtool_ops ax88172a_ethtool_ops = { - .get_drvinfo = asix_get_drvinfo, - .get_link = usbnet_get_link, - .get_msglevel = usbnet_get_msglevel, - .set_msglevel = usbnet_set_msglevel, - .get_wol = asix_get_wol, - .set_wol = asix_set_wol, - .get_eeprom_len = asix_get_eeprom_len, - .get_eeprom = asix_get_eeprom, - .get_settings = ax88172a_get_settings, - .set_settings = ax88172a_set_settings, - .nway_reset = ax88172a_nway_reset, -}; - -static int ax88172a_reset_phy(struct usbnet *dev, int embd_phy) -{ - int ret; - - ret = asix_sw_reset(dev, AX_SWRESET_IPPD); - if (ret < 0) - goto err; - - msleep(150); - ret = asix_sw_reset(dev, AX_SWRESET_CLEAR); - if (ret < 0) - goto err; - - msleep(150); - - ret = asix_sw_reset(dev, embd_phy ? AX_SWRESET_IPRL : AX_SWRESET_IPPD); - if (ret < 0) - goto err; - - return 0; - -err: - return ret; -} - - -static int ax88172a_bind(struct usbnet *dev, struct usb_interface *intf) -{ - int ret; - struct asix_data *data = (struct asix_data *)&dev->data; - u8 buf[ETH_ALEN]; - struct ax88172a_private *priv; - - data->eeprom_len = AX88772_EEPROM_LEN; - - usbnet_get_endpoints(dev, intf); - - priv = kzalloc(sizeof(*priv), GFP_KERNEL); - if (!priv) { - netdev_err(dev->net, "Could not allocate memory for private data\n"); - return -ENOMEM; - } - dev->driver_priv = priv; - - /* Get the MAC address */ - ret = asix_read_cmd(dev, AX_CMD_READ_NODE_ID, 0, 0, ETH_ALEN, buf); - if (ret < 0) { - netdev_err(dev->net, "Failed to read MAC address: %d\n", ret); - goto free; - } - memcpy(dev->net->dev_addr, buf, ETH_ALEN); - - dev->net->netdev_ops = &ax88172a_netdev_ops; - dev->net->ethtool_ops = &ax88172a_ethtool_ops; - - /* are we using the internal or the external phy? */ - ret = asix_read_cmd(dev, AX_CMD_SW_PHY_STATUS, 0, 0, 1, buf); - if (ret < 0) { - netdev_err(dev->net, "Failed to read software interface selection register: %d\n", - ret); - goto free; - } - - netdev_dbg(dev->net, "AX_CMD_SW_PHY_STATUS = 0x%02x\n", buf[0]); - switch (buf[0] & AX_PHY_SELECT_MASK) { - case AX_PHY_SELECT_INTERNAL: - netdev_dbg(dev->net, "use internal phy\n"); - priv->use_embdphy = 1; - break; - case AX_PHY_SELECT_EXTERNAL: - netdev_dbg(dev->net, "use external phy\n"); - priv->use_embdphy = 0; - break; - default: - netdev_err(dev->net, "Interface mode not supported by driver\n"); - goto free; - } - - priv->phy_addr = asix_read_phy_addr(dev, priv->use_embdphy); - ax88172a_reset_phy(dev, priv->use_embdphy); - - /* Asix framing packs multiple eth frames into a 2K usb bulk transfer */ - if (dev->driver_info->flags & FLAG_FRAMING_AX) { - /* hard_mtu is still the default - the device does not support - jumbo eth frames */ - dev->rx_urb_size = 2048; - } - - /* init MDIO bus */ - ret = ax88172a_init_mdio(dev); - if (ret) - goto free; - - return 0; - -free: - kfree(priv); - return ret; -} - -static int ax88172a_stop(struct usbnet *dev) -{ - struct ax88172a_private *priv = dev->driver_priv; - - netdev_dbg(dev->net, "Stopping interface\n"); - - if (priv->phydev) { - netdev_info(dev->net, "Disconnecting from phy %s\n", - priv->phy_name); - phy_stop(priv->phydev); - phy_disconnect(priv->phydev); - } - - return 0; -} - -static void ax88172a_unbind(struct usbnet *dev, struct usb_interface *intf) -{ - struct ax88172a_private *priv = dev->driver_priv; - - ax88172a_remove_mdio(dev); - kfree(priv); -} - -static int ax88172a_reset(struct usbnet *dev) -{ - struct asix_data *data = (struct asix_data *)&dev->data; - struct ax88172a_private *priv = dev->driver_priv; - int ret; - u16 rx_ctl; - - ax88172a_reset_phy(dev, priv->use_embdphy); - - msleep(150); - rx_ctl = asix_read_rx_ctl(dev); - netdev_dbg(dev->net, "RX_CTL is 0x%04x after software reset\n", rx_ctl); - ret = asix_write_rx_ctl(dev, 0x0000); - if (ret < 0) - goto out; - - rx_ctl = asix_read_rx_ctl(dev); - netdev_dbg(dev->net, "RX_CTL is 0x%04x setting to 0x0000\n", rx_ctl); - - msleep(150); - - ret = asix_write_cmd(dev, AX_CMD_WRITE_IPG0, - AX88772_IPG0_DEFAULT | AX88772_IPG1_DEFAULT, - AX88772_IPG2_DEFAULT, 0, NULL); - if (ret < 0) { - netdev_err(dev->net, "Write IPG,IPG1,IPG2 failed: %d\n", ret); - goto out; - } - - /* Rewrite MAC address */ - memcpy(data->mac_addr, dev->net->dev_addr, ETH_ALEN); - ret = asix_write_cmd(dev, AX_CMD_WRITE_NODE_ID, 0, 0, ETH_ALEN, - data->mac_addr); - if (ret < 0) - goto out; - - /* Set RX_CTL to default values with 2k buffer, and enable cactus */ - ret = asix_write_rx_ctl(dev, AX_DEFAULT_RX_CTL); - if (ret < 0) - goto out; - - rx_ctl = asix_read_rx_ctl(dev); - netdev_dbg(dev->net, "RX_CTL is 0x%04x after all initializations\n", - rx_ctl); - - rx_ctl = asix_read_medium_status(dev); - netdev_dbg(dev->net, "Medium Status is 0x%04x after all initializations\n", - rx_ctl); - - /* Connect to PHY */ - snprintf(priv->phy_name, 20, PHY_ID_FMT, - priv->mdio->id, priv->phy_addr); - - priv->phydev = phy_connect(dev->net, priv->phy_name, - &ax88172a_adjust_link, - 0, PHY_INTERFACE_MODE_MII); - if (IS_ERR(priv->phydev)) { - netdev_err(dev->net, "Could not connect to PHY device %s\n", - priv->phy_name); - ret = PTR_ERR(priv->phydev); - goto out; - } - - netdev_info(dev->net, "Connected to phy %s\n", priv->phy_name); - - /* During power-up, the AX88172A set the power down (BMCR_PDOWN) - * bit of the PHY. Bring the PHY up again. - */ - genphy_resume(priv->phydev); - phy_start(priv->phydev); - - return 0; - -out: - return ret; - -} - -const struct driver_info ax88172a_info = { - .description = "ASIX AX88172A USB 2.0 Ethernet", - .bind = ax88172a_bind, - .reset = ax88172a_reset, - .stop = ax88172a_stop, - .unbind = ax88172a_unbind, - .status = ax88172a_status, - .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR | - FLAG_MULTI_PACKET, - .rx_fixup = asix_rx_fixup, - .tx_fixup = asix_tx_fixup, -}; diff --git a/trunk/drivers/net/usb/smsc75xx.c b/trunk/drivers/net/usb/smsc75xx.c index 6c0c5b76fc41..1c6e51588da7 100644 --- a/trunk/drivers/net/usb/smsc75xx.c +++ b/trunk/drivers/net/usb/smsc75xx.c @@ -616,7 +616,7 @@ static void smsc75xx_init_mac_address(struct usbnet *dev) /* no eeprom, or eeprom values are invalid. generate random MAC */ eth_hw_addr_random(dev->net); - netif_dbg(dev, ifup, dev->net, "MAC address set to eth_random_addr"); + netif_dbg(dev, ifup, dev->net, "MAC address set to random_ether_addr"); } static int smsc75xx_set_mac_address(struct usbnet *dev) diff --git a/trunk/drivers/net/usb/smsc95xx.c b/trunk/drivers/net/usb/smsc95xx.c index 25cc3a15a4ea..bd7cbaa688e4 100644 --- a/trunk/drivers/net/usb/smsc95xx.c +++ b/trunk/drivers/net/usb/smsc95xx.c @@ -647,7 +647,7 @@ static void smsc95xx_init_mac_address(struct usbnet *dev) /* no eeprom, or eeprom values are invalid. generate random MAC */ eth_hw_addr_random(dev->net); - netif_dbg(dev, ifup, dev->net, "MAC address set to eth_random_addr\n"); + netif_dbg(dev, ifup, dev->net, "MAC address set to random_ether_addr\n"); } static int smsc95xx_set_mac_address(struct usbnet *dev) diff --git a/trunk/drivers/net/usb/usbnet.c b/trunk/drivers/net/usb/usbnet.c index 8531c1caac28..e92c057f794a 100644 --- a/trunk/drivers/net/usb/usbnet.c +++ b/trunk/drivers/net/usb/usbnet.c @@ -1593,7 +1593,7 @@ static int __init usbnet_init(void) BUILD_BUG_ON( FIELD_SIZEOF(struct sk_buff, cb) < sizeof(struct skb_data)); - eth_random_addr(node_id); + random_ether_addr(node_id); return 0; } module_init(usbnet_init); diff --git a/trunk/drivers/net/wimax/i2400m/driver.c b/trunk/drivers/net/wimax/i2400m/driver.c index 025426132754..850b8bc38bee 100644 --- a/trunk/drivers/net/wimax/i2400m/driver.c +++ b/trunk/drivers/net/wimax/i2400m/driver.c @@ -896,7 +896,7 @@ int i2400m_setup(struct i2400m *i2400m, enum i2400m_bri bm_flags) result = i2400m_read_mac_addr(i2400m); if (result < 0) goto error_read_mac_addr; - eth_random_addr(i2400m->src_mac_addr); + random_ether_addr(i2400m->src_mac_addr); i2400m->pm_notifier.notifier_call = i2400m_pm_notifier; register_pm_notifier(&i2400m->pm_notifier); diff --git a/trunk/drivers/net/wireless/adm8211.c b/trunk/drivers/net/wireless/adm8211.c index 689a71c1af71..97afcec24759 100644 --- a/trunk/drivers/net/wireless/adm8211.c +++ b/trunk/drivers/net/wireless/adm8211.c @@ -1854,7 +1854,7 @@ static int __devinit adm8211_probe(struct pci_dev *pdev, if (!is_valid_ether_addr(perm_addr)) { printk(KERN_WARNING "%s (adm8211): Invalid hwaddr in EEPROM!\n", pci_name(pdev)); - eth_random_addr(perm_addr); + random_ether_addr(perm_addr); } SET_IEEE80211_PERM_ADDR(dev, perm_addr); diff --git a/trunk/drivers/net/wireless/p54/eeprom.c b/trunk/drivers/net/wireless/p54/eeprom.c index 14037092ba89..636daf2860cc 100644 --- a/trunk/drivers/net/wireless/p54/eeprom.c +++ b/trunk/drivers/net/wireless/p54/eeprom.c @@ -857,7 +857,7 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) wiphy_warn(dev->wiphy, "Invalid hwaddr! Using randomly generated MAC addr\n"); - eth_random_addr(perm_addr); + random_ether_addr(perm_addr); SET_IEEE80211_PERM_ADDR(dev, perm_addr); } diff --git a/trunk/drivers/net/wireless/rt2x00/rt2400pci.c b/trunk/drivers/net/wireless/rt2x00/rt2400pci.c index 8b9dbd76a252..5e6b50143165 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2400pci.c @@ -1455,7 +1455,7 @@ static int rt2400pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) */ mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0); if (!is_valid_ether_addr(mac)) { - eth_random_addr(mac); + random_ether_addr(mac); EEPROM(rt2x00dev, "MAC: %pM\n", mac); } diff --git a/trunk/drivers/net/wireless/rt2x00/rt2500pci.c b/trunk/drivers/net/wireless/rt2x00/rt2500pci.c index d2cf8a4bc8b5..136b849f11b5 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2500pci.c @@ -1585,7 +1585,7 @@ static int rt2500pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) */ mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0); if (!is_valid_ether_addr(mac)) { - eth_random_addr(mac); + random_ether_addr(mac); EEPROM(rt2x00dev, "MAC: %pM\n", mac); } diff --git a/trunk/drivers/net/wireless/rt2x00/rt2500usb.c b/trunk/drivers/net/wireless/rt2x00/rt2500usb.c index 3aae36bb0a9e..669aecdb411d 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2500usb.c @@ -1352,7 +1352,7 @@ static int rt2500usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) */ mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0); if (!is_valid_ether_addr(mac)) { - eth_random_addr(mac); + random_ether_addr(mac); EEPROM(rt2x00dev, "MAC: %pM\n", mac); } diff --git a/trunk/drivers/net/wireless/rt2x00/rt2800lib.c b/trunk/drivers/net/wireless/rt2x00/rt2800lib.c index 88455b1b9fe0..e76f03c9b468 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2800lib.c @@ -4335,7 +4335,7 @@ int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev) */ mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0); if (!is_valid_ether_addr(mac)) { - eth_random_addr(mac); + random_ether_addr(mac); EEPROM(rt2x00dev, "MAC: %pM\n", mac); } diff --git a/trunk/drivers/net/wireless/rt2x00/rt61pci.c b/trunk/drivers/net/wireless/rt2x00/rt61pci.c index f32259686b45..ee22bd74579d 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt61pci.c +++ b/trunk/drivers/net/wireless/rt2x00/rt61pci.c @@ -2415,7 +2415,7 @@ static int rt61pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) */ mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0); if (!is_valid_ether_addr(mac)) { - eth_random_addr(mac); + random_ether_addr(mac); EEPROM(rt2x00dev, "MAC: %pM\n", mac); } diff --git a/trunk/drivers/net/wireless/rt2x00/rt73usb.c b/trunk/drivers/net/wireless/rt2x00/rt73usb.c index ba6e434b859d..77ccbbc7da41 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt73usb.c +++ b/trunk/drivers/net/wireless/rt2x00/rt73usb.c @@ -1770,7 +1770,7 @@ static int rt73usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) */ mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0); if (!is_valid_ether_addr(mac)) { - eth_random_addr(mac); + random_ether_addr(mac); EEPROM(rt2x00dev, "MAC: %pM\n", mac); } diff --git a/trunk/drivers/net/wireless/rtl818x/rtl8180/dev.c b/trunk/drivers/net/wireless/rtl818x/rtl8180/dev.c index aceaf689f737..3b505395d869 100644 --- a/trunk/drivers/net/wireless/rtl818x/rtl8180/dev.c +++ b/trunk/drivers/net/wireless/rtl818x/rtl8180/dev.c @@ -1078,7 +1078,7 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev, if (!is_valid_ether_addr(mac_addr)) { printk(KERN_WARNING "%s (rtl8180): Invalid hwaddr! Using" " randomly generated MAC addr\n", pci_name(pdev)); - eth_random_addr(mac_addr); + random_ether_addr(mac_addr); } SET_IEEE80211_PERM_ADDR(dev, mac_addr); diff --git a/trunk/drivers/net/wireless/rtl818x/rtl8187/dev.c b/trunk/drivers/net/wireless/rtl818x/rtl8187/dev.c index 71a30b026089..4fb1ca1b86b9 100644 --- a/trunk/drivers/net/wireless/rtl818x/rtl8187/dev.c +++ b/trunk/drivers/net/wireless/rtl818x/rtl8187/dev.c @@ -1486,7 +1486,7 @@ static int __devinit rtl8187_probe(struct usb_interface *intf, if (!is_valid_ether_addr(mac_addr)) { printk(KERN_WARNING "rtl8187: Invalid hwaddr! Using randomly " "generated MAC address\n"); - eth_random_addr(mac_addr); + random_ether_addr(mac_addr); } SET_IEEE80211_PERM_ADDR(dev, mac_addr); diff --git a/trunk/drivers/s390/net/qeth_l2_main.c b/trunk/drivers/s390/net/qeth_l2_main.c index b09355c14ee1..426986518e96 100644 --- a/trunk/drivers/s390/net/qeth_l2_main.c +++ b/trunk/drivers/s390/net/qeth_l2_main.c @@ -647,7 +647,7 @@ static int qeth_l2_request_initial_mac(struct qeth_card *card) } QETH_DBF_HEX(SETUP, 2, card->dev->dev_addr, OSA_ADDR_LEN); } else { - eth_random_addr(card->dev->dev_addr); + random_ether_addr(card->dev->dev_addr); memcpy(card->dev->dev_addr, vendor_pre, 3); } return 0; diff --git a/trunk/drivers/s390/net/qeth_l3_main.c b/trunk/drivers/s390/net/qeth_l3_main.c index bada7f66c146..73ac63d901c9 100644 --- a/trunk/drivers/s390/net/qeth_l3_main.c +++ b/trunk/drivers/s390/net/qeth_l3_main.c @@ -1473,7 +1473,7 @@ static int qeth_l3_iqd_read_initial_mac_cb(struct qeth_card *card, memcpy(card->dev->dev_addr, cmd->data.create_destroy_addr.unique_id, ETH_ALEN); else - eth_random_addr(card->dev->dev_addr); + random_ether_addr(card->dev->dev_addr); return 0; } diff --git a/trunk/drivers/usb/atm/xusbatm.c b/trunk/drivers/usb/atm/xusbatm.c index b3b1bb78b2ef..14ec9f0c5924 100644 --- a/trunk/drivers/usb/atm/xusbatm.c +++ b/trunk/drivers/usb/atm/xusbatm.c @@ -20,7 +20,7 @@ ******************************************************************************/ #include -#include /* for eth_random_addr() */ +#include /* for random_ether_addr() */ #include "usbatm.h" @@ -163,7 +163,7 @@ static int xusbatm_atm_start(struct usbatm_data *usbatm, atm_dbg(usbatm, "%s entered\n", __func__); /* use random MAC as we've no way to get it from the device */ - eth_random_addr(atm_dev->esi); + random_ether_addr(atm_dev->esi); return 0; } diff --git a/trunk/drivers/usb/gadget/u_ether.c b/trunk/drivers/usb/gadget/u_ether.c index b9e1925b2df0..47cf48b51c9d 100644 --- a/trunk/drivers/usb/gadget/u_ether.c +++ b/trunk/drivers/usb/gadget/u_ether.c @@ -724,7 +724,7 @@ static int get_ether_addr(const char *str, u8 *dev_addr) if (is_valid_ether_addr(dev_addr)) return 0; } - eth_random_addr(dev_addr); + random_ether_addr(dev_addr); return 1; } diff --git a/trunk/include/linux/etherdevice.h b/trunk/include/linux/etherdevice.h index d426336d92d9..98a27cccedfd 100644 --- a/trunk/include/linux/etherdevice.h +++ b/trunk/include/linux/etherdevice.h @@ -124,21 +124,19 @@ static inline bool is_valid_ether_addr(const u8 *addr) } /** - * eth_random_addr - Generate software assigned random Ethernet address + * random_ether_addr - Generate software assigned random Ethernet address * @addr: Pointer to a six-byte array containing the Ethernet address * * Generate a random Ethernet address (MAC) that is not multicast * and has the local assigned bit set. */ -static inline void eth_random_addr(u8 *addr) +static inline void random_ether_addr(u8 *addr) { - get_random_bytes(addr, ETH_ALEN); - addr[0] &= 0xfe; /* clear multicast bit */ - addr[0] |= 0x02; /* set local assignment bit (IEEE802) */ + get_random_bytes (addr, ETH_ALEN); + addr [0] &= 0xfe; /* clear multicast bit */ + addr [0] |= 0x02; /* set local assignment bit (IEEE802) */ } -#define random_ether_addr(addr) eth_random_addr(addr) - /** * eth_broadcast_addr - Assign broadcast address * @addr: Pointer to a six-byte array containing the Ethernet address @@ -162,7 +160,7 @@ static inline void eth_broadcast_addr(u8 *addr) static inline void eth_hw_addr_random(struct net_device *dev) { dev->addr_assign_type |= NET_ADDR_RANDOM; - eth_random_addr(dev->dev_addr); + random_ether_addr(dev->dev_addr); } /** diff --git a/trunk/include/linux/if_team.h b/trunk/include/linux/if_team.h index 7fd0cdeb9444..dfa0c8e0ab84 100644 --- a/trunk/include/linux/if_team.h +++ b/trunk/include/linux/if_team.h @@ -13,8 +13,6 @@ #ifdef __KERNEL__ -#include - struct team_pcpu_stats { u64 rx_packets; u64 rx_bytes; @@ -62,10 +60,6 @@ struct team_port { unsigned int mtu; } orig; -#ifdef CONFIG_NET_POLL_CONTROLLER - struct netpoll *np; -#endif - long mode_priv[0]; }; @@ -79,33 +73,6 @@ static inline bool team_port_txable(struct team_port *port) return port->linkup && team_port_enabled(port); } -#ifdef CONFIG_NET_POLL_CONTROLLER -static inline void team_netpoll_send_skb(struct team_port *port, - struct sk_buff *skb) -{ - struct netpoll *np = port->np; - - if (np) - netpoll_send_skb(np, skb); -} -#else -static inline void team_netpoll_send_skb(struct team_port *port, - struct sk_buff *skb) -{ -} -#endif - -static inline int team_dev_queue_xmit(struct team *team, struct team_port *port, - struct sk_buff *skb) -{ - skb->dev = port->dev; - if (unlikely(netpoll_tx_running(port->dev))) { - team_netpoll_send_skb(port, skb); - return 0; - } - return dev_queue_xmit(skb); -} - struct team_mode_ops { int (*init)(struct team *team); void (*exit)(struct team *team); diff --git a/trunk/include/linux/netpoll.h b/trunk/include/linux/netpoll.h index 28f5389c924b..5dfa091c3347 100644 --- a/trunk/include/linux/netpoll.h +++ b/trunk/include/linux/netpoll.h @@ -43,7 +43,7 @@ struct netpoll_info { void netpoll_send_udp(struct netpoll *np, const char *msg, int len); void netpoll_print_options(struct netpoll *np); int netpoll_parse_options(struct netpoll *np, char *opt); -int __netpoll_setup(struct netpoll *np, struct net_device *ndev); +int __netpoll_setup(struct netpoll *np); int netpoll_setup(struct netpoll *np); int netpoll_trap(void); void netpoll_set_trap(int trap); diff --git a/trunk/include/linux/snmp.h b/trunk/include/linux/snmp.h index e5fcbd079e4a..2e68f5ba0389 100644 --- a/trunk/include/linux/snmp.h +++ b/trunk/include/linux/snmp.h @@ -208,6 +208,7 @@ enum LINUX_MIB_TCPDSACKOFOSENT, /* TCPDSACKOfoSent */ LINUX_MIB_TCPDSACKRECV, /* TCPDSACKRecv */ LINUX_MIB_TCPDSACKOFORECV, /* TCPDSACKOfoRecv */ + LINUX_MIB_TCPABORTONSYN, /* TCPAbortOnSyn */ LINUX_MIB_TCPABORTONDATA, /* TCPAbortOnData */ LINUX_MIB_TCPABORTONCLOSE, /* TCPAbortOnClose */ LINUX_MIB_TCPABORTONMEMORY, /* TCPAbortOnMemory */ @@ -232,12 +233,7 @@ enum LINUX_MIB_TCPREQQFULLDOCOOKIES, /* TCPReqQFullDoCookies */ LINUX_MIB_TCPREQQFULLDROP, /* TCPReqQFullDrop */ LINUX_MIB_TCPRETRANSFAIL, /* TCPRetransFail */ - LINUX_MIB_TCPRCVCOALESCE, /* TCPRcvCoalesce */ - LINUX_MIB_TCPOFOQUEUE, /* TCPOFOQueue */ - LINUX_MIB_TCPOFODROP, /* TCPOFODrop */ - LINUX_MIB_TCPOFOMERGE, /* TCPOFOMerge */ - LINUX_MIB_TCPCHALLENGEACK, /* TCPChallengeACK */ - LINUX_MIB_TCPSYNCHALLENGE, /* TCPSYNChallenge */ + LINUX_MIB_TCPRCVCOALESCE, /* TCPRcvCoalesce */ __LINUX_MIB_MAX }; diff --git a/trunk/include/linux/sock_diag.h b/trunk/include/linux/sock_diag.h index e3e395acc2fd..6793fac5eab5 100644 --- a/trunk/include/linux/sock_diag.h +++ b/trunk/include/linux/sock_diag.h @@ -44,5 +44,6 @@ void sock_diag_save_cookie(void *sk, __u32 *cookie); int sock_diag_put_meminfo(struct sock *sk, struct sk_buff *skb, int attr); +extern struct sock *sock_diag_nlsk; #endif /* KERNEL */ #endif diff --git a/trunk/include/linux/tipc_config.h b/trunk/include/linux/tipc_config.h index c98928420100..9730b0e51e46 100644 --- a/trunk/include/linux/tipc_config.h +++ b/trunk/include/linux/tipc_config.h @@ -102,8 +102,8 @@ #define TIPC_CMD_SET_LINK_TOL 0x4107 /* tx link_config, rx none */ #define TIPC_CMD_SET_LINK_PRI 0x4108 /* tx link_config, rx none */ #define TIPC_CMD_SET_LINK_WINDOW 0x4109 /* tx link_config, rx none */ -#define TIPC_CMD_SET_LOG_SIZE 0x410A /* obsoleted */ -#define TIPC_CMD_DUMP_LOG 0x410B /* obsoleted */ +#define TIPC_CMD_SET_LOG_SIZE 0x410A /* tx unsigned, rx none */ +#define TIPC_CMD_DUMP_LOG 0x410B /* tx none, rx ultra_string */ #define TIPC_CMD_RESET_LINK_STATS 0x410C /* tx link_name, rx none */ /* diff --git a/trunk/include/net/inet_connection_sock.h b/trunk/include/net/inet_connection_sock.h index 291e7cee14e7..2cf44b4ed2e6 100644 --- a/trunk/include/net/inet_connection_sock.h +++ b/trunk/include/net/inet_connection_sock.h @@ -337,4 +337,6 @@ extern int inet_csk_compat_getsockopt(struct sock *sk, int level, int optname, char __user *optval, int __user *optlen); extern int inet_csk_compat_setsockopt(struct sock *sk, int level, int optname, char __user *optval, unsigned int optlen); + +extern struct dst_entry *inet_csk_update_pmtu(struct sock *sk, u32 mtu); #endif /* _INET_CONNECTION_SOCK_H */ diff --git a/trunk/include/net/net_namespace.h b/trunk/include/net/net_namespace.h index ae1cd6c9ba52..ac9195e6a062 100644 --- a/trunk/include/net/net_namespace.h +++ b/trunk/include/net/net_namespace.h @@ -101,7 +101,6 @@ struct net { struct netns_xfrm xfrm; #endif struct netns_ipvs *ipvs; - struct sock *diag_nlsk; }; diff --git a/trunk/include/net/tcp.h b/trunk/include/net/tcp.h index 85c5090bfe25..439984b9af49 100644 --- a/trunk/include/net/tcp.h +++ b/trunk/include/net/tcp.h @@ -254,7 +254,6 @@ extern int sysctl_tcp_thin_linear_timeouts; extern int sysctl_tcp_thin_dupack; extern int sysctl_tcp_early_retrans; extern int sysctl_tcp_limit_output_bytes; -extern int sysctl_tcp_challenge_ack_limit; extern atomic_long_t tcp_memory_allocated; extern struct percpu_counter tcp_sockets_allocated; diff --git a/trunk/net/8021q/vlan_dev.c b/trunk/net/8021q/vlan_dev.c index 73a2a83ee2da..da1bc9c3cf38 100644 --- a/trunk/net/8021q/vlan_dev.c +++ b/trunk/net/8021q/vlan_dev.c @@ -681,7 +681,10 @@ static int vlan_dev_netpoll_setup(struct net_device *dev, struct netpoll_info *n if (!netpoll) goto out; - err = __netpoll_setup(netpoll, real_dev); + netpoll->dev = real_dev; + strlcpy(netpoll->dev_name, real_dev->name, IFNAMSIZ); + + err = __netpoll_setup(netpoll); if (err) { kfree(netpoll); goto out; diff --git a/trunk/net/bridge/br_device.c b/trunk/net/bridge/br_device.c index f4be1bbfef26..929e48aed444 100644 --- a/trunk/net/bridge/br_device.c +++ b/trunk/net/bridge/br_device.c @@ -246,7 +246,10 @@ int br_netpoll_enable(struct net_bridge_port *p) if (!np) goto out; - err = __netpoll_setup(np, p->dev); + np->dev = p->dev; + strlcpy(np->dev_name, p->dev->name, IFNAMSIZ); + + err = __netpoll_setup(np); if (err) { kfree(np); goto out; diff --git a/trunk/net/bridge/br_multicast.c b/trunk/net/bridge/br_multicast.c index 241743417f49..2d9a0663b848 100644 --- a/trunk/net/bridge/br_multicast.c +++ b/trunk/net/bridge/br_multicast.c @@ -540,11 +540,10 @@ static struct net_bridge_mdb_entry *br_multicast_get_group( if (mdb->size >= max) { max *= 2; - if (unlikely(max > br->hash_max)) { - br_warn(br, "Multicast hash table maximum of %d " - "reached, disabling snooping: %s\n", - br->hash_max, - port ? port->dev->name : br->dev->name); + if (unlikely(max >= br->hash_max)) { + br_warn(br, "Multicast hash table maximum " + "reached, disabling snooping: %s, %d\n", + port ? port->dev->name : br->dev->name, max); err = -E2BIG; disable: br->multicast_disabled = 1; diff --git a/trunk/net/core/netpoll.c b/trunk/net/core/netpoll.c index b4c90e42b443..f9f40b932e4b 100644 --- a/trunk/net/core/netpoll.c +++ b/trunk/net/core/netpoll.c @@ -715,16 +715,14 @@ int netpoll_parse_options(struct netpoll *np, char *opt) } EXPORT_SYMBOL(netpoll_parse_options); -int __netpoll_setup(struct netpoll *np, struct net_device *ndev) +int __netpoll_setup(struct netpoll *np) { + struct net_device *ndev = np->dev; struct netpoll_info *npinfo; const struct net_device_ops *ops; unsigned long flags; int err; - np->dev = ndev; - strlcpy(np->dev_name, ndev->name, IFNAMSIZ); - if ((ndev->priv_flags & IFF_DISABLE_NETPOLL) || !ndev->netdev_ops->ndo_poll_controller) { np_err(np, "%s doesn't support polling, aborting\n", @@ -853,11 +851,13 @@ int netpoll_setup(struct netpoll *np) np_info(np, "local IP %pI4\n", &np->local_ip); } + np->dev = ndev; + /* fill up the skb queue */ refill_skbs(); rtnl_lock(); - err = __netpoll_setup(np, ndev); + err = __netpoll_setup(np); rtnl_unlock(); if (err) diff --git a/trunk/net/core/sock_diag.c b/trunk/net/core/sock_diag.c index 9d8755e4a7a5..07a29eb34a41 100644 --- a/trunk/net/core/sock_diag.c +++ b/trunk/net/core/sock_diag.c @@ -166,36 +166,23 @@ static void sock_diag_rcv(struct sk_buff *skb) mutex_unlock(&sock_diag_mutex); } -static int __net_init diag_net_init(struct net *net) +struct sock *sock_diag_nlsk; +EXPORT_SYMBOL_GPL(sock_diag_nlsk); + +static int __init sock_diag_init(void) { struct netlink_kernel_cfg cfg = { .input = sock_diag_rcv, }; - net->diag_nlsk = netlink_kernel_create(net, NETLINK_SOCK_DIAG, + sock_diag_nlsk = netlink_kernel_create(&init_net, NETLINK_SOCK_DIAG, THIS_MODULE, &cfg); - return net->diag_nlsk == NULL ? -ENOMEM : 0; -} - -static void __net_exit diag_net_exit(struct net *net) -{ - netlink_kernel_release(net->diag_nlsk); - net->diag_nlsk = NULL; -} - -static struct pernet_operations diag_net_ops = { - .init = diag_net_init, - .exit = diag_net_exit, -}; - -static int __init sock_diag_init(void) -{ - return register_pernet_subsys(&diag_net_ops); + return sock_diag_nlsk == NULL ? -ENOMEM : 0; } static void __exit sock_diag_exit(void) { - unregister_pernet_subsys(&diag_net_ops); + netlink_kernel_release(sock_diag_nlsk); } module_init(sock_diag_init); diff --git a/trunk/net/dccp/ipv4.c b/trunk/net/dccp/ipv4.c index 129ed8f74138..683902fcc8ed 100644 --- a/trunk/net/dccp/ipv4.c +++ b/trunk/net/dccp/ipv4.c @@ -161,17 +161,10 @@ static inline void dccp_do_pmtu_discovery(struct sock *sk, if (sk->sk_state == DCCP_LISTEN) return; - /* We don't check in the destentry if pmtu discovery is forbidden - * on this route. We just assume that no packet_to_big packets - * are send back when pmtu discovery is not active. - * There is a small race when the user changes this flag in the - * route, but I think that's acceptable. - */ - if ((dst = __sk_dst_check(sk, 0)) == NULL) + dst = inet_csk_update_pmtu(sk, mtu); + if (!dst) return; - dst->ops->update_pmtu(dst, mtu); - /* Something is about to be wrong... Remember soft error * for the case, if this connection will not able to recover. */ diff --git a/trunk/net/ieee802154/6lowpan.c b/trunk/net/ieee802154/6lowpan.c index 6a095225148e..6871ec1b30f8 100644 --- a/trunk/net/ieee802154/6lowpan.c +++ b/trunk/net/ieee802154/6lowpan.c @@ -302,7 +302,7 @@ static inline int lowpan_fetch_skb_u16(struct sk_buff *skb, u16 *val) if (unlikely(!pskb_may_pull(skb, 2))) return -EINVAL; - *val = (skb->data[0] << 8) | skb->data[1]; + *val = skb->data[0] | (skb->data[1] << 8); skb_pull(skb, 2); return 0; @@ -314,9 +314,6 @@ lowpan_uncompress_udp_header(struct sk_buff *skb) struct udphdr *uh = udp_hdr(skb); u8 tmp; - if (!uh) - goto err; - if (lowpan_fetch_skb_u8(skb, &tmp)) goto err; @@ -645,7 +642,7 @@ static void lowpan_fragment_timer_expired(unsigned long entry_addr) } static struct lowpan_fragment * -lowpan_alloc_new_frame(struct sk_buff *skb, u8 len, u16 tag) +lowpan_alloc_new_frame(struct sk_buff *skb, u8 iphc0, u8 len, u16 tag) { struct lowpan_fragment *frame; @@ -656,7 +653,7 @@ lowpan_alloc_new_frame(struct sk_buff *skb, u8 len, u16 tag) INIT_LIST_HEAD(&frame->list); - frame->length = len; + frame->length = (iphc0 & 7) | (len << 3); frame->tag = tag; /* allocate buffer for frame assembling */ @@ -714,18 +711,14 @@ lowpan_process_data(struct sk_buff *skb) case LOWPAN_DISPATCH_FRAGN: { struct lowpan_fragment *frame; - /* slen stores the rightmost 8 bits of the 11 bits length */ - u8 slen, offset; - u16 len, tag; + u8 len, offset; + u16 tag; bool found = false; - if (lowpan_fetch_skb_u8(skb, &slen) || /* frame length */ + if (lowpan_fetch_skb_u8(skb, &len) || /* frame length */ lowpan_fetch_skb_u16(skb, &tag)) /* fragment tag */ goto drop; - /* adds the 3 MSB to the 8 LSB to retrieve the 11 bits length */ - len = ((iphc0 & 7) << 8) | slen; - /* * check if frame assembling with the same tag is * already in progress @@ -740,7 +733,7 @@ lowpan_process_data(struct sk_buff *skb) /* alloc new frame structure */ if (!found) { - frame = lowpan_alloc_new_frame(skb, len, tag); + frame = lowpan_alloc_new_frame(skb, iphc0, len, tag); if (!frame) goto unlock_and_drop; } @@ -1008,10 +1001,10 @@ lowpan_skb_fragmentation(struct sk_buff *skb) tag = fragment_tag++; /* first fragment header */ - head[0] = LOWPAN_DISPATCH_FRAG1 | ((payload_length >> 8) & 0x7); - head[1] = payload_length & 0xff; - head[2] = tag >> 8; - head[3] = tag & 0xff; + head[0] = LOWPAN_DISPATCH_FRAG1 | (payload_length & 0x7); + head[1] = (payload_length >> 3) & 0xff; + head[2] = tag & 0xff; + head[3] = tag >> 8; err = lowpan_fragment_xmit(skb, head, header_length, 0, 0); diff --git a/trunk/net/ipv4/inet_connection_sock.c b/trunk/net/ipv4/inet_connection_sock.c index 76825be3b643..200d21809379 100644 --- a/trunk/net/ipv4/inet_connection_sock.c +++ b/trunk/net/ipv4/inet_connection_sock.c @@ -803,3 +803,49 @@ int inet_csk_compat_setsockopt(struct sock *sk, int level, int optname, } EXPORT_SYMBOL_GPL(inet_csk_compat_setsockopt); #endif + +static struct dst_entry *inet_csk_rebuild_route(struct sock *sk, struct flowi *fl) +{ + struct inet_sock *inet = inet_sk(sk); + struct ip_options_rcu *inet_opt; + __be32 daddr = inet->inet_daddr; + struct flowi4 *fl4; + struct rtable *rt; + + rcu_read_lock(); + inet_opt = rcu_dereference(inet->inet_opt); + if (inet_opt && inet_opt->opt.srr) + daddr = inet_opt->opt.faddr; + fl4 = &fl->u.ip4; + rt = ip_route_output_ports(sock_net(sk), fl4, sk, daddr, + inet->inet_saddr, inet->inet_dport, + inet->inet_sport, sk->sk_protocol, + RT_CONN_FLAGS(sk), sk->sk_bound_dev_if); + if (IS_ERR(rt)) + rt = NULL; + if (rt) + sk_setup_caps(sk, &rt->dst); + rcu_read_unlock(); + + return &rt->dst; +} + +struct dst_entry *inet_csk_update_pmtu(struct sock *sk, u32 mtu) +{ + struct dst_entry *dst = __sk_dst_check(sk, 0); + struct inet_sock *inet = inet_sk(sk); + + if (!dst) { + dst = inet_csk_rebuild_route(sk, &inet->cork.fl); + if (!dst) + goto out; + } + dst->ops->update_pmtu(dst, mtu); + + dst = __sk_dst_check(sk, 0); + if (!dst) + dst = inet_csk_rebuild_route(sk, &inet->cork.fl); +out: + return dst; +} +EXPORT_SYMBOL_GPL(inet_csk_update_pmtu); diff --git a/trunk/net/ipv4/inet_diag.c b/trunk/net/ipv4/inet_diag.c index 570e61f9611f..38064a285cca 100644 --- a/trunk/net/ipv4/inet_diag.c +++ b/trunk/net/ipv4/inet_diag.c @@ -272,17 +272,16 @@ int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *in_s int err; struct sock *sk; struct sk_buff *rep; - struct net *net = sock_net(in_skb->sk); err = -EINVAL; if (req->sdiag_family == AF_INET) { - sk = inet_lookup(net, hashinfo, req->id.idiag_dst[0], + sk = inet_lookup(&init_net, hashinfo, req->id.idiag_dst[0], req->id.idiag_dport, req->id.idiag_src[0], req->id.idiag_sport, req->id.idiag_if); } #if IS_ENABLED(CONFIG_IPV6) else if (req->sdiag_family == AF_INET6) { - sk = inet6_lookup(net, hashinfo, + sk = inet6_lookup(&init_net, hashinfo, (struct in6_addr *)req->id.idiag_dst, req->id.idiag_dport, (struct in6_addr *)req->id.idiag_src, @@ -318,7 +317,7 @@ int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *in_s nlmsg_free(rep); goto out; } - err = netlink_unicast(net->diag_nlsk, rep, NETLINK_CB(in_skb).pid, + err = netlink_unicast(sock_diag_nlsk, rep, NETLINK_CB(in_skb).pid, MSG_DONTWAIT); if (err > 0) err = 0; @@ -725,7 +724,6 @@ void inet_diag_dump_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *skb, { int i, num; int s_i, s_num; - struct net *net = sock_net(skb->sk); s_i = cb->args[1]; s_num = num = cb->args[2]; @@ -745,9 +743,6 @@ void inet_diag_dump_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *skb, sk_nulls_for_each(sk, node, &ilb->head) { struct inet_sock *inet = inet_sk(sk); - if (!net_eq(sock_net(sk), net)) - continue; - if (num < s_num) { num++; continue; @@ -818,8 +813,6 @@ void inet_diag_dump_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *skb, sk_nulls_for_each(sk, node, &head->chain) { struct inet_sock *inet = inet_sk(sk); - if (!net_eq(sock_net(sk), net)) - continue; if (num < s_num) goto next_normal; if (!(r->idiag_states & (1 << sk->sk_state))) @@ -846,8 +839,6 @@ void inet_diag_dump_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *skb, inet_twsk_for_each(tw, node, &head->twchain) { - if (!net_eq(twsk_net(tw), net)) - continue; if (num < s_num) goto next_dying; @@ -952,7 +943,6 @@ static int inet_diag_get_exact_compat(struct sk_buff *in_skb, static int inet_diag_rcv_msg_compat(struct sk_buff *skb, struct nlmsghdr *nlh) { int hdrlen = sizeof(struct inet_diag_req); - struct net *net = sock_net(skb->sk); if (nlh->nlmsg_type >= INET_DIAG_GETSOCK_MAX || nlmsg_len(nlh) < hdrlen) @@ -973,7 +963,7 @@ static int inet_diag_rcv_msg_compat(struct sk_buff *skb, struct nlmsghdr *nlh) struct netlink_dump_control c = { .dump = inet_diag_dump_compat, }; - return netlink_dump_start(net->diag_nlsk, skb, nlh, &c); + return netlink_dump_start(sock_diag_nlsk, skb, nlh, &c); } } @@ -983,7 +973,6 @@ static int inet_diag_rcv_msg_compat(struct sk_buff *skb, struct nlmsghdr *nlh) static int inet_diag_handler_dump(struct sk_buff *skb, struct nlmsghdr *h) { int hdrlen = sizeof(struct inet_diag_req_v2); - struct net *net = sock_net(skb->sk); if (nlmsg_len(h) < hdrlen) return -EINVAL; @@ -1002,7 +991,7 @@ static int inet_diag_handler_dump(struct sk_buff *skb, struct nlmsghdr *h) struct netlink_dump_control c = { .dump = inet_diag_dump, }; - return netlink_dump_start(net->diag_nlsk, skb, h, &c); + return netlink_dump_start(sock_diag_nlsk, skb, h, &c); } } diff --git a/trunk/net/ipv4/proc.c b/trunk/net/ipv4/proc.c index 2a5240b2ea61..8af0d44e4e22 100644 --- a/trunk/net/ipv4/proc.c +++ b/trunk/net/ipv4/proc.c @@ -232,6 +232,7 @@ static const struct snmp_mib snmp4_net_list[] = { SNMP_MIB_ITEM("TCPDSACKOfoSent", LINUX_MIB_TCPDSACKOFOSENT), SNMP_MIB_ITEM("TCPDSACKRecv", LINUX_MIB_TCPDSACKRECV), SNMP_MIB_ITEM("TCPDSACKOfoRecv", LINUX_MIB_TCPDSACKOFORECV), + SNMP_MIB_ITEM("TCPAbortOnSyn", LINUX_MIB_TCPABORTONSYN), SNMP_MIB_ITEM("TCPAbortOnData", LINUX_MIB_TCPABORTONDATA), SNMP_MIB_ITEM("TCPAbortOnClose", LINUX_MIB_TCPABORTONCLOSE), SNMP_MIB_ITEM("TCPAbortOnMemory", LINUX_MIB_TCPABORTONMEMORY), @@ -257,11 +258,6 @@ static const struct snmp_mib snmp4_net_list[] = { SNMP_MIB_ITEM("TCPReqQFullDrop", LINUX_MIB_TCPREQQFULLDROP), SNMP_MIB_ITEM("TCPRetransFail", LINUX_MIB_TCPRETRANSFAIL), SNMP_MIB_ITEM("TCPRcvCoalesce", LINUX_MIB_TCPRCVCOALESCE), - SNMP_MIB_ITEM("TCPOFOQueue", LINUX_MIB_TCPOFOQUEUE), - SNMP_MIB_ITEM("TCPOFODrop", LINUX_MIB_TCPOFODROP), - SNMP_MIB_ITEM("TCPOFOMerge", LINUX_MIB_TCPOFOMERGE), - SNMP_MIB_ITEM("TCPChallengeACK", LINUX_MIB_TCPCHALLENGEACK), - SNMP_MIB_ITEM("TCPSYNChallenge", LINUX_MIB_TCPSYNCHALLENGE), SNMP_MIB_SENTINEL }; diff --git a/trunk/net/ipv4/sysctl_net_ipv4.c b/trunk/net/ipv4/sysctl_net_ipv4.c index 3f6a1e762e9c..70730f7aeafe 100644 --- a/trunk/net/ipv4/sysctl_net_ipv4.c +++ b/trunk/net/ipv4/sysctl_net_ipv4.c @@ -605,13 +605,6 @@ static struct ctl_table ipv4_table[] = { .mode = 0644, .proc_handler = proc_dointvec }, - { - .procname = "tcp_challenge_ack_limit", - .data = &sysctl_tcp_challenge_ack_limit, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = proc_dointvec - }, #ifdef CONFIG_NET_DMA { .procname = "tcp_dma_copybreak", diff --git a/trunk/net/ipv4/tcp_input.c b/trunk/net/ipv4/tcp_input.c index 8aaec5536111..055ac49b8b40 100644 --- a/trunk/net/ipv4/tcp_input.c +++ b/trunk/net/ipv4/tcp_input.c @@ -88,9 +88,6 @@ int sysctl_tcp_app_win __read_mostly = 31; int sysctl_tcp_adv_win_scale __read_mostly = 1; EXPORT_SYMBOL(sysctl_tcp_adv_win_scale); -/* rfc5961 challenge ack rate limiting */ -int sysctl_tcp_challenge_ack_limit = 100; - int sysctl_tcp_stdurg __read_mostly; int sysctl_tcp_rfc1337 __read_mostly; int sysctl_tcp_max_orphans __read_mostly = NR_FILE; @@ -4400,8 +4397,8 @@ static void tcp_data_queue_ofo(struct sock *sk, struct sk_buff *skb) TCP_ECN_check_ce(tp, skb); - if (unlikely(tcp_try_rmem_schedule(sk, skb->truesize))) { - NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPOFODROP); + if (tcp_try_rmem_schedule(sk, skb->truesize)) { + /* TODO: should increment a counter */ __kfree_skb(skb); return; } @@ -4410,7 +4407,6 @@ static void tcp_data_queue_ofo(struct sock *sk, struct sk_buff *skb) tp->pred_flags = 0; inet_csk_schedule_ack(sk); - NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPOFOQUEUE); SOCK_DEBUG(sk, "out of order segment: rcv_next %X seq %X - %X\n", tp->rcv_nxt, TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq); @@ -4464,7 +4460,6 @@ static void tcp_data_queue_ofo(struct sock *sk, struct sk_buff *skb) if (skb1 && before(seq, TCP_SKB_CB(skb1)->end_seq)) { if (!after(end_seq, TCP_SKB_CB(skb1)->end_seq)) { /* All the bits are present. Drop. */ - NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPOFOMERGE); __kfree_skb(skb); skb = NULL; tcp_dsack_set(sk, seq, end_seq); @@ -4503,7 +4498,6 @@ static void tcp_data_queue_ofo(struct sock *sk, struct sk_buff *skb) __skb_unlink(skb1, &tp->out_of_order_queue); tcp_dsack_extend(sk, TCP_SKB_CB(skb1)->seq, TCP_SKB_CB(skb1)->end_seq); - NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPOFOMERGE); __kfree_skb(skb1); } @@ -5250,28 +5244,11 @@ static bool tcp_dma_try_early_copy(struct sock *sk, struct sk_buff *skb, } #endif /* CONFIG_NET_DMA */ -static void tcp_send_challenge_ack(struct sock *sk) -{ - /* unprotected vars, we dont care of overwrites */ - static u32 challenge_timestamp; - static unsigned int challenge_count; - u32 now = jiffies / HZ; - - if (now != challenge_timestamp) { - challenge_timestamp = now; - challenge_count = 0; - } - if (++challenge_count <= sysctl_tcp_challenge_ack_limit) { - NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPCHALLENGEACK); - tcp_send_ack(sk); - } -} - /* Does PAWS and seqno based validation of an incoming segment, flags will * play significant role here. */ -static bool tcp_validate_incoming(struct sock *sk, struct sk_buff *skb, - const struct tcphdr *th, int syn_inerr) +static int tcp_validate_incoming(struct sock *sk, struct sk_buff *skb, + const struct tcphdr *th, int syn_inerr) { const u8 *hash_location; struct tcp_sock *tp = tcp_sk(sk); @@ -5303,16 +5280,7 @@ static bool tcp_validate_incoming(struct sock *sk, struct sk_buff *skb, /* Step 2: check RST bit */ if (th->rst) { - /* RFC 5961 3.2 : - * If sequence number exactly matches RCV.NXT, then - * RESET the connection - * else - * Send a challenge ACK - */ - if (TCP_SKB_CB(skb)->seq == tp->rcv_nxt) - tcp_reset(sk); - else - tcp_send_challenge_ack(sk); + tcp_reset(sk); goto discard; } @@ -5323,22 +5291,20 @@ static bool tcp_validate_incoming(struct sock *sk, struct sk_buff *skb, /* step 3: check security and precedence [ignored] */ - /* step 4: Check for a SYN - * RFC 5691 4.2 : Send a challenge ack - */ - if (th->syn) { + /* step 4: Check for a SYN in window. */ + if (th->syn && !before(TCP_SKB_CB(skb)->seq, tp->rcv_nxt)) { if (syn_inerr) TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_INERRS); - NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPSYNCHALLENGE); - tcp_send_challenge_ack(sk); - goto discard; + NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPABORTONSYN); + tcp_reset(sk); + return -1; } - return true; + return 1; discard: __kfree_skb(skb); - return false; + return 0; } /* @@ -5368,6 +5334,7 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb, const struct tcphdr *th, unsigned int len) { struct tcp_sock *tp = tcp_sk(sk); + int res; if (sk->sk_rx_dst) { struct dst_entry *dst = sk->sk_rx_dst; @@ -5556,8 +5523,9 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb, * Standard slow path. */ - if (!tcp_validate_incoming(sk, skb, th, 1)) - return 0; + res = tcp_validate_incoming(sk, skb, th, 1); + if (res <= 0) + return -res; step5: if (th->ack && tcp_ack(sk, skb, FLAG_SLOWPATH) < 0) @@ -5877,6 +5845,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, struct tcp_sock *tp = tcp_sk(sk); struct inet_connection_sock *icsk = inet_csk(sk); int queued = 0; + int res; tp->rx_opt.saw_tstamp = 0; @@ -5931,8 +5900,9 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, return 0; } - if (!tcp_validate_incoming(sk, skb, th, 0)) - return 0; + res = tcp_validate_incoming(sk, skb, th, 0); + if (res <= 0) + return -res; /* step 5: check the ACK field */ if (th->ack) { diff --git a/trunk/net/ipv4/tcp_ipv4.c b/trunk/net/ipv4/tcp_ipv4.c index 7a0062cb4ed0..b8e7e0595407 100644 --- a/trunk/net/ipv4/tcp_ipv4.c +++ b/trunk/net/ipv4/tcp_ipv4.c @@ -289,17 +289,10 @@ static void do_pmtu_discovery(struct sock *sk, const struct iphdr *iph, u32 mtu) if (sk->sk_state == TCP_LISTEN) return; - /* We don't check in the destentry if pmtu discovery is forbidden - * on this route. We just assume that no packet_to_big packets - * are send back when pmtu discovery is not active. - * There is a small race when the user changes this flag in the - * route, but I think that's acceptable. - */ - if ((dst = __sk_dst_check(sk, 0)) == NULL) + dst = inet_csk_update_pmtu(sk, mtu); + if (!dst) return; - dst->ops->update_pmtu(dst, mtu); - /* Something is about to be wrong... Remember soft error * for the case, if this connection will not able to recover. */ diff --git a/trunk/net/ipv4/udp_diag.c b/trunk/net/ipv4/udp_diag.c index 16d0960062be..a7f86a3cd502 100644 --- a/trunk/net/ipv4/udp_diag.c +++ b/trunk/net/ipv4/udp_diag.c @@ -34,16 +34,15 @@ static int udp_dump_one(struct udp_table *tbl, struct sk_buff *in_skb, int err = -EINVAL; struct sock *sk; struct sk_buff *rep; - struct net *net = sock_net(in_skb->sk); if (req->sdiag_family == AF_INET) - sk = __udp4_lib_lookup(net, + sk = __udp4_lib_lookup(&init_net, req->id.idiag_src[0], req->id.idiag_sport, req->id.idiag_dst[0], req->id.idiag_dport, req->id.idiag_if, tbl); #if IS_ENABLED(CONFIG_IPV6) else if (req->sdiag_family == AF_INET6) - sk = __udp6_lib_lookup(net, + sk = __udp6_lib_lookup(&init_net, (struct in6_addr *)req->id.idiag_src, req->id.idiag_sport, (struct in6_addr *)req->id.idiag_dst, @@ -76,7 +75,7 @@ static int udp_dump_one(struct udp_table *tbl, struct sk_buff *in_skb, kfree_skb(rep); goto out; } - err = netlink_unicast(net->diag_nlsk, rep, NETLINK_CB(in_skb).pid, + err = netlink_unicast(sock_diag_nlsk, rep, NETLINK_CB(in_skb).pid, MSG_DONTWAIT); if (err > 0) err = 0; @@ -91,7 +90,6 @@ static void udp_dump(struct udp_table *table, struct sk_buff *skb, struct netlin struct inet_diag_req_v2 *r, struct nlattr *bc) { int num, s_num, slot, s_slot; - struct net *net = sock_net(skb->sk); s_slot = cb->args[0]; num = s_num = cb->args[1]; @@ -108,8 +106,6 @@ static void udp_dump(struct udp_table *table, struct sk_buff *skb, struct netlin sk_nulls_for_each(sk, node, &hslot->head) { struct inet_sock *inet = inet_sk(sk); - if (!net_eq(sock_net(sk), net)) - continue; if (num < s_num) goto next; if (!(r->idiag_states & (1 << sk->sk_state))) diff --git a/trunk/net/ipv6/mcast.c b/trunk/net/ipv6/mcast.c index 92f8e48e4ba4..6d0f5dc8e3a6 100644 --- a/trunk/net/ipv6/mcast.c +++ b/trunk/net/ipv6/mcast.c @@ -211,9 +211,6 @@ int ipv6_sock_mc_drop(struct sock *sk, int ifindex, const struct in6_addr *addr) struct ipv6_mc_socklist __rcu **lnk; struct net *net = sock_net(sk); - if (!ipv6_addr_is_multicast(addr)) - return -EINVAL; - spin_lock(&ipv6_sk_mc_lock); for (lnk = &np->ipv6_mc_list; (mc_lst = rcu_dereference_protected(*lnk, diff --git a/trunk/net/ipv6/route.c b/trunk/net/ipv6/route.c index 412fad809a3b..2a4c8d48977f 100644 --- a/trunk/net/ipv6/route.c +++ b/trunk/net/ipv6/route.c @@ -2399,12 +2399,10 @@ static int rt6_fill_node(struct net *net, rtm->rtm_protocol = rt->rt6i_protocol; if (rt->rt6i_flags & RTF_DYNAMIC) rtm->rtm_protocol = RTPROT_REDIRECT; - else if (rt->rt6i_flags & RTF_ADDRCONF) { - if (rt->rt6i_flags & (RTF_DEFAULT | RTF_ROUTEINFO)) - rtm->rtm_protocol = RTPROT_RA; - else - rtm->rtm_protocol = RTPROT_KERNEL; - } + else if (rt->rt6i_flags & RTF_ADDRCONF) + rtm->rtm_protocol = RTPROT_KERNEL; + else if (rt->rt6i_flags & RTF_DEFAULT) + rtm->rtm_protocol = RTPROT_RA; if (rt->rt6i_flags & RTF_CACHE) rtm->rtm_flags |= RTM_F_CLONED; diff --git a/trunk/net/irda/af_irda.c b/trunk/net/irda/af_irda.c index bb738c9f9146..bb14c3477680 100644 --- a/trunk/net/irda/af_irda.c +++ b/trunk/net/irda/af_irda.c @@ -955,7 +955,7 @@ static int irda_accept(struct socket *sock, struct socket *newsock, int flags) * The main difference with a "standard" connect is that with IrDA we need * to resolve the service name into a TSAP selector (in TCP, port number * doesn't have to be resolved). - * Because of this service name resolution, we can offer "auto-connect", + * Because of this service name resoltion, we can offer "auto-connect", * where we connect to a service without specifying a destination address. * * Note : by consulting "errno", the user space caller may learn the cause diff --git a/trunk/net/irda/irlan/irlan_provider.c b/trunk/net/irda/irlan/irlan_provider.c index 4664855222f4..32dcaac70b0c 100644 --- a/trunk/net/irda/irlan/irlan_provider.c +++ b/trunk/net/irda/irlan/irlan_provider.c @@ -296,7 +296,7 @@ void irlan_provider_send_reply(struct irlan_cb *self, int command, skb = alloc_skb(IRLAN_MAX_HEADER + IRLAN_CMD_HEADER + /* Bigger param length comes from CMD_GET_MEDIA_CHAR */ IRLAN_STRING_PARAMETER_LEN("FILTER_TYPE", "DIRECTED") + - IRLAN_STRING_PARAMETER_LEN("FILTER_TYPE", "BROADCAST") + + IRLAN_STRING_PARAMETER_LEN("FILTER_TYPE", "BORADCAST") + IRLAN_STRING_PARAMETER_LEN("FILTER_TYPE", "MULTICAST") + IRLAN_STRING_PARAMETER_LEN("ACCESS_TYPE", "HOSTED"), GFP_ATOMIC); diff --git a/trunk/net/sched/sch_netem.c b/trunk/net/sched/sch_netem.c index 298c0ddfb57e..c412ad0d0308 100644 --- a/trunk/net/sched/sch_netem.c +++ b/trunk/net/sched/sch_netem.c @@ -380,14 +380,7 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch) return NET_XMIT_SUCCESS | __NET_XMIT_BYPASS; } - /* If a delay is expected, orphan the skb. (orphaning usually takes - * place at TX completion time, so _before_ the link transit delay) - * Ideally, this orphaning should be done after the rate limiting - * module, because this breaks TCP Small Queue, and other mechanisms - * based on socket sk_wmem_alloc. - */ - if (q->latency || q->jitter) - skb_orphan(skb); + skb_orphan(skb); /* * If we need to duplicate packet, then re-insert at top of the diff --git a/trunk/net/sctp/sm_make_chunk.c b/trunk/net/sctp/sm_make_chunk.c index 479a70ef6ff8..b6de71efb140 100644 --- a/trunk/net/sctp/sm_make_chunk.c +++ b/trunk/net/sctp/sm_make_chunk.c @@ -132,7 +132,7 @@ void sctp_init_cause(struct sctp_chunk *chunk, __be16 cause_code, * abort chunk. Differs from sctp_init_cause in that it won't oops * if there isn't enough space in the op error chunk */ -static int sctp_init_cause_fixed(struct sctp_chunk *chunk, __be16 cause_code, +int sctp_init_cause_fixed(struct sctp_chunk *chunk, __be16 cause_code, size_t paylen) { sctp_errhdr_t err; diff --git a/trunk/net/tipc/Kconfig b/trunk/net/tipc/Kconfig index 585460180ffb..2c5954b85933 100644 --- a/trunk/net/tipc/Kconfig +++ b/trunk/net/tipc/Kconfig @@ -41,4 +41,29 @@ config TIPC_PORTS Setting this to a smaller value saves some memory, setting it to higher allows for more ports. +config TIPC_LOG + int "Size of log buffer" + depends on TIPC_ADVANCED + range 0 32768 + default "0" + help + Size (in bytes) of TIPC's internal log buffer, which records the + occurrence of significant events. Can range from 0 to 32768 bytes; + default is 0. + + There is no need to enable the log buffer unless the node will be + managed remotely via TIPC. + +config TIPC_DEBUG + bool "Enable debugging support" + default n + help + Saying Y here enables TIPC debugging capabilities used by developers. + Most users do not need to bother; if unsure, just say N. + + Enabling debugging support causes TIPC to display data about its + internal state when certain abnormal conditions occur. It also + makes it easy for developers to capture additional information of + interest using the dbg() or msg_dbg() macros. + endif # TIPC diff --git a/trunk/net/tipc/bcast.c b/trunk/net/tipc/bcast.c index e4e6d8cd47e6..d9df34fbd7ca 100644 --- a/trunk/net/tipc/bcast.c +++ b/trunk/net/tipc/bcast.c @@ -701,43 +701,48 @@ void tipc_bcbearer_sort(void) int tipc_bclink_stats(char *buf, const u32 buf_size) { - int ret; - struct tipc_stats *s; + struct print_buf pb; if (!bcl) return 0; + tipc_printbuf_init(&pb, buf, buf_size); + spin_lock_bh(&bc_lock); - s = &bcl->stats; - - ret = tipc_snprintf(buf, buf_size, "Link <%s>\n" - " Window:%u packets\n", - bcl->name, bcl->queue_limit[0]); - ret += tipc_snprintf(buf + ret, buf_size - ret, - " RX packets:%u fragments:%u/%u bundles:%u/%u\n", - s->recv_info, s->recv_fragments, - s->recv_fragmented, s->recv_bundles, - s->recv_bundled); - ret += tipc_snprintf(buf + ret, buf_size - ret, - " TX packets:%u fragments:%u/%u bundles:%u/%u\n", - s->sent_info, s->sent_fragments, - s->sent_fragmented, s->sent_bundles, - s->sent_bundled); - ret += tipc_snprintf(buf + ret, buf_size - ret, - " RX naks:%u defs:%u dups:%u\n", - s->recv_nacks, s->deferred_recv, s->duplicates); - ret += tipc_snprintf(buf + ret, buf_size - ret, - " TX naks:%u acks:%u dups:%u\n", - s->sent_nacks, s->sent_acks, s->retransmitted); - ret += tipc_snprintf(buf + ret, buf_size - ret, - " Congestion bearer:%u link:%u Send queue max:%u avg:%u\n", - s->bearer_congs, s->link_congs, s->max_queue_sz, - s->queue_sz_counts ? - (s->accu_queue_sz / s->queue_sz_counts) : 0); + tipc_printf(&pb, "Link <%s>\n" + " Window:%u packets\n", + bcl->name, bcl->queue_limit[0]); + tipc_printf(&pb, " RX packets:%u fragments:%u/%u bundles:%u/%u\n", + bcl->stats.recv_info, + bcl->stats.recv_fragments, + bcl->stats.recv_fragmented, + bcl->stats.recv_bundles, + bcl->stats.recv_bundled); + tipc_printf(&pb, " TX packets:%u fragments:%u/%u bundles:%u/%u\n", + bcl->stats.sent_info, + bcl->stats.sent_fragments, + bcl->stats.sent_fragmented, + bcl->stats.sent_bundles, + bcl->stats.sent_bundled); + tipc_printf(&pb, " RX naks:%u defs:%u dups:%u\n", + bcl->stats.recv_nacks, + bcl->stats.deferred_recv, + bcl->stats.duplicates); + tipc_printf(&pb, " TX naks:%u acks:%u dups:%u\n", + bcl->stats.sent_nacks, + bcl->stats.sent_acks, + bcl->stats.retransmitted); + tipc_printf(&pb, " Congestion bearer:%u link:%u Send queue max:%u avg:%u\n", + bcl->stats.bearer_congs, + bcl->stats.link_congs, + bcl->stats.max_queue_sz, + bcl->stats.queue_sz_counts + ? (bcl->stats.accu_queue_sz / bcl->stats.queue_sz_counts) + : 0); spin_unlock_bh(&bc_lock); - return ret; + return tipc_printbuf_validate(&pb); } int tipc_bclink_reset_stats(void) @@ -875,7 +880,7 @@ void tipc_port_list_add(struct tipc_port_list *pl_ptr, u32 port) if (!item->next) { item->next = kmalloc(sizeof(*item), GFP_ATOMIC); if (!item->next) { - pr_warn("Incomplete multicast delivery, no memory\n"); + warn("Incomplete multicast delivery, no memory\n"); return; } item->next->next = NULL; diff --git a/trunk/net/tipc/bearer.c b/trunk/net/tipc/bearer.c index 09e71241265d..86b703f55092 100644 --- a/trunk/net/tipc/bearer.c +++ b/trunk/net/tipc/bearer.c @@ -123,30 +123,28 @@ int tipc_register_media(struct tipc_media *m_ptr) exit: write_unlock_bh(&tipc_net_lock); if (res) - pr_warn("Media <%s> registration error\n", m_ptr->name); + warn("Media <%s> registration error\n", m_ptr->name); return res; } /** * tipc_media_addr_printf - record media address in print buffer */ -void tipc_media_addr_printf(char *buf, int len, struct tipc_media_addr *a) +void tipc_media_addr_printf(struct print_buf *pb, struct tipc_media_addr *a) { char addr_str[MAX_ADDR_STR]; struct tipc_media *m_ptr; - int ret; m_ptr = media_find_id(a->media_id); if (m_ptr && !m_ptr->addr2str(a, addr_str, sizeof(addr_str))) - ret = tipc_snprintf(buf, len, "%s(%s)", m_ptr->name, addr_str); + tipc_printf(pb, "%s(%s)", m_ptr->name, addr_str); else { u32 i; - ret = tipc_snprintf(buf, len, "UNKNOWN(%u)", a->media_id); + tipc_printf(pb, "UNKNOWN(%u)", a->media_id); for (i = 0; i < sizeof(a->value); i++) - ret += tipc_snprintf(buf - ret, len + ret, - "-%02x", a->value[i]); + tipc_printf(pb, "-%02x", a->value[i]); } } @@ -420,12 +418,12 @@ int tipc_enable_bearer(const char *name, u32 disc_domain, u32 priority) int res = -EINVAL; if (!tipc_own_addr) { - pr_warn("Bearer <%s> rejected, not supported in standalone mode\n", - name); + warn("Bearer <%s> rejected, not supported in standalone mode\n", + name); return -ENOPROTOOPT; } if (!bearer_name_validate(name, &b_names)) { - pr_warn("Bearer <%s> rejected, illegal name\n", name); + warn("Bearer <%s> rejected, illegal name\n", name); return -EINVAL; } if (tipc_addr_domain_valid(disc_domain) && @@ -437,13 +435,12 @@ int tipc_enable_bearer(const char *name, u32 disc_domain, u32 priority) res = 0; /* accept specified node in own cluster */ } if (res) { - pr_warn("Bearer <%s> rejected, illegal discovery domain\n", - name); + warn("Bearer <%s> rejected, illegal discovery domain\n", name); return -EINVAL; } if ((priority > TIPC_MAX_LINK_PRI) && (priority != TIPC_MEDIA_LINK_PRI)) { - pr_warn("Bearer <%s> rejected, illegal priority\n", name); + warn("Bearer <%s> rejected, illegal priority\n", name); return -EINVAL; } @@ -451,8 +448,8 @@ int tipc_enable_bearer(const char *name, u32 disc_domain, u32 priority) m_ptr = tipc_media_find(b_names.media_name); if (!m_ptr) { - pr_warn("Bearer <%s> rejected, media <%s> not registered\n", - name, b_names.media_name); + warn("Bearer <%s> rejected, media <%s> not registered\n", name, + b_names.media_name); goto exit; } @@ -468,25 +465,24 @@ int tipc_enable_bearer(const char *name, u32 disc_domain, u32 priority) continue; } if (!strcmp(name, tipc_bearers[i].name)) { - pr_warn("Bearer <%s> rejected, already enabled\n", - name); + warn("Bearer <%s> rejected, already enabled\n", name); goto exit; } if ((tipc_bearers[i].priority == priority) && (++with_this_prio > 2)) { if (priority-- == 0) { - pr_warn("Bearer <%s> rejected, duplicate priority\n", - name); + warn("Bearer <%s> rejected, duplicate priority\n", + name); goto exit; } - pr_warn("Bearer <%s> priority adjustment required %u->%u\n", - name, priority + 1, priority); + warn("Bearer <%s> priority adjustment required %u->%u\n", + name, priority + 1, priority); goto restart; } } if (bearer_id >= MAX_BEARERS) { - pr_warn("Bearer <%s> rejected, bearer limit reached (%u)\n", - name, MAX_BEARERS); + warn("Bearer <%s> rejected, bearer limit reached (%u)\n", + name, MAX_BEARERS); goto exit; } @@ -494,8 +490,7 @@ int tipc_enable_bearer(const char *name, u32 disc_domain, u32 priority) strcpy(b_ptr->name, name); res = m_ptr->enable_bearer(b_ptr); if (res) { - pr_warn("Bearer <%s> rejected, enable failure (%d)\n", - name, -res); + warn("Bearer <%s> rejected, enable failure (%d)\n", name, -res); goto exit; } @@ -513,13 +508,12 @@ int tipc_enable_bearer(const char *name, u32 disc_domain, u32 priority) res = tipc_disc_create(b_ptr, &m_ptr->bcast_addr, disc_domain); if (res) { bearer_disable(b_ptr); - pr_warn("Bearer <%s> rejected, discovery object creation failed\n", - name); + warn("Bearer <%s> rejected, discovery object creation failed\n", + name); goto exit; } - pr_info("Enabled bearer <%s>, discovery domain %s, priority %u\n", - name, - tipc_addr_string_fill(addr_string, disc_domain), priority); + info("Enabled bearer <%s>, discovery domain %s, priority %u\n", + name, tipc_addr_string_fill(addr_string, disc_domain), priority); exit: write_unlock_bh(&tipc_net_lock); return res; @@ -537,12 +531,12 @@ int tipc_block_bearer(const char *name) read_lock_bh(&tipc_net_lock); b_ptr = tipc_bearer_find(name); if (!b_ptr) { - pr_warn("Attempt to block unknown bearer <%s>\n", name); + warn("Attempt to block unknown bearer <%s>\n", name); read_unlock_bh(&tipc_net_lock); return -EINVAL; } - pr_info("Blocking bearer <%s>\n", name); + info("Blocking bearer <%s>\n", name); spin_lock_bh(&b_ptr->lock); b_ptr->blocked = 1; list_splice_init(&b_ptr->cong_links, &b_ptr->links); @@ -568,7 +562,7 @@ static void bearer_disable(struct tipc_bearer *b_ptr) struct tipc_link *l_ptr; struct tipc_link *temp_l_ptr; - pr_info("Disabling bearer <%s>\n", b_ptr->name); + info("Disabling bearer <%s>\n", b_ptr->name); spin_lock_bh(&b_ptr->lock); b_ptr->blocked = 1; b_ptr->media->disable_bearer(b_ptr); @@ -590,7 +584,7 @@ int tipc_disable_bearer(const char *name) write_lock_bh(&tipc_net_lock); b_ptr = tipc_bearer_find(name); if (b_ptr == NULL) { - pr_warn("Attempt to disable unknown bearer <%s>\n", name); + warn("Attempt to disable unknown bearer <%s>\n", name); res = -EINVAL; } else { bearer_disable(b_ptr); diff --git a/trunk/net/tipc/bearer.h b/trunk/net/tipc/bearer.h index dd4c2abf08e7..4680de118aff 100644 --- a/trunk/net/tipc/bearer.h +++ b/trunk/net/tipc/bearer.h @@ -179,7 +179,7 @@ void tipc_eth_media_stop(void); int tipc_media_set_priority(const char *name, u32 new_value); int tipc_media_set_window(const char *name, u32 new_value); -void tipc_media_addr_printf(char *buf, int len, struct tipc_media_addr *a); +void tipc_media_addr_printf(struct print_buf *pb, struct tipc_media_addr *a); struct sk_buff *tipc_media_get_names(void); struct sk_buff *tipc_bearer_get_names(void); diff --git a/trunk/net/tipc/config.c b/trunk/net/tipc/config.c index a056a3852f71..c5712a343810 100644 --- a/trunk/net/tipc/config.c +++ b/trunk/net/tipc/config.c @@ -39,8 +39,6 @@ #include "name_table.h" #include "config.h" -#define REPLY_TRUNCATED "\n" - static u32 config_port_ref; static DEFINE_SPINLOCK(config_lock); @@ -106,12 +104,13 @@ struct sk_buff *tipc_cfg_reply_string_type(u16 tlv_type, char *string) return buf; } +#define MAX_STATS_INFO 2000 + static struct sk_buff *tipc_show_stats(void) { struct sk_buff *buf; struct tlv_desc *rep_tlv; - char *pb; - int pb_len; + struct print_buf pb; int str_len; u32 value; @@ -122,16 +121,17 @@ static struct sk_buff *tipc_show_stats(void) if (value != 0) return tipc_cfg_reply_error_string("unsupported argument"); - buf = tipc_cfg_reply_alloc(TLV_SPACE(ULTRA_STRING_MAX_LEN)); + buf = tipc_cfg_reply_alloc(TLV_SPACE(MAX_STATS_INFO)); if (buf == NULL) return NULL; rep_tlv = (struct tlv_desc *)buf->data; - pb = TLV_DATA(rep_tlv); - pb_len = ULTRA_STRING_MAX_LEN; + tipc_printbuf_init(&pb, (char *)TLV_DATA(rep_tlv), MAX_STATS_INFO); + + tipc_printf(&pb, "TIPC version " TIPC_MOD_VER "\n"); - str_len = tipc_snprintf(pb, pb_len, "TIPC version " TIPC_MOD_VER "\n"); - str_len += 1; /* for "\0" */ + /* Use additional tipc_printf()'s to return more info ... */ + str_len = tipc_printbuf_validate(&pb); skb_put(buf, TLV_SPACE(str_len)); TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len); @@ -334,6 +334,12 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area case TIPC_CMD_SHOW_PORTS: rep_tlv_buf = tipc_port_get_ports(); break; + case TIPC_CMD_SET_LOG_SIZE: + rep_tlv_buf = tipc_log_resize_cmd(req_tlv_area, req_tlv_space); + break; + case TIPC_CMD_DUMP_LOG: + rep_tlv_buf = tipc_log_dump(); + break; case TIPC_CMD_SHOW_STATS: rep_tlv_buf = tipc_show_stats(); break; @@ -393,8 +399,6 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area case TIPC_CMD_GET_MAX_CLUSTERS: case TIPC_CMD_SET_MAX_NODES: case TIPC_CMD_GET_MAX_NODES: - case TIPC_CMD_SET_LOG_SIZE: - case TIPC_CMD_DUMP_LOG: rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED " (obsolete command)"); break; @@ -404,15 +408,6 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area break; } - WARN_ON(rep_tlv_buf->len > TLV_SPACE(ULTRA_STRING_MAX_LEN)); - - /* Append an error message if we cannot return all requested data */ - if (rep_tlv_buf->len == TLV_SPACE(ULTRA_STRING_MAX_LEN)) { - if (*(rep_tlv_buf->data + ULTRA_STRING_MAX_LEN) != '\0') - sprintf(rep_tlv_buf->data + rep_tlv_buf->len - - sizeof(REPLY_TRUNCATED) - 1, REPLY_TRUNCATED); - } - /* Return reply buffer */ exit: spin_unlock_bh(&config_lock); @@ -437,7 +432,7 @@ static void cfg_named_msg_event(void *userdata, if ((size < sizeof(*req_hdr)) || (size != TCM_ALIGN(ntohl(req_hdr->tcm_len))) || (ntohs(req_hdr->tcm_flags) != TCM_F_REQUEST)) { - pr_warn("Invalid configuration message discarded\n"); + warn("Invalid configuration message discarded\n"); return; } @@ -483,7 +478,7 @@ int tipc_cfg_init(void) return 0; failed: - pr_err("Unable to create configuration service\n"); + err("Unable to create configuration service\n"); return res; } @@ -499,7 +494,7 @@ void tipc_cfg_reinit(void) seq.lower = seq.upper = tipc_own_addr; res = tipc_publish(config_port_ref, TIPC_ZONE_SCOPE, &seq); if (res) - pr_err("Unable to reinitialize configuration service\n"); + err("Unable to reinitialize configuration service\n"); } void tipc_cfg_stop(void) diff --git a/trunk/net/tipc/core.c b/trunk/net/tipc/core.c index 6586eac6a50e..f7b95239ebda 100644 --- a/trunk/net/tipc/core.c +++ b/trunk/net/tipc/core.c @@ -34,18 +34,22 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include + #include "core.h" #include "ref.h" #include "name_table.h" #include "subscr.h" #include "config.h" -#include #ifndef CONFIG_TIPC_PORTS #define CONFIG_TIPC_PORTS 8191 #endif +#ifndef CONFIG_TIPC_LOG +#define CONFIG_TIPC_LOG 0 +#endif /* global variables used by multiple sub-systems within TIPC */ int tipc_random; @@ -121,6 +125,7 @@ static void tipc_core_stop(void) tipc_nametbl_stop(); tipc_ref_table_stop(); tipc_socket_stop(); + tipc_log_resize(0); } /** @@ -156,7 +161,10 @@ static int __init tipc_init(void) { int res; - pr_info("Activated (version " TIPC_MOD_VER ")\n"); + if (tipc_log_resize(CONFIG_TIPC_LOG) != 0) + warn("Unable to create log buffer\n"); + + info("Activated (version " TIPC_MOD_VER ")\n"); tipc_own_addr = 0; tipc_remote_management = 1; @@ -167,9 +175,9 @@ static int __init tipc_init(void) res = tipc_core_start(); if (res) - pr_err("Unable to start in single node mode\n"); + err("Unable to start in single node mode\n"); else - pr_info("Started in single node mode\n"); + info("Started in single node mode\n"); return res; } @@ -177,7 +185,7 @@ static void __exit tipc_exit(void) { tipc_core_stop_net(); tipc_core_stop(); - pr_info("Deactivated\n"); + info("Deactivated\n"); } module_init(tipc_init); diff --git a/trunk/net/tipc/core.h b/trunk/net/tipc/core.h index fd42e106c185..2a9bb99537b3 100644 --- a/trunk/net/tipc/core.h +++ b/trunk/net/tipc/core.h @@ -37,8 +37,6 @@ #ifndef _TIPC_CORE_H #define _TIPC_CORE_H -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -60,11 +58,68 @@ #define TIPC_MOD_VER "2.0.0" -#define ULTRA_STRING_MAX_LEN 32768 - struct tipc_msg; /* msg.h */ +struct print_buf; /* log.h */ + +/* + * TIPC system monitoring code + */ + +/* + * TIPC's print buffer subsystem supports the following print buffers: + * + * TIPC_NULL : null buffer (i.e. print nowhere) + * TIPC_CONS : system console + * TIPC_LOG : TIPC log buffer + * &buf : user-defined buffer (struct print_buf *) + * + * Note: TIPC_LOG is configured to echo its output to the system console; + * user-defined buffers can be configured to do the same thing. + */ +extern struct print_buf *const TIPC_NULL; +extern struct print_buf *const TIPC_CONS; +extern struct print_buf *const TIPC_LOG; + +void tipc_printf(struct print_buf *, const char *fmt, ...); + +/* + * TIPC_OUTPUT is the destination print buffer for system messages. + */ +#ifndef TIPC_OUTPUT +#define TIPC_OUTPUT TIPC_LOG +#endif + +#define err(fmt, arg...) tipc_printf(TIPC_OUTPUT, \ + KERN_ERR "TIPC: " fmt, ## arg) +#define warn(fmt, arg...) tipc_printf(TIPC_OUTPUT, \ + KERN_WARNING "TIPC: " fmt, ## arg) +#define info(fmt, arg...) tipc_printf(TIPC_OUTPUT, \ + KERN_NOTICE "TIPC: " fmt, ## arg) + +#ifdef CONFIG_TIPC_DEBUG + +/* + * DBG_OUTPUT is the destination print buffer for debug messages. + */ +#ifndef DBG_OUTPUT +#define DBG_OUTPUT TIPC_LOG +#endif + +#define dbg(fmt, arg...) tipc_printf(DBG_OUTPUT, KERN_DEBUG fmt, ## arg); + +#define msg_dbg(msg, txt) tipc_msg_dbg(DBG_OUTPUT, msg, txt); + +void tipc_msg_dbg(struct print_buf *, struct tipc_msg *, const char *); + +#else + +#define dbg(fmt, arg...) do {} while (0) +#define msg_dbg(msg, txt) do {} while (0) + +#define tipc_msg_dbg(buf, msg, txt) do {} while (0) + +#endif -int tipc_snprintf(char *buf, int len, const char *fmt, ...); /* * TIPC-specific error codes diff --git a/trunk/net/tipc/discover.c b/trunk/net/tipc/discover.c index 50eaa403eb6e..ae054cfe179f 100644 --- a/trunk/net/tipc/discover.c +++ b/trunk/net/tipc/discover.c @@ -100,12 +100,14 @@ static void disc_dupl_alert(struct tipc_bearer *b_ptr, u32 node_addr, { char node_addr_str[16]; char media_addr_str[64]; + struct print_buf pb; tipc_addr_string_fill(node_addr_str, node_addr); - tipc_media_addr_printf(media_addr_str, sizeof(media_addr_str), - media_addr); - pr_warn("Duplicate %s using %s seen on <%s>\n", node_addr_str, - media_addr_str, b_ptr->name); + tipc_printbuf_init(&pb, media_addr_str, sizeof(media_addr_str)); + tipc_media_addr_printf(&pb, media_addr); + tipc_printbuf_validate(&pb); + warn("Duplicate %s using %s seen on <%s>\n", + node_addr_str, media_addr_str, b_ptr->name); } /** diff --git a/trunk/net/tipc/handler.c b/trunk/net/tipc/handler.c index 7a52d3922f3c..9c6f22ff1c6d 100644 --- a/trunk/net/tipc/handler.c +++ b/trunk/net/tipc/handler.c @@ -57,14 +57,14 @@ unsigned int tipc_k_signal(Handler routine, unsigned long argument) struct queue_item *item; if (!handler_enabled) { - pr_err("Signal request ignored by handler\n"); + err("Signal request ignored by handler\n"); return -ENOPROTOOPT; } spin_lock_bh(&qitem_lock); item = kmem_cache_alloc(tipc_queue_item_cache, GFP_ATOMIC); if (!item) { - pr_err("Signal queue out of memory\n"); + err("Signal queue out of memory\n"); spin_unlock_bh(&qitem_lock); return -ENOMEM; } diff --git a/trunk/net/tipc/link.c b/trunk/net/tipc/link.c index 1c1e6151875e..f6bf4830ddfe 100644 --- a/trunk/net/tipc/link.c +++ b/trunk/net/tipc/link.c @@ -41,12 +41,6 @@ #include "discover.h" #include "config.h" -/* - * Error message prefixes - */ -static const char *link_co_err = "Link changeover error, "; -static const char *link_rst_msg = "Resetting link "; -static const char *link_unk_evt = "Unknown link event "; /* * Out-of-range value for link session numbers @@ -306,20 +300,20 @@ struct tipc_link *tipc_link_create(struct tipc_node *n_ptr, if (n_ptr->link_cnt >= 2) { tipc_addr_string_fill(addr_string, n_ptr->addr); - pr_err("Attempt to establish third link to %s\n", addr_string); + err("Attempt to establish third link to %s\n", addr_string); return NULL; } if (n_ptr->links[b_ptr->identity]) { tipc_addr_string_fill(addr_string, n_ptr->addr); - pr_err("Attempt to establish second link on <%s> to %s\n", - b_ptr->name, addr_string); + err("Attempt to establish second link on <%s> to %s\n", + b_ptr->name, addr_string); return NULL; } l_ptr = kzalloc(sizeof(*l_ptr), GFP_ATOMIC); if (!l_ptr) { - pr_warn("Link creation failed, no memory\n"); + warn("Link creation failed, no memory\n"); return NULL; } @@ -377,7 +371,7 @@ struct tipc_link *tipc_link_create(struct tipc_node *n_ptr, void tipc_link_delete(struct tipc_link *l_ptr) { if (!l_ptr) { - pr_err("Attempt to delete non-existent link\n"); + err("Attempt to delete non-existent link\n"); return; } @@ -638,8 +632,8 @@ static void link_state_event(struct tipc_link *l_ptr, unsigned int event) link_set_timer(l_ptr, cont_intv / 4); break; case RESET_MSG: - pr_info("%s<%s>, requested by peer\n", link_rst_msg, - l_ptr->name); + info("Resetting link <%s>, requested by peer\n", + l_ptr->name); tipc_link_reset(l_ptr); l_ptr->state = RESET_RESET; l_ptr->fsm_msg_cnt = 0; @@ -648,7 +642,7 @@ static void link_state_event(struct tipc_link *l_ptr, unsigned int event) link_set_timer(l_ptr, cont_intv); break; default: - pr_err("%s%u in WW state\n", link_unk_evt, event); + err("Unknown link event %u in WW state\n", event); } break; case WORKING_UNKNOWN: @@ -660,8 +654,8 @@ static void link_state_event(struct tipc_link *l_ptr, unsigned int event) link_set_timer(l_ptr, cont_intv); break; case RESET_MSG: - pr_info("%s<%s>, requested by peer while probing\n", - link_rst_msg, l_ptr->name); + info("Resetting link <%s>, requested by peer " + "while probing\n", l_ptr->name); tipc_link_reset(l_ptr); l_ptr->state = RESET_RESET; l_ptr->fsm_msg_cnt = 0; @@ -686,8 +680,8 @@ static void link_state_event(struct tipc_link *l_ptr, unsigned int event) l_ptr->fsm_msg_cnt++; link_set_timer(l_ptr, cont_intv / 4); } else { /* Link has failed */ - pr_warn("%s<%s>, peer not responding\n", - link_rst_msg, l_ptr->name); + warn("Resetting link <%s>, peer not responding\n", + l_ptr->name); tipc_link_reset(l_ptr); l_ptr->state = RESET_UNKNOWN; l_ptr->fsm_msg_cnt = 0; @@ -698,7 +692,7 @@ static void link_state_event(struct tipc_link *l_ptr, unsigned int event) } break; default: - pr_err("%s%u in WU state\n", link_unk_evt, event); + err("Unknown link event %u in WU state\n", event); } break; case RESET_UNKNOWN: @@ -732,7 +726,7 @@ static void link_state_event(struct tipc_link *l_ptr, unsigned int event) link_set_timer(l_ptr, cont_intv); break; default: - pr_err("%s%u in RU state\n", link_unk_evt, event); + err("Unknown link event %u in RU state\n", event); } break; case RESET_RESET: @@ -757,11 +751,11 @@ static void link_state_event(struct tipc_link *l_ptr, unsigned int event) link_set_timer(l_ptr, cont_intv); break; default: - pr_err("%s%u in RR state\n", link_unk_evt, event); + err("Unknown link event %u in RR state\n", event); } break; default: - pr_err("Unknown link state %u/%u\n", l_ptr->state, event); + err("Unknown link state %u/%u\n", l_ptr->state, event); } } @@ -862,8 +856,7 @@ int tipc_link_send_buf(struct tipc_link *l_ptr, struct sk_buff *buf) } kfree_skb(buf); if (imp > CONN_MANAGER) { - pr_warn("%s<%s>, send queue full", link_rst_msg, - l_ptr->name); + warn("Resetting link <%s>, send queue full", l_ptr->name); tipc_link_reset(l_ptr); } return dsz; @@ -1416,8 +1409,8 @@ static void link_reset_all(unsigned long addr) tipc_node_lock(n_ptr); - pr_warn("Resetting all links to %s\n", - tipc_addr_string_fill(addr_string, n_ptr->addr)); + warn("Resetting all links to %s\n", + tipc_addr_string_fill(addr_string, n_ptr->addr)); for (i = 0; i < MAX_BEARERS; i++) { if (n_ptr->links[i]) { @@ -1435,7 +1428,7 @@ static void link_retransmit_failure(struct tipc_link *l_ptr, { struct tipc_msg *msg = buf_msg(buf); - pr_warn("Retransmission failure on link <%s>\n", l_ptr->name); + warn("Retransmission failure on link <%s>\n", l_ptr->name); if (l_ptr->addr) { /* Handle failure on standard link */ @@ -1447,23 +1440,21 @@ static void link_retransmit_failure(struct tipc_link *l_ptr, struct tipc_node *n_ptr; char addr_string[16]; - pr_info("Msg seq number: %u, ", msg_seqno(msg)); - pr_cont("Outstanding acks: %lu\n", - (unsigned long) TIPC_SKB_CB(buf)->handle); + info("Msg seq number: %u, ", msg_seqno(msg)); + info("Outstanding acks: %lu\n", + (unsigned long) TIPC_SKB_CB(buf)->handle); n_ptr = tipc_bclink_retransmit_to(); tipc_node_lock(n_ptr); tipc_addr_string_fill(addr_string, n_ptr->addr); - pr_info("Broadcast link info for %s\n", addr_string); - pr_info("Supportable: %d, Supported: %d, Acked: %u\n", - n_ptr->bclink.supportable, - n_ptr->bclink.supported, - n_ptr->bclink.acked); - pr_info("Last in: %u, Oos state: %u, Last sent: %u\n", - n_ptr->bclink.last_in, - n_ptr->bclink.oos_state, - n_ptr->bclink.last_sent); + info("Broadcast link info for %s\n", addr_string); + info("Supportable: %d, ", n_ptr->bclink.supportable); + info("Supported: %d, ", n_ptr->bclink.supported); + info("Acked: %u\n", n_ptr->bclink.acked); + info("Last in: %u, ", n_ptr->bclink.last_in); + info("Oos state: %u, ", n_ptr->bclink.oos_state); + info("Last sent: %u\n", n_ptr->bclink.last_sent); tipc_k_signal((Handler)link_reset_all, (unsigned long)n_ptr->addr); @@ -1488,8 +1479,8 @@ void tipc_link_retransmit(struct tipc_link *l_ptr, struct sk_buff *buf, l_ptr->retransm_queue_head = msg_seqno(msg); l_ptr->retransm_queue_size = retransmits; } else { - pr_err("Unexpected retransmit on link %s (qsize=%d)\n", - l_ptr->name, l_ptr->retransm_queue_size); + err("Unexpected retransmit on link %s (qsize=%d)\n", + l_ptr->name, l_ptr->retransm_queue_size); } return; } else { @@ -2083,9 +2074,8 @@ static void link_recv_proto_msg(struct tipc_link *l_ptr, struct sk_buff *buf) if (msg_linkprio(msg) && (msg_linkprio(msg) != l_ptr->priority)) { - pr_warn("%s<%s>, priority change %u->%u\n", - link_rst_msg, l_ptr->name, l_ptr->priority, - msg_linkprio(msg)); + warn("Resetting link <%s>, priority change %u->%u\n", + l_ptr->name, l_ptr->priority, msg_linkprio(msg)); l_ptr->priority = msg_linkprio(msg); tipc_link_reset(l_ptr); /* Enforce change to take effect */ break; @@ -2149,13 +2139,15 @@ static void tipc_link_tunnel(struct tipc_link *l_ptr, tunnel = l_ptr->owner->active_links[selector & 1]; if (!tipc_link_is_up(tunnel)) { - pr_warn("%stunnel link no longer available\n", link_co_err); + warn("Link changeover error, " + "tunnel link no longer available\n"); return; } msg_set_size(tunnel_hdr, length + INT_H_SIZE); buf = tipc_buf_acquire(length + INT_H_SIZE); if (!buf) { - pr_warn("%sunable to send tunnel msg\n", link_co_err); + warn("Link changeover error, " + "unable to send tunnel msg\n"); return; } skb_copy_to_linear_data(buf, tunnel_hdr, INT_H_SIZE); @@ -2181,7 +2173,8 @@ void tipc_link_changeover(struct tipc_link *l_ptr) return; if (!l_ptr->owner->permit_changeover) { - pr_warn("%speer did not permit changeover\n", link_co_err); + warn("Link changeover error, " + "peer did not permit changeover\n"); return; } @@ -2199,8 +2192,8 @@ void tipc_link_changeover(struct tipc_link *l_ptr) msg_set_size(&tunnel_hdr, INT_H_SIZE); tipc_link_send_buf(tunnel, buf); } else { - pr_warn("%sunable to send changeover msg\n", - link_co_err); + warn("Link changeover error, " + "unable to send changeover msg\n"); } return; } @@ -2253,8 +2246,8 @@ void tipc_link_send_duplicate(struct tipc_link *l_ptr, struct tipc_link *tunnel) msg_set_size(&tunnel_hdr, length + INT_H_SIZE); outbuf = tipc_buf_acquire(length + INT_H_SIZE); if (outbuf == NULL) { - pr_warn("%sunable to send duplicate msg\n", - link_co_err); + warn("Link changeover error, " + "unable to send duplicate msg\n"); return; } skb_copy_to_linear_data(outbuf, &tunnel_hdr, INT_H_SIZE); @@ -2305,8 +2298,8 @@ static int link_recv_changeover_msg(struct tipc_link **l_ptr, if (!dest_link) goto exit; if (dest_link == *l_ptr) { - pr_err("Unexpected changeover message on link <%s>\n", - (*l_ptr)->name); + err("Unexpected changeover message on link <%s>\n", + (*l_ptr)->name); goto exit; } *l_ptr = dest_link; @@ -2317,7 +2310,7 @@ static int link_recv_changeover_msg(struct tipc_link **l_ptr, goto exit; *buf = buf_extract(tunnel_buf, INT_H_SIZE); if (*buf == NULL) { - pr_warn("%sduplicate msg dropped\n", link_co_err); + warn("Link changeover error, duplicate msg dropped\n"); goto exit; } kfree_skb(tunnel_buf); @@ -2326,8 +2319,8 @@ static int link_recv_changeover_msg(struct tipc_link **l_ptr, /* First original message ?: */ if (tipc_link_is_up(dest_link)) { - pr_info("%s<%s>, changeover initiated by peer\n", link_rst_msg, - dest_link->name); + info("Resetting link <%s>, changeover initiated by peer\n", + dest_link->name); tipc_link_reset(dest_link); dest_link->exp_msg_count = msg_count; if (!msg_count) @@ -2340,7 +2333,8 @@ static int link_recv_changeover_msg(struct tipc_link **l_ptr, /* Receive original message */ if (dest_link->exp_msg_count == 0) { - pr_warn("%sgot too many tunnelled messages\n", link_co_err); + warn("Link switchover error, " + "got too many tunnelled messages\n"); goto exit; } dest_link->exp_msg_count--; @@ -2352,7 +2346,7 @@ static int link_recv_changeover_msg(struct tipc_link **l_ptr, kfree_skb(tunnel_buf); return 1; } else { - pr_warn("%soriginal msg dropped\n", link_co_err); + warn("Link changeover error, original msg dropped\n"); } } exit: @@ -2373,7 +2367,7 @@ void tipc_link_recv_bundle(struct sk_buff *buf) while (msgcount--) { obuf = buf_extract(buf, pos); if (obuf == NULL) { - pr_warn("Link unable to unbundle message(s)\n"); + warn("Link unable to unbundle message(s)\n"); break; } pos += align(msg_size(buf_msg(obuf))); @@ -2544,7 +2538,7 @@ int tipc_link_recv_fragment(struct sk_buff **pending, struct sk_buff **fb, set_fragm_size(pbuf, fragm_sz); set_expected_frags(pbuf, exp_fragm_cnt - 1); } else { - pr_debug("Link unable to reassemble fragmented message\n"); + dbg("Link unable to reassemble fragmented message\n"); kfree_skb(fbuf); return -1; } @@ -2866,114 +2860,112 @@ static u32 percent(u32 count, u32 total) */ static int tipc_link_stats(const char *name, char *buf, const u32 buf_size) { - struct tipc_link *l; - struct tipc_stats *s; + struct print_buf pb; + struct tipc_link *l_ptr; struct tipc_node *node; char *status; u32 profile_total = 0; - int ret; if (!strcmp(name, tipc_bclink_name)) return tipc_bclink_stats(buf, buf_size); + tipc_printbuf_init(&pb, buf, buf_size); + read_lock_bh(&tipc_net_lock); - l = link_find_link(name, &node); - if (!l) { + l_ptr = link_find_link(name, &node); + if (!l_ptr) { read_unlock_bh(&tipc_net_lock); return 0; } tipc_node_lock(node); - s = &l->stats; - if (tipc_link_is_active(l)) + if (tipc_link_is_active(l_ptr)) status = "ACTIVE"; - else if (tipc_link_is_up(l)) + else if (tipc_link_is_up(l_ptr)) status = "STANDBY"; else status = "DEFUNCT"; - - ret = tipc_snprintf(buf, buf_size, "Link <%s>\n" - " %s MTU:%u Priority:%u Tolerance:%u ms" - " Window:%u packets\n", - l->name, status, l->max_pkt, l->priority, - l->tolerance, l->queue_limit[0]); - - ret += tipc_snprintf(buf + ret, buf_size - ret, - " RX packets:%u fragments:%u/%u bundles:%u/%u\n", - l->next_in_no - s->recv_info, s->recv_fragments, - s->recv_fragmented, s->recv_bundles, - s->recv_bundled); - - ret += tipc_snprintf(buf + ret, buf_size - ret, - " TX packets:%u fragments:%u/%u bundles:%u/%u\n", - l->next_out_no - s->sent_info, s->sent_fragments, - s->sent_fragmented, s->sent_bundles, - s->sent_bundled); - - profile_total = s->msg_length_counts; + tipc_printf(&pb, "Link <%s>\n" + " %s MTU:%u Priority:%u Tolerance:%u ms" + " Window:%u packets\n", + l_ptr->name, status, l_ptr->max_pkt, + l_ptr->priority, l_ptr->tolerance, l_ptr->queue_limit[0]); + tipc_printf(&pb, " RX packets:%u fragments:%u/%u bundles:%u/%u\n", + l_ptr->next_in_no - l_ptr->stats.recv_info, + l_ptr->stats.recv_fragments, + l_ptr->stats.recv_fragmented, + l_ptr->stats.recv_bundles, + l_ptr->stats.recv_bundled); + tipc_printf(&pb, " TX packets:%u fragments:%u/%u bundles:%u/%u\n", + l_ptr->next_out_no - l_ptr->stats.sent_info, + l_ptr->stats.sent_fragments, + l_ptr->stats.sent_fragmented, + l_ptr->stats.sent_bundles, + l_ptr->stats.sent_bundled); + profile_total = l_ptr->stats.msg_length_counts; if (!profile_total) profile_total = 1; - - ret += tipc_snprintf(buf + ret, buf_size - ret, - " TX profile sample:%u packets average:%u octets\n" - " 0-64:%u%% -256:%u%% -1024:%u%% -4096:%u%% " - "-16384:%u%% -32768:%u%% -66000:%u%%\n", - s->msg_length_counts, - s->msg_lengths_total / profile_total, - percent(s->msg_length_profile[0], profile_total), - percent(s->msg_length_profile[1], profile_total), - percent(s->msg_length_profile[2], profile_total), - percent(s->msg_length_profile[3], profile_total), - percent(s->msg_length_profile[4], profile_total), - percent(s->msg_length_profile[5], profile_total), - percent(s->msg_length_profile[6], profile_total)); - - ret += tipc_snprintf(buf + ret, buf_size - ret, - " RX states:%u probes:%u naks:%u defs:%u" - " dups:%u\n", s->recv_states, s->recv_probes, - s->recv_nacks, s->deferred_recv, s->duplicates); - - ret += tipc_snprintf(buf + ret, buf_size - ret, - " TX states:%u probes:%u naks:%u acks:%u" - " dups:%u\n", s->sent_states, s->sent_probes, - s->sent_nacks, s->sent_acks, s->retransmitted); - - ret += tipc_snprintf(buf + ret, buf_size - ret, - " Congestion bearer:%u link:%u Send queue" - " max:%u avg:%u\n", s->bearer_congs, s->link_congs, - s->max_queue_sz, s->queue_sz_counts ? - (s->accu_queue_sz / s->queue_sz_counts) : 0); + tipc_printf(&pb, " TX profile sample:%u packets average:%u octets\n" + " 0-64:%u%% -256:%u%% -1024:%u%% -4096:%u%% " + "-16384:%u%% -32768:%u%% -66000:%u%%\n", + l_ptr->stats.msg_length_counts, + l_ptr->stats.msg_lengths_total / profile_total, + percent(l_ptr->stats.msg_length_profile[0], profile_total), + percent(l_ptr->stats.msg_length_profile[1], profile_total), + percent(l_ptr->stats.msg_length_profile[2], profile_total), + percent(l_ptr->stats.msg_length_profile[3], profile_total), + percent(l_ptr->stats.msg_length_profile[4], profile_total), + percent(l_ptr->stats.msg_length_profile[5], profile_total), + percent(l_ptr->stats.msg_length_profile[6], profile_total)); + tipc_printf(&pb, " RX states:%u probes:%u naks:%u defs:%u dups:%u\n", + l_ptr->stats.recv_states, + l_ptr->stats.recv_probes, + l_ptr->stats.recv_nacks, + l_ptr->stats.deferred_recv, + l_ptr->stats.duplicates); + tipc_printf(&pb, " TX states:%u probes:%u naks:%u acks:%u dups:%u\n", + l_ptr->stats.sent_states, + l_ptr->stats.sent_probes, + l_ptr->stats.sent_nacks, + l_ptr->stats.sent_acks, + l_ptr->stats.retransmitted); + tipc_printf(&pb, " Congestion bearer:%u link:%u Send queue max:%u avg:%u\n", + l_ptr->stats.bearer_congs, + l_ptr->stats.link_congs, + l_ptr->stats.max_queue_sz, + l_ptr->stats.queue_sz_counts + ? (l_ptr->stats.accu_queue_sz / l_ptr->stats.queue_sz_counts) + : 0); tipc_node_unlock(node); read_unlock_bh(&tipc_net_lock); - return ret; + return tipc_printbuf_validate(&pb); } +#define MAX_LINK_STATS_INFO 2000 + struct sk_buff *tipc_link_cmd_show_stats(const void *req_tlv_area, int req_tlv_space) { struct sk_buff *buf; struct tlv_desc *rep_tlv; int str_len; - int pb_len; - char *pb; if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_LINK_NAME)) return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); - buf = tipc_cfg_reply_alloc(TLV_SPACE(ULTRA_STRING_MAX_LEN)); + buf = tipc_cfg_reply_alloc(TLV_SPACE(MAX_LINK_STATS_INFO)); if (!buf) return NULL; rep_tlv = (struct tlv_desc *)buf->data; - pb = TLV_DATA(rep_tlv); - pb_len = ULTRA_STRING_MAX_LEN; + str_len = tipc_link_stats((char *)TLV_DATA(req_tlv_area), - pb, pb_len); + (char *)TLV_DATA(rep_tlv), MAX_LINK_STATS_INFO); if (!str_len) { kfree_skb(buf); return tipc_cfg_reply_error_string("link not found"); } - str_len += 1; /* for "\0" */ + skb_put(buf, TLV_SPACE(str_len)); TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len); @@ -3011,16 +3003,62 @@ u32 tipc_link_get_max_pkt(u32 dest, u32 selector) static void link_print(struct tipc_link *l_ptr, const char *str) { - pr_info("%s Link %x<%s>:", str, l_ptr->addr, l_ptr->b_ptr->name); + char print_area[256]; + struct print_buf pb; + struct print_buf *buf = &pb; + + tipc_printbuf_init(buf, print_area, sizeof(print_area)); + + tipc_printf(buf, str); + tipc_printf(buf, "Link %x<%s>:", + l_ptr->addr, l_ptr->b_ptr->name); + +#ifdef CONFIG_TIPC_DEBUG + if (link_reset_reset(l_ptr) || link_reset_unknown(l_ptr)) + goto print_state; + + tipc_printf(buf, ": NXO(%u):", mod(l_ptr->next_out_no)); + tipc_printf(buf, "NXI(%u):", mod(l_ptr->next_in_no)); + tipc_printf(buf, "SQUE"); + if (l_ptr->first_out) { + tipc_printf(buf, "[%u..", buf_seqno(l_ptr->first_out)); + if (l_ptr->next_out) + tipc_printf(buf, "%u..", buf_seqno(l_ptr->next_out)); + tipc_printf(buf, "%u]", buf_seqno(l_ptr->last_out)); + if ((mod(buf_seqno(l_ptr->last_out) - + buf_seqno(l_ptr->first_out)) + != (l_ptr->out_queue_size - 1)) || + (l_ptr->last_out->next != NULL)) { + tipc_printf(buf, "\nSend queue inconsistency\n"); + tipc_printf(buf, "first_out= %p ", l_ptr->first_out); + tipc_printf(buf, "next_out= %p ", l_ptr->next_out); + tipc_printf(buf, "last_out= %p ", l_ptr->last_out); + } + } else + tipc_printf(buf, "[]"); + tipc_printf(buf, "SQSIZ(%u)", l_ptr->out_queue_size); + if (l_ptr->oldest_deferred_in) { + u32 o = buf_seqno(l_ptr->oldest_deferred_in); + u32 n = buf_seqno(l_ptr->newest_deferred_in); + tipc_printf(buf, ":RQUE[%u..%u]", o, n); + if (l_ptr->deferred_inqueue_sz != mod((n + 1) - o)) { + tipc_printf(buf, ":RQSIZ(%u)", + l_ptr->deferred_inqueue_sz); + } + } +print_state: +#endif if (link_working_unknown(l_ptr)) - pr_cont(":WU\n"); + tipc_printf(buf, ":WU"); else if (link_reset_reset(l_ptr)) - pr_cont(":RR\n"); + tipc_printf(buf, ":RR"); else if (link_reset_unknown(l_ptr)) - pr_cont(":RU\n"); + tipc_printf(buf, ":RU"); else if (link_working_working(l_ptr)) - pr_cont(":WW\n"); - else - pr_cont("\n"); + tipc_printf(buf, ":WW"); + tipc_printf(buf, "\n"); + + tipc_printbuf_validate(buf); + info("%s", print_area); } diff --git a/trunk/net/tipc/link.h b/trunk/net/tipc/link.h index 6e921121be06..d6a60a963ce6 100644 --- a/trunk/net/tipc/link.h +++ b/trunk/net/tipc/link.h @@ -37,6 +37,7 @@ #ifndef _TIPC_LINK_H #define _TIPC_LINK_H +#include "log.h" #include "msg.h" #include "node.h" @@ -62,37 +63,6 @@ */ #define MAX_PKT_DEFAULT 1500 -struct tipc_stats { - u32 sent_info; /* used in counting # sent packets */ - u32 recv_info; /* used in counting # recv'd packets */ - u32 sent_states; - u32 recv_states; - u32 sent_probes; - u32 recv_probes; - u32 sent_nacks; - u32 recv_nacks; - u32 sent_acks; - u32 sent_bundled; - u32 sent_bundles; - u32 recv_bundled; - u32 recv_bundles; - u32 retransmitted; - u32 sent_fragmented; - u32 sent_fragments; - u32 recv_fragmented; - u32 recv_fragments; - u32 link_congs; /* # port sends blocked by congestion */ - u32 bearer_congs; - u32 deferred_recv; - u32 duplicates; - u32 max_queue_sz; /* send queue size high water mark */ - u32 accu_queue_sz; /* used for send queue size profiling */ - u32 queue_sz_counts; /* used for send queue size profiling */ - u32 msg_length_counts; /* used for message length profiling */ - u32 msg_lengths_total; /* used for message length profiling */ - u32 msg_length_profile[7]; /* used for msg. length profiling */ -}; - /** * struct tipc_link - TIPC link data structure * @addr: network address of link's peer node @@ -205,7 +175,36 @@ struct tipc_link { struct sk_buff *defragm_buf; /* Statistics */ - struct tipc_stats stats; + struct { + u32 sent_info; /* used in counting # sent packets */ + u32 recv_info; /* used in counting # recv'd packets */ + u32 sent_states; + u32 recv_states; + u32 sent_probes; + u32 recv_probes; + u32 sent_nacks; + u32 recv_nacks; + u32 sent_acks; + u32 sent_bundled; + u32 sent_bundles; + u32 recv_bundled; + u32 recv_bundles; + u32 retransmitted; + u32 sent_fragmented; + u32 sent_fragments; + u32 recv_fragmented; + u32 recv_fragments; + u32 link_congs; /* # port sends blocked by congestion */ + u32 bearer_congs; + u32 deferred_recv; + u32 duplicates; + u32 max_queue_sz; /* send queue size high water mark */ + u32 accu_queue_sz; /* used for send queue size profiling */ + u32 queue_sz_counts; /* used for send queue size profiling */ + u32 msg_length_counts; /* used for message length profiling */ + u32 msg_lengths_total; /* used for message length profiling */ + u32 msg_length_profile[7]; /* used for msg. length profiling */ + } stats; }; struct tipc_port; diff --git a/trunk/net/tipc/log.c b/trunk/net/tipc/log.c index abef644f27d8..026733f24919 100644 --- a/trunk/net/tipc/log.c +++ b/trunk/net/tipc/log.c @@ -36,20 +36,302 @@ #include "core.h" #include "config.h" +#include "log.h" + +/* + * TIPC pre-defines the following print buffers: + * + * TIPC_NULL : null buffer (i.e. print nowhere) + * TIPC_CONS : system console + * TIPC_LOG : TIPC log buffer + * + * Additional user-defined print buffers are also permitted. + */ +static struct print_buf null_buf = { NULL, 0, NULL, 0 }; +struct print_buf *const TIPC_NULL = &null_buf; + +static struct print_buf cons_buf = { NULL, 0, NULL, 1 }; +struct print_buf *const TIPC_CONS = &cons_buf; + +static struct print_buf log_buf = { NULL, 0, NULL, 1 }; +struct print_buf *const TIPC_LOG = &log_buf; + +/* + * Locking policy when using print buffers. + * + * 1) tipc_printf() uses 'print_lock' to protect against concurrent access to + * 'print_string' when writing to a print buffer. This also protects against + * concurrent writes to the print buffer being written to. + * + * 2) tipc_log_XXX() leverages the aforementioned use of 'print_lock' to + * protect against all types of concurrent operations on their associated + * print buffer (not just write operations). + * + * Note: All routines of the form tipc_printbuf_XXX() are lock-free, and rely + * on the caller to prevent simultaneous use of the print buffer(s) being + * manipulated. + */ +static char print_string[TIPC_PB_MAX_STR]; +static DEFINE_SPINLOCK(print_lock); + +static void tipc_printbuf_move(struct print_buf *pb_to, + struct print_buf *pb_from); + +#define FORMAT(PTR, LEN, FMT) \ +{\ + va_list args;\ + va_start(args, FMT);\ + LEN = vsprintf(PTR, FMT, args);\ + va_end(args);\ + *(PTR + LEN) = '\0';\ +} + +/** + * tipc_printbuf_init - initialize print buffer to empty + * @pb: pointer to print buffer structure + * @raw: pointer to character array used by print buffer + * @size: size of character array + * + * Note: If the character array is too small (or absent), the print buffer + * becomes a null device that discards anything written to it. + */ +void tipc_printbuf_init(struct print_buf *pb, char *raw, u32 size) +{ + pb->buf = raw; + pb->crs = raw; + pb->size = size; + pb->echo = 0; + + if (size < TIPC_PB_MIN_SIZE) { + pb->buf = NULL; + } else if (raw) { + pb->buf[0] = 0; + pb->buf[size - 1] = ~0; + } +} + +/** + * tipc_printbuf_reset - reinitialize print buffer to empty state + * @pb: pointer to print buffer structure + */ +static void tipc_printbuf_reset(struct print_buf *pb) +{ + if (pb->buf) { + pb->crs = pb->buf; + pb->buf[0] = 0; + pb->buf[pb->size - 1] = ~0; + } +} + +/** + * tipc_printbuf_empty - test if print buffer is in empty state + * @pb: pointer to print buffer structure + * + * Returns non-zero if print buffer is empty. + */ +static int tipc_printbuf_empty(struct print_buf *pb) +{ + return !pb->buf || (pb->crs == pb->buf); +} + +/** + * tipc_printbuf_validate - check for print buffer overflow + * @pb: pointer to print buffer structure + * + * Verifies that a print buffer has captured all data written to it. + * If data has been lost, linearize buffer and prepend an error message + * + * Returns length of print buffer data string (including trailing NUL) + */ +int tipc_printbuf_validate(struct print_buf *pb) +{ + char *err = "\n\n*** PRINT BUFFER OVERFLOW ***\n\n"; + char *cp_buf; + struct print_buf cb; + + if (!pb->buf) + return 0; + + if (pb->buf[pb->size - 1] == 0) { + cp_buf = kmalloc(pb->size, GFP_ATOMIC); + if (cp_buf) { + tipc_printbuf_init(&cb, cp_buf, pb->size); + tipc_printbuf_move(&cb, pb); + tipc_printbuf_move(pb, &cb); + kfree(cp_buf); + memcpy(pb->buf, err, strlen(err)); + } else { + tipc_printbuf_reset(pb); + tipc_printf(pb, err); + } + } + return pb->crs - pb->buf + 1; +} + +/** + * tipc_printbuf_move - move print buffer contents to another print buffer + * @pb_to: pointer to destination print buffer structure + * @pb_from: pointer to source print buffer structure + * + * Current contents of destination print buffer (if any) are discarded. + * Source print buffer becomes empty if a successful move occurs. + */ +static void tipc_printbuf_move(struct print_buf *pb_to, + struct print_buf *pb_from) +{ + int len; + + /* Handle the cases where contents can't be moved */ + if (!pb_to->buf) + return; + + if (!pb_from->buf) { + tipc_printbuf_reset(pb_to); + return; + } + + if (pb_to->size < pb_from->size) { + strcpy(pb_to->buf, "*** PRINT BUFFER MOVE ERROR ***"); + pb_to->buf[pb_to->size - 1] = ~0; + pb_to->crs = strchr(pb_to->buf, 0); + return; + } + + /* Copy data from char after cursor to end (if used) */ + len = pb_from->buf + pb_from->size - pb_from->crs - 2; + if ((pb_from->buf[pb_from->size - 1] == 0) && (len > 0)) { + strcpy(pb_to->buf, pb_from->crs + 1); + pb_to->crs = pb_to->buf + len; + } else + pb_to->crs = pb_to->buf; + + /* Copy data from start to cursor (always) */ + len = pb_from->crs - pb_from->buf; + strcpy(pb_to->crs, pb_from->buf); + pb_to->crs += len; + + tipc_printbuf_reset(pb_from); +} /** - * tipc_snprintf - append formatted output to print buffer - * @buf: pointer to print buffer - * @len: buffer length + * tipc_printf - append formatted output to print buffer + * @pb: pointer to print buffer * @fmt: formatted info to be printed */ -int tipc_snprintf(char *buf, int len, const char *fmt, ...) +void tipc_printf(struct print_buf *pb, const char *fmt, ...) +{ + int chars_to_add; + int chars_left; + char save_char; + + spin_lock_bh(&print_lock); + + FORMAT(print_string, chars_to_add, fmt); + if (chars_to_add >= TIPC_PB_MAX_STR) + strcpy(print_string, "*** PRINT BUFFER STRING TOO LONG ***"); + + if (pb->buf) { + chars_left = pb->buf + pb->size - pb->crs - 1; + if (chars_to_add <= chars_left) { + strcpy(pb->crs, print_string); + pb->crs += chars_to_add; + } else if (chars_to_add >= (pb->size - 1)) { + strcpy(pb->buf, print_string + chars_to_add + 1 + - pb->size); + pb->crs = pb->buf + pb->size - 1; + } else { + strcpy(pb->buf, print_string + chars_left); + save_char = print_string[chars_left]; + print_string[chars_left] = 0; + strcpy(pb->crs, print_string); + print_string[chars_left] = save_char; + pb->crs = pb->buf + chars_to_add - chars_left; + } + } + + if (pb->echo) + printk("%s", print_string); + + spin_unlock_bh(&print_lock); +} + +/** + * tipc_log_resize - change the size of the TIPC log buffer + * @log_size: print buffer size to use + */ +int tipc_log_resize(int log_size) +{ + int res = 0; + + spin_lock_bh(&print_lock); + kfree(TIPC_LOG->buf); + TIPC_LOG->buf = NULL; + if (log_size) { + if (log_size < TIPC_PB_MIN_SIZE) + log_size = TIPC_PB_MIN_SIZE; + res = TIPC_LOG->echo; + tipc_printbuf_init(TIPC_LOG, kmalloc(log_size, GFP_ATOMIC), + log_size); + TIPC_LOG->echo = res; + res = !TIPC_LOG->buf; + } + spin_unlock_bh(&print_lock); + + return res; +} + +/** + * tipc_log_resize_cmd - reconfigure size of TIPC log buffer + */ +struct sk_buff *tipc_log_resize_cmd(const void *req_tlv_area, int req_tlv_space) +{ + u32 value; + + if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED)) + return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); + + value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area)); + if (value > 32768) + return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE + " (log size must be 0-32768)"); + if (tipc_log_resize(value)) + return tipc_cfg_reply_error_string( + "unable to create specified log (log size is now 0)"); + return tipc_cfg_reply_none(); +} + +/** + * tipc_log_dump - capture TIPC log buffer contents in configuration message + */ +struct sk_buff *tipc_log_dump(void) { - int i; - va_list args; + struct sk_buff *reply; + + spin_lock_bh(&print_lock); + if (!TIPC_LOG->buf) { + spin_unlock_bh(&print_lock); + reply = tipc_cfg_reply_ultra_string("log not activated\n"); + } else if (tipc_printbuf_empty(TIPC_LOG)) { + spin_unlock_bh(&print_lock); + reply = tipc_cfg_reply_ultra_string("log is empty\n"); + } else { + struct tlv_desc *rep_tlv; + struct print_buf pb; + int str_len; - va_start(args, fmt); - i = vscnprintf(buf, len, fmt, args); - va_end(args); - return i; + str_len = min(TIPC_LOG->size, 32768u); + spin_unlock_bh(&print_lock); + reply = tipc_cfg_reply_alloc(TLV_SPACE(str_len)); + if (reply) { + rep_tlv = (struct tlv_desc *)reply->data; + tipc_printbuf_init(&pb, TLV_DATA(rep_tlv), str_len); + spin_lock_bh(&print_lock); + tipc_printbuf_move(&pb, TIPC_LOG); + spin_unlock_bh(&print_lock); + str_len = strlen(TLV_DATA(rep_tlv)) + 1; + skb_put(reply, TLV_SPACE(str_len)); + TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len); + } + } + return reply; } diff --git a/trunk/net/tipc/log.h b/trunk/net/tipc/log.h new file mode 100644 index 000000000000..d1f5eb967fd8 --- /dev/null +++ b/trunk/net/tipc/log.h @@ -0,0 +1,66 @@ +/* + * net/tipc/log.h: Include file for TIPC print buffer routines + * + * Copyright (c) 1997-2006, Ericsson AB + * Copyright (c) 2005-2007, Wind River Systems + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the names of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _TIPC_LOG_H +#define _TIPC_LOG_H + +/** + * struct print_buf - TIPC print buffer structure + * @buf: pointer to character array containing print buffer contents + * @size: size of character array + * @crs: pointer to first unused space in character array (i.e. final NUL) + * @echo: echo output to system console if non-zero + */ +struct print_buf { + char *buf; + u32 size; + char *crs; + int echo; +}; + +#define TIPC_PB_MIN_SIZE 64 /* minimum size for a print buffer's array */ +#define TIPC_PB_MAX_STR 512 /* max printable string (with trailing NUL) */ + +void tipc_printbuf_init(struct print_buf *pb, char *buf, u32 size); +int tipc_printbuf_validate(struct print_buf *pb); + +int tipc_log_resize(int log_size); + +struct sk_buff *tipc_log_resize_cmd(const void *req_tlv_area, + int req_tlv_space); +struct sk_buff *tipc_log_dump(void); + +#endif diff --git a/trunk/net/tipc/msg.c b/trunk/net/tipc/msg.c index f2db8a87d9c5..deea0d232dca 100644 --- a/trunk/net/tipc/msg.c +++ b/trunk/net/tipc/msg.c @@ -109,3 +109,245 @@ int tipc_msg_build(struct tipc_msg *hdr, struct iovec const *msg_sect, *buf = NULL; return -EFAULT; } + +#ifdef CONFIG_TIPC_DEBUG +void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str) +{ + u32 usr = msg_user(msg); + tipc_printf(buf, KERN_DEBUG); + tipc_printf(buf, str); + + switch (usr) { + case MSG_BUNDLER: + tipc_printf(buf, "BNDL::"); + tipc_printf(buf, "MSGS(%u):", msg_msgcnt(msg)); + break; + case BCAST_PROTOCOL: + tipc_printf(buf, "BCASTP::"); + break; + case MSG_FRAGMENTER: + tipc_printf(buf, "FRAGM::"); + switch (msg_type(msg)) { + case FIRST_FRAGMENT: + tipc_printf(buf, "FIRST:"); + break; + case FRAGMENT: + tipc_printf(buf, "BODY:"); + break; + case LAST_FRAGMENT: + tipc_printf(buf, "LAST:"); + break; + default: + tipc_printf(buf, "UNKNOWN:%x", msg_type(msg)); + + } + tipc_printf(buf, "NO(%u/%u):", msg_long_msgno(msg), + msg_fragm_no(msg)); + break; + case TIPC_LOW_IMPORTANCE: + case TIPC_MEDIUM_IMPORTANCE: + case TIPC_HIGH_IMPORTANCE: + case TIPC_CRITICAL_IMPORTANCE: + tipc_printf(buf, "DAT%u:", msg_user(msg)); + if (msg_short(msg)) { + tipc_printf(buf, "CON:"); + break; + } + switch (msg_type(msg)) { + case TIPC_CONN_MSG: + tipc_printf(buf, "CON:"); + break; + case TIPC_MCAST_MSG: + tipc_printf(buf, "MCST:"); + break; + case TIPC_NAMED_MSG: + tipc_printf(buf, "NAM:"); + break; + case TIPC_DIRECT_MSG: + tipc_printf(buf, "DIR:"); + break; + default: + tipc_printf(buf, "UNKNOWN TYPE %u", msg_type(msg)); + } + if (msg_reroute_cnt(msg)) + tipc_printf(buf, "REROUTED(%u):", + msg_reroute_cnt(msg)); + break; + case NAME_DISTRIBUTOR: + tipc_printf(buf, "NMD::"); + switch (msg_type(msg)) { + case PUBLICATION: + tipc_printf(buf, "PUBL(%u):", (msg_size(msg) - msg_hdr_sz(msg)) / 20); /* Items */ + break; + case WITHDRAWAL: + tipc_printf(buf, "WDRW:"); + break; + default: + tipc_printf(buf, "UNKNOWN:%x", msg_type(msg)); + } + if (msg_reroute_cnt(msg)) + tipc_printf(buf, "REROUTED(%u):", + msg_reroute_cnt(msg)); + break; + case CONN_MANAGER: + tipc_printf(buf, "CONN_MNG:"); + switch (msg_type(msg)) { + case CONN_PROBE: + tipc_printf(buf, "PROBE:"); + break; + case CONN_PROBE_REPLY: + tipc_printf(buf, "PROBE_REPLY:"); + break; + case CONN_ACK: + tipc_printf(buf, "CONN_ACK:"); + tipc_printf(buf, "ACK(%u):", msg_msgcnt(msg)); + break; + default: + tipc_printf(buf, "UNKNOWN TYPE:%x", msg_type(msg)); + } + if (msg_reroute_cnt(msg)) + tipc_printf(buf, "REROUTED(%u):", msg_reroute_cnt(msg)); + break; + case LINK_PROTOCOL: + switch (msg_type(msg)) { + case STATE_MSG: + tipc_printf(buf, "STATE:"); + tipc_printf(buf, "%s:", msg_probe(msg) ? "PRB" : ""); + tipc_printf(buf, "NXS(%u):", msg_next_sent(msg)); + tipc_printf(buf, "GAP(%u):", msg_seq_gap(msg)); + tipc_printf(buf, "LSTBC(%u):", msg_last_bcast(msg)); + break; + case RESET_MSG: + tipc_printf(buf, "RESET:"); + if (msg_size(msg) != msg_hdr_sz(msg)) + tipc_printf(buf, "BEAR:%s:", msg_data(msg)); + break; + case ACTIVATE_MSG: + tipc_printf(buf, "ACTIVATE:"); + break; + default: + tipc_printf(buf, "UNKNOWN TYPE:%x", msg_type(msg)); + } + tipc_printf(buf, "PLANE(%c):", msg_net_plane(msg)); + tipc_printf(buf, "SESS(%u):", msg_session(msg)); + break; + case CHANGEOVER_PROTOCOL: + tipc_printf(buf, "TUNL:"); + switch (msg_type(msg)) { + case DUPLICATE_MSG: + tipc_printf(buf, "DUPL:"); + break; + case ORIGINAL_MSG: + tipc_printf(buf, "ORIG:"); + tipc_printf(buf, "EXP(%u)", msg_msgcnt(msg)); + break; + default: + tipc_printf(buf, "UNKNOWN TYPE:%x", msg_type(msg)); + } + break; + case LINK_CONFIG: + tipc_printf(buf, "CFG:"); + switch (msg_type(msg)) { + case DSC_REQ_MSG: + tipc_printf(buf, "DSC_REQ:"); + break; + case DSC_RESP_MSG: + tipc_printf(buf, "DSC_RESP:"); + break; + default: + tipc_printf(buf, "UNKNOWN TYPE:%x:", msg_type(msg)); + break; + } + break; + default: + tipc_printf(buf, "UNKNOWN USER:"); + } + + switch (usr) { + case CONN_MANAGER: + case TIPC_LOW_IMPORTANCE: + case TIPC_MEDIUM_IMPORTANCE: + case TIPC_HIGH_IMPORTANCE: + case TIPC_CRITICAL_IMPORTANCE: + switch (msg_errcode(msg)) { + case TIPC_OK: + break; + case TIPC_ERR_NO_NAME: + tipc_printf(buf, "NO_NAME:"); + break; + case TIPC_ERR_NO_PORT: + tipc_printf(buf, "NO_PORT:"); + break; + case TIPC_ERR_NO_NODE: + tipc_printf(buf, "NO_PROC:"); + break; + case TIPC_ERR_OVERLOAD: + tipc_printf(buf, "OVERLOAD:"); + break; + case TIPC_CONN_SHUTDOWN: + tipc_printf(buf, "SHUTDOWN:"); + break; + default: + tipc_printf(buf, "UNKNOWN ERROR(%x):", + msg_errcode(msg)); + } + default: + break; + } + + tipc_printf(buf, "HZ(%u):", msg_hdr_sz(msg)); + tipc_printf(buf, "SZ(%u):", msg_size(msg)); + tipc_printf(buf, "SQNO(%u):", msg_seqno(msg)); + + if (msg_non_seq(msg)) + tipc_printf(buf, "NOSEQ:"); + else + tipc_printf(buf, "ACK(%u):", msg_ack(msg)); + tipc_printf(buf, "BACK(%u):", msg_bcast_ack(msg)); + tipc_printf(buf, "PRND(%x)", msg_prevnode(msg)); + + if (msg_isdata(msg)) { + if (msg_named(msg)) { + tipc_printf(buf, "NTYP(%u):", msg_nametype(msg)); + tipc_printf(buf, "NINST(%u)", msg_nameinst(msg)); + } + } + + if ((usr != LINK_PROTOCOL) && (usr != LINK_CONFIG) && + (usr != MSG_BUNDLER)) { + if (!msg_short(msg)) { + tipc_printf(buf, ":ORIG(%x:%u):", + msg_orignode(msg), msg_origport(msg)); + tipc_printf(buf, ":DEST(%x:%u):", + msg_destnode(msg), msg_destport(msg)); + } else { + tipc_printf(buf, ":OPRT(%u):", msg_origport(msg)); + tipc_printf(buf, ":DPRT(%u):", msg_destport(msg)); + } + } + if (msg_user(msg) == NAME_DISTRIBUTOR) { + tipc_printf(buf, ":ONOD(%x):", msg_orignode(msg)); + tipc_printf(buf, ":DNOD(%x):", msg_destnode(msg)); + } + + if (msg_user(msg) == LINK_CONFIG) { + struct tipc_media_addr orig; + + tipc_printf(buf, ":DDOM(%x):", msg_dest_domain(msg)); + tipc_printf(buf, ":NETID(%u):", msg_bc_netid(msg)); + memcpy(orig.value, msg_media_addr(msg), sizeof(orig.value)); + orig.media_id = 0; + orig.broadcast = 0; + tipc_media_addr_printf(buf, &orig); + } + if (msg_user(msg) == BCAST_PROTOCOL) { + tipc_printf(buf, "BCNACK:AFTER(%u):", msg_bcgap_after(msg)); + tipc_printf(buf, "TO(%u):", msg_bcgap_to(msg)); + } + tipc_printf(buf, "\n"); + if ((usr == CHANGEOVER_PROTOCOL) && (msg_msgcnt(msg))) + tipc_msg_dbg(buf, msg_get_wrapped(msg), " /"); + if ((usr == MSG_FRAGMENTER) && (msg_type(msg) == FIRST_FRAGMENT)) + tipc_msg_dbg(buf, msg_get_wrapped(msg), " /"); +} +#endif diff --git a/trunk/net/tipc/name_distr.c b/trunk/net/tipc/name_distr.c index 55d3928dfd67..158318e67b08 100644 --- a/trunk/net/tipc/name_distr.c +++ b/trunk/net/tipc/name_distr.c @@ -161,7 +161,7 @@ void tipc_named_publish(struct publication *publ) buf = named_prepare_buf(PUBLICATION, ITEM_SIZE, 0); if (!buf) { - pr_warn("Publication distribution failure\n"); + warn("Publication distribution failure\n"); return; } @@ -186,7 +186,7 @@ void tipc_named_withdraw(struct publication *publ) buf = named_prepare_buf(WITHDRAWAL, ITEM_SIZE, 0); if (!buf) { - pr_warn("Withdrawal distribution failure\n"); + warn("Withdrawal distribution failure\n"); return; } @@ -213,7 +213,7 @@ static void named_distribute(struct list_head *message_list, u32 node, rest -= left; buf = named_prepare_buf(PUBLICATION, left, node); if (!buf) { - pr_warn("Bulk publication failure\n"); + warn("Bulk publication failure\n"); return; } item = (struct distr_item *)msg_data(buf_msg(buf)); @@ -283,10 +283,9 @@ static void named_purge_publ(struct publication *publ) write_unlock_bh(&tipc_nametbl_lock); if (p != publ) { - pr_err("Unable to remove publication from failed node\n" - " (type=%u, lower=%u, node=0x%x, ref=%u, key=%u)\n", - publ->type, publ->lower, publ->node, publ->ref, - publ->key); + err("Unable to remove publication from failed node\n" + "(type=%u, lower=%u, node=0x%x, ref=%u, key=%u)\n", + publ->type, publ->lower, publ->node, publ->ref, publ->key); } kfree(p); @@ -330,14 +329,14 @@ void tipc_named_recv(struct sk_buff *buf) tipc_nodesub_unsubscribe(&publ->subscr); kfree(publ); } else { - pr_err("Unable to remove publication by node 0x%x\n" - " (type=%u, lower=%u, ref=%u, key=%u)\n", - msg_orignode(msg), ntohl(item->type), - ntohl(item->lower), ntohl(item->ref), - ntohl(item->key)); + err("Unable to remove publication by node 0x%x\n" + "(type=%u, lower=%u, ref=%u, key=%u)\n", + msg_orignode(msg), + ntohl(item->type), ntohl(item->lower), + ntohl(item->ref), ntohl(item->key)); } } else { - pr_warn("Unrecognized name table message received\n"); + warn("Unrecognized name table message received\n"); } item++; } diff --git a/trunk/net/tipc/name_table.c b/trunk/net/tipc/name_table.c index 360c478b0b53..13fb9d559ea5 100644 --- a/trunk/net/tipc/name_table.c +++ b/trunk/net/tipc/name_table.c @@ -126,7 +126,7 @@ static struct publication *publ_create(u32 type, u32 lower, u32 upper, { struct publication *publ = kzalloc(sizeof(*publ), GFP_ATOMIC); if (publ == NULL) { - pr_warn("Publication creation failure, no memory\n"); + warn("Publication creation failure, no memory\n"); return NULL; } @@ -163,7 +163,7 @@ static struct name_seq *tipc_nameseq_create(u32 type, struct hlist_head *seq_hea struct sub_seq *sseq = tipc_subseq_alloc(1); if (!nseq || !sseq) { - pr_warn("Name sequence creation failed, no memory\n"); + warn("Name sequence creation failed, no memory\n"); kfree(nseq); kfree(sseq); return NULL; @@ -263,8 +263,8 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq, /* Lower end overlaps existing entry => need an exact match */ if ((sseq->lower != lower) || (sseq->upper != upper)) { - pr_warn("Cannot publish {%u,%u,%u}, overlap error\n", - type, lower, upper); + warn("Cannot publish {%u,%u,%u}, overlap error\n", + type, lower, upper); return NULL; } @@ -286,8 +286,8 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq, /* Fail if upper end overlaps into an existing entry */ if ((inspos < nseq->first_free) && (upper >= nseq->sseqs[inspos].lower)) { - pr_warn("Cannot publish {%u,%u,%u}, overlap error\n", - type, lower, upper); + warn("Cannot publish {%u,%u,%u}, overlap error\n", + type, lower, upper); return NULL; } @@ -296,8 +296,8 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq, struct sub_seq *sseqs = tipc_subseq_alloc(nseq->alloc * 2); if (!sseqs) { - pr_warn("Cannot publish {%u,%u,%u}, no memory\n", - type, lower, upper); + warn("Cannot publish {%u,%u,%u}, no memory\n", + type, lower, upper); return NULL; } memcpy(sseqs, nseq->sseqs, @@ -309,8 +309,8 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq, info = kzalloc(sizeof(*info), GFP_ATOMIC); if (!info) { - pr_warn("Cannot publish {%u,%u,%u}, no memory\n", - type, lower, upper); + warn("Cannot publish {%u,%u,%u}, no memory\n", + type, lower, upper); return NULL; } @@ -492,8 +492,8 @@ struct publication *tipc_nametbl_insert_publ(u32 type, u32 lower, u32 upper, if ((scope < TIPC_ZONE_SCOPE) || (scope > TIPC_NODE_SCOPE) || (lower > upper)) { - pr_debug("Failed to publish illegal {%u,%u,%u} with scope %u\n", - type, lower, upper, scope); + dbg("Failed to publish illegal {%u,%u,%u} with scope %u\n", + type, lower, upper, scope); return NULL; } @@ -668,8 +668,8 @@ struct publication *tipc_nametbl_publish(u32 type, u32 lower, u32 upper, struct publication *publ; if (table.local_publ_count >= tipc_max_publications) { - pr_warn("Publication failed, local publication limit reached (%u)\n", - tipc_max_publications); + warn("Publication failed, local publication limit reached (%u)\n", + tipc_max_publications); return NULL; } @@ -702,9 +702,9 @@ int tipc_nametbl_withdraw(u32 type, u32 lower, u32 ref, u32 key) return 1; } write_unlock_bh(&tipc_nametbl_lock); - pr_err("Unable to remove local publication\n" - "(type=%u, lower=%u, ref=%u, key=%u)\n", - type, lower, ref, key); + err("Unable to remove local publication\n" + "(type=%u, lower=%u, ref=%u, key=%u)\n", + type, lower, ref, key); return 0; } @@ -725,8 +725,8 @@ void tipc_nametbl_subscribe(struct tipc_subscription *s) tipc_nameseq_subscribe(seq, s); spin_unlock_bh(&seq->lock); } else { - pr_warn("Failed to create subscription for {%u,%u,%u}\n", - s->seq.type, s->seq.lower, s->seq.upper); + warn("Failed to create subscription for {%u,%u,%u}\n", + s->seq.type, s->seq.lower, s->seq.upper); } write_unlock_bh(&tipc_nametbl_lock); } @@ -753,20 +753,19 @@ void tipc_nametbl_unsubscribe(struct tipc_subscription *s) /** * subseq_list - print specified sub-sequence contents into the given buffer */ -static int subseq_list(struct sub_seq *sseq, char *buf, int len, u32 depth, +static void subseq_list(struct sub_seq *sseq, struct print_buf *buf, u32 depth, u32 index) { char portIdStr[27]; const char *scope_str[] = {"", " zone", " cluster", " node"}; struct publication *publ; struct name_info *info; - int ret; - ret = tipc_snprintf(buf, len, "%-10u %-10u ", sseq->lower, sseq->upper); + tipc_printf(buf, "%-10u %-10u ", sseq->lower, sseq->upper); if (depth == 2) { - ret += tipc_snprintf(buf - ret, len + ret, "\n"); - return ret; + tipc_printf(buf, "\n"); + return; } info = sseq->info; @@ -775,58 +774,52 @@ static int subseq_list(struct sub_seq *sseq, char *buf, int len, u32 depth, sprintf(portIdStr, "<%u.%u.%u:%u>", tipc_zone(publ->node), tipc_cluster(publ->node), tipc_node(publ->node), publ->ref); - ret += tipc_snprintf(buf + ret, len - ret, "%-26s ", portIdStr); + tipc_printf(buf, "%-26s ", portIdStr); if (depth > 3) { - ret += tipc_snprintf(buf + ret, len - ret, "%-10u %s", - publ->key, scope_str[publ->scope]); + tipc_printf(buf, "%-10u %s", publ->key, + scope_str[publ->scope]); } if (!list_is_last(&publ->zone_list, &info->zone_list)) - ret += tipc_snprintf(buf + ret, len - ret, - "\n%33s", " "); + tipc_printf(buf, "\n%33s", " "); }; - ret += tipc_snprintf(buf + ret, len - ret, "\n"); - return ret; + tipc_printf(buf, "\n"); } /** * nameseq_list - print specified name sequence contents into the given buffer */ -static int nameseq_list(struct name_seq *seq, char *buf, int len, u32 depth, +static void nameseq_list(struct name_seq *seq, struct print_buf *buf, u32 depth, u32 type, u32 lowbound, u32 upbound, u32 index) { struct sub_seq *sseq; char typearea[11]; - int ret = 0; if (seq->first_free == 0) - return 0; + return; sprintf(typearea, "%-10u", seq->type); if (depth == 1) { - ret += tipc_snprintf(buf, len, "%s\n", typearea); - return ret; + tipc_printf(buf, "%s\n", typearea); + return; } for (sseq = seq->sseqs; sseq != &seq->sseqs[seq->first_free]; sseq++) { if ((lowbound <= sseq->upper) && (upbound >= sseq->lower)) { - ret += tipc_snprintf(buf + ret, len - ret, "%s ", - typearea); + tipc_printf(buf, "%s ", typearea); spin_lock_bh(&seq->lock); - ret += subseq_list(sseq, buf + ret, len - ret, - depth, index); + subseq_list(sseq, buf, depth, index); spin_unlock_bh(&seq->lock); sprintf(typearea, "%10s", " "); } } - return ret; } /** * nametbl_header - print name table header into the given buffer */ -static int nametbl_header(char *buf, int len, u32 depth) +static void nametbl_header(struct print_buf *buf, u32 depth) { const char *header[] = { "Type ", @@ -836,27 +829,24 @@ static int nametbl_header(char *buf, int len, u32 depth) }; int i; - int ret = 0; if (depth > 4) depth = 4; for (i = 0; i < depth; i++) - ret += tipc_snprintf(buf + ret, len - ret, header[i]); - ret += tipc_snprintf(buf + ret, len - ret, "\n"); - return ret; + tipc_printf(buf, header[i]); + tipc_printf(buf, "\n"); } /** * nametbl_list - print specified name table contents into the given buffer */ -static int nametbl_list(char *buf, int len, u32 depth_info, +static void nametbl_list(struct print_buf *buf, u32 depth_info, u32 type, u32 lowbound, u32 upbound) { struct hlist_head *seq_head; struct hlist_node *seq_node; struct name_seq *seq; int all_types; - int ret = 0; u32 depth; u32 i; @@ -864,69 +854,65 @@ static int nametbl_list(char *buf, int len, u32 depth_info, depth = (depth_info & ~TIPC_NTQ_ALLTYPES); if (depth == 0) - return 0; + return; if (all_types) { /* display all entries in name table to specified depth */ - ret += nametbl_header(buf, len, depth); + nametbl_header(buf, depth); lowbound = 0; upbound = ~0; for (i = 0; i < tipc_nametbl_size; i++) { seq_head = &table.types[i]; hlist_for_each_entry(seq, seq_node, seq_head, ns_list) { - ret += nameseq_list(seq, buf + ret, len - ret, - depth, seq->type, - lowbound, upbound, i); + nameseq_list(seq, buf, depth, seq->type, + lowbound, upbound, i); } } } else { /* display only the sequence that matches the specified type */ if (upbound < lowbound) { - ret += tipc_snprintf(buf + ret, len - ret, - "invalid name sequence specified\n"); - return ret; + tipc_printf(buf, "invalid name sequence specified\n"); + return; } - ret += nametbl_header(buf + ret, len - ret, depth); + nametbl_header(buf, depth); i = hash(type); seq_head = &table.types[i]; hlist_for_each_entry(seq, seq_node, seq_head, ns_list) { if (seq->type == type) { - ret += nameseq_list(seq, buf + ret, len - ret, - depth, type, - lowbound, upbound, i); + nameseq_list(seq, buf, depth, type, + lowbound, upbound, i); break; } } } - return ret; } +#define MAX_NAME_TBL_QUERY 32768 + struct sk_buff *tipc_nametbl_get(const void *req_tlv_area, int req_tlv_space) { struct sk_buff *buf; struct tipc_name_table_query *argv; struct tlv_desc *rep_tlv; - char *pb; - int pb_len; + struct print_buf b; int str_len; if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NAME_TBL_QUERY)) return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); - buf = tipc_cfg_reply_alloc(TLV_SPACE(ULTRA_STRING_MAX_LEN)); + buf = tipc_cfg_reply_alloc(TLV_SPACE(MAX_NAME_TBL_QUERY)); if (!buf) return NULL; rep_tlv = (struct tlv_desc *)buf->data; - pb = TLV_DATA(rep_tlv); - pb_len = ULTRA_STRING_MAX_LEN; + tipc_printbuf_init(&b, TLV_DATA(rep_tlv), MAX_NAME_TBL_QUERY); argv = (struct tipc_name_table_query *)TLV_DATA(req_tlv_area); read_lock_bh(&tipc_nametbl_lock); - str_len = nametbl_list(pb, pb_len, ntohl(argv->depth), - ntohl(argv->type), - ntohl(argv->lowbound), ntohl(argv->upbound)); + nametbl_list(&b, ntohl(argv->depth), ntohl(argv->type), + ntohl(argv->lowbound), ntohl(argv->upbound)); read_unlock_bh(&tipc_nametbl_lock); - str_len += 1; /* for "\0" */ + str_len = tipc_printbuf_validate(&b); + skb_put(buf, TLV_SPACE(str_len)); TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len); @@ -954,10 +940,8 @@ void tipc_nametbl_stop(void) /* Verify name table is empty, then release it */ write_lock_bh(&tipc_nametbl_lock); for (i = 0; i < tipc_nametbl_size; i++) { - if (hlist_empty(&table.types[i])) - continue; - pr_err("nametbl_stop(): orphaned hash chain detected\n"); - break; + if (!hlist_empty(&table.types[i])) + err("tipc_nametbl_stop(): hash chain %u is non-null\n", i); } kfree(table.types); table.types = NULL; diff --git a/trunk/net/tipc/net.c b/trunk/net/tipc/net.c index 5b5cea259caf..7c236c89cf5e 100644 --- a/trunk/net/tipc/net.c +++ b/trunk/net/tipc/net.c @@ -184,9 +184,9 @@ int tipc_net_start(u32 addr) tipc_cfg_reinit(); - pr_info("Started in network mode\n"); - pr_info("Own node address %s, network identity %u\n", - tipc_addr_string_fill(addr_string, tipc_own_addr), tipc_net_id); + info("Started in network mode\n"); + info("Own node address %s, network identity %u\n", + tipc_addr_string_fill(addr_string, tipc_own_addr), tipc_net_id); return 0; } @@ -202,5 +202,5 @@ void tipc_net_stop(void) list_for_each_entry_safe(node, t_node, &tipc_node_list, list) tipc_node_delete(node); write_unlock_bh(&tipc_net_lock); - pr_info("Left network mode\n"); + info("Left network mode\n"); } diff --git a/trunk/net/tipc/netlink.c b/trunk/net/tipc/netlink.c index 47a839df27dc..7bda8e3d1398 100644 --- a/trunk/net/tipc/netlink.c +++ b/trunk/net/tipc/netlink.c @@ -90,7 +90,7 @@ int tipc_netlink_start(void) res = genl_register_family_with_ops(&tipc_genl_family, &tipc_genl_ops, 1); if (res) { - pr_err("Failed to register netlink interface\n"); + err("Failed to register netlink interface\n"); return res; } diff --git a/trunk/net/tipc/node.c b/trunk/net/tipc/node.c index d21db204e25a..d4fd341e6e0d 100644 --- a/trunk/net/tipc/node.c +++ b/trunk/net/tipc/node.c @@ -105,7 +105,7 @@ struct tipc_node *tipc_node_create(u32 addr) n_ptr = kzalloc(sizeof(*n_ptr), GFP_ATOMIC); if (!n_ptr) { spin_unlock_bh(&node_create_lock); - pr_warn("Node creation failed, no memory\n"); + warn("Node creation failed, no memory\n"); return NULL; } @@ -151,8 +151,8 @@ void tipc_node_link_up(struct tipc_node *n_ptr, struct tipc_link *l_ptr) n_ptr->working_links++; - pr_info("Established link <%s> on network plane %c\n", - l_ptr->name, l_ptr->b_ptr->net_plane); + info("Established link <%s> on network plane %c\n", + l_ptr->name, l_ptr->b_ptr->net_plane); if (!active[0]) { active[0] = active[1] = l_ptr; @@ -160,7 +160,7 @@ void tipc_node_link_up(struct tipc_node *n_ptr, struct tipc_link *l_ptr) return; } if (l_ptr->priority < active[0]->priority) { - pr_info("New link <%s> becomes standby\n", l_ptr->name); + info("New link <%s> becomes standby\n", l_ptr->name); return; } tipc_link_send_duplicate(active[0], l_ptr); @@ -168,9 +168,9 @@ void tipc_node_link_up(struct tipc_node *n_ptr, struct tipc_link *l_ptr) active[0] = l_ptr; return; } - pr_info("Old link <%s> becomes standby\n", active[0]->name); + info("Old link <%s> becomes standby\n", active[0]->name); if (active[1] != active[0]) - pr_info("Old link <%s> becomes standby\n", active[1]->name); + info("Old link <%s> becomes standby\n", active[1]->name); active[0] = active[1] = l_ptr; } @@ -211,11 +211,11 @@ void tipc_node_link_down(struct tipc_node *n_ptr, struct tipc_link *l_ptr) n_ptr->working_links--; if (!tipc_link_is_active(l_ptr)) { - pr_info("Lost standby link <%s> on network plane %c\n", - l_ptr->name, l_ptr->b_ptr->net_plane); + info("Lost standby link <%s> on network plane %c\n", + l_ptr->name, l_ptr->b_ptr->net_plane); return; } - pr_info("Lost link <%s> on network plane %c\n", + info("Lost link <%s> on network plane %c\n", l_ptr->name, l_ptr->b_ptr->net_plane); active = &n_ptr->active_links[0]; @@ -290,8 +290,8 @@ static void node_lost_contact(struct tipc_node *n_ptr) char addr_string[16]; u32 i; - pr_info("Lost contact with %s\n", - tipc_addr_string_fill(addr_string, n_ptr->addr)); + info("Lost contact with %s\n", + tipc_addr_string_fill(addr_string, n_ptr->addr)); /* Flush broadcast link info associated with lost node */ if (n_ptr->bclink.supported) { diff --git a/trunk/net/tipc/node_subscr.c b/trunk/net/tipc/node_subscr.c index 5e34b015da45..7a27344108fe 100644 --- a/trunk/net/tipc/node_subscr.c +++ b/trunk/net/tipc/node_subscr.c @@ -51,8 +51,7 @@ void tipc_nodesub_subscribe(struct tipc_node_subscr *node_sub, u32 addr, node_sub->node = tipc_node_find(addr); if (!node_sub->node) { - pr_warn("Node subscription rejected, unknown node 0x%x\n", - addr); + warn("Node subscription rejected, unknown node 0x%x\n", addr); return; } node_sub->handle_node_down = handle_down; diff --git a/trunk/net/tipc/port.c b/trunk/net/tipc/port.c index 07c42fba672b..70bf78bd5b75 100644 --- a/trunk/net/tipc/port.c +++ b/trunk/net/tipc/port.c @@ -191,7 +191,7 @@ void tipc_port_recv_mcast(struct sk_buff *buf, struct tipc_port_list *dp) struct sk_buff *b = skb_clone(buf, GFP_ATOMIC); if (b == NULL) { - pr_warn("Unable to deliver multicast message(s)\n"); + warn("Unable to deliver multicast message(s)\n"); goto exit; } if ((index == 0) && (cnt != 0)) @@ -221,12 +221,12 @@ struct tipc_port *tipc_createport_raw(void *usr_handle, p_ptr = kzalloc(sizeof(*p_ptr), GFP_ATOMIC); if (!p_ptr) { - pr_warn("Port creation failed, no memory\n"); + warn("Port creation failed, no memory\n"); return NULL; } ref = tipc_ref_acquire(p_ptr, &p_ptr->lock); if (!ref) { - pr_warn("Port creation failed, ref. table exhausted\n"); + warn("Port creation failed, reference table exhausted\n"); kfree(p_ptr); return NULL; } @@ -581,73 +581,67 @@ void tipc_port_recv_proto_msg(struct sk_buff *buf) kfree_skb(buf); } -static int port_print(struct tipc_port *p_ptr, char *buf, int len, int full_id) +static void port_print(struct tipc_port *p_ptr, struct print_buf *buf, int full_id) { struct publication *publ; - int ret; if (full_id) - ret = tipc_snprintf(buf, len, "<%u.%u.%u:%u>:", - tipc_zone(tipc_own_addr), - tipc_cluster(tipc_own_addr), - tipc_node(tipc_own_addr), p_ptr->ref); + tipc_printf(buf, "<%u.%u.%u:%u>:", + tipc_zone(tipc_own_addr), tipc_cluster(tipc_own_addr), + tipc_node(tipc_own_addr), p_ptr->ref); else - ret = tipc_snprintf(buf, len, "%-10u:", p_ptr->ref); + tipc_printf(buf, "%-10u:", p_ptr->ref); if (p_ptr->connected) { u32 dport = port_peerport(p_ptr); u32 destnode = port_peernode(p_ptr); - ret += tipc_snprintf(buf + ret, len - ret, - " connected to <%u.%u.%u:%u>", - tipc_zone(destnode), - tipc_cluster(destnode), - tipc_node(destnode), dport); + tipc_printf(buf, " connected to <%u.%u.%u:%u>", + tipc_zone(destnode), tipc_cluster(destnode), + tipc_node(destnode), dport); if (p_ptr->conn_type != 0) - ret += tipc_snprintf(buf + ret, len - ret, - " via {%u,%u}", p_ptr->conn_type, - p_ptr->conn_instance); + tipc_printf(buf, " via {%u,%u}", + p_ptr->conn_type, + p_ptr->conn_instance); } else if (p_ptr->published) { - ret += tipc_snprintf(buf + ret, len - ret, " bound to"); + tipc_printf(buf, " bound to"); list_for_each_entry(publ, &p_ptr->publications, pport_list) { if (publ->lower == publ->upper) - ret += tipc_snprintf(buf + ret, len - ret, - " {%u,%u}", publ->type, - publ->lower); + tipc_printf(buf, " {%u,%u}", publ->type, + publ->lower); else - ret += tipc_snprintf(buf + ret, len - ret, - " {%u,%u,%u}", publ->type, - publ->lower, publ->upper); + tipc_printf(buf, " {%u,%u,%u}", publ->type, + publ->lower, publ->upper); } } - ret += tipc_snprintf(buf + ret, len - ret, "\n"); - return ret; + tipc_printf(buf, "\n"); } +#define MAX_PORT_QUERY 32768 + struct sk_buff *tipc_port_get_ports(void) { struct sk_buff *buf; struct tlv_desc *rep_tlv; - char *pb; - int pb_len; + struct print_buf pb; struct tipc_port *p_ptr; - int str_len = 0; + int str_len; - buf = tipc_cfg_reply_alloc(TLV_SPACE(ULTRA_STRING_MAX_LEN)); + buf = tipc_cfg_reply_alloc(TLV_SPACE(MAX_PORT_QUERY)); if (!buf) return NULL; rep_tlv = (struct tlv_desc *)buf->data; - pb = TLV_DATA(rep_tlv); - pb_len = ULTRA_STRING_MAX_LEN; + tipc_printbuf_init(&pb, TLV_DATA(rep_tlv), MAX_PORT_QUERY); spin_lock_bh(&tipc_port_list_lock); list_for_each_entry(p_ptr, &ports, port_list) { spin_lock_bh(p_ptr->lock); - str_len += port_print(p_ptr, pb, pb_len, 0); + port_print(p_ptr, &pb, 0); spin_unlock_bh(p_ptr->lock); } spin_unlock_bh(&tipc_port_list_lock); - str_len += 1; /* for "\0" */ + str_len = tipc_printbuf_validate(&pb); + skb_put(buf, TLV_SPACE(str_len)); TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len); @@ -912,7 +906,7 @@ int tipc_createport(void *usr_handle, up_ptr = kmalloc(sizeof(*up_ptr), GFP_ATOMIC); if (!up_ptr) { - pr_warn("Port creation failed, no memory\n"); + warn("Port creation failed, no memory\n"); return -ENOMEM; } p_ptr = tipc_createport_raw(NULL, port_dispatcher, port_wakeup, diff --git a/trunk/net/tipc/ref.c b/trunk/net/tipc/ref.c index 2a2a938dc22c..5cada0e38e03 100644 --- a/trunk/net/tipc/ref.c +++ b/trunk/net/tipc/ref.c @@ -153,11 +153,11 @@ u32 tipc_ref_acquire(void *object, spinlock_t **lock) struct reference *entry = NULL; if (!object) { - pr_err("Attempt to acquire ref. to non-existent obj\n"); + err("Attempt to acquire reference to non-existent object\n"); return 0; } if (!tipc_ref_table.entries) { - pr_err("Ref. table not found in acquisition attempt\n"); + err("Reference table not found during acquisition attempt\n"); return 0; } @@ -211,7 +211,7 @@ void tipc_ref_discard(u32 ref) u32 index_mask; if (!tipc_ref_table.entries) { - pr_err("Ref. table not found during discard attempt\n"); + err("Reference table not found during discard attempt\n"); return; } @@ -222,11 +222,11 @@ void tipc_ref_discard(u32 ref) write_lock_bh(&ref_table_lock); if (!entry->object) { - pr_err("Attempt to discard ref. to non-existent obj\n"); + err("Attempt to discard reference to non-existent object\n"); goto exit; } if (entry->ref != ref) { - pr_err("Attempt to discard non-existent reference\n"); + err("Attempt to discard non-existent reference\n"); goto exit; } diff --git a/trunk/net/tipc/socket.c b/trunk/net/tipc/socket.c index 09dc5b97e079..1ebb49f3ddbe 100644 --- a/trunk/net/tipc/socket.c +++ b/trunk/net/tipc/socket.c @@ -34,12 +34,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include "core.h" -#include "port.h" - #include #include +#include "core.h" +#include "port.h" + #define SS_LISTENING -1 /* socket is listening */ #define SS_READY -2 /* socket is connectionless */ @@ -1787,13 +1787,13 @@ int tipc_socket_init(void) res = proto_register(&tipc_proto, 1); if (res) { - pr_err("Failed to register TIPC protocol type\n"); + err("Failed to register TIPC protocol type\n"); goto out; } res = sock_register(&tipc_family_ops); if (res) { - pr_err("Failed to register TIPC socket type\n"); + err("Failed to register TIPC socket type\n"); proto_unregister(&tipc_proto); goto out; } diff --git a/trunk/net/tipc/subscr.c b/trunk/net/tipc/subscr.c index 5ed5965eb0be..f976e9cd6a72 100644 --- a/trunk/net/tipc/subscr.c +++ b/trunk/net/tipc/subscr.c @@ -305,8 +305,8 @@ static struct tipc_subscription *subscr_subscribe(struct tipc_subscr *s, /* Refuse subscription if global limit exceeded */ if (atomic_read(&topsrv.subscription_count) >= tipc_max_subscriptions) { - pr_warn("Subscription rejected, limit reached (%u)\n", - tipc_max_subscriptions); + warn("Subscription rejected, subscription limit reached (%u)\n", + tipc_max_subscriptions); subscr_terminate(subscriber); return NULL; } @@ -314,7 +314,7 @@ static struct tipc_subscription *subscr_subscribe(struct tipc_subscr *s, /* Allocate subscription object */ sub = kmalloc(sizeof(*sub), GFP_ATOMIC); if (!sub) { - pr_warn("Subscription rejected, no memory\n"); + warn("Subscription rejected, no memory\n"); subscr_terminate(subscriber); return NULL; } @@ -328,7 +328,7 @@ static struct tipc_subscription *subscr_subscribe(struct tipc_subscr *s, if ((!(sub->filter & TIPC_SUB_PORTS) == !(sub->filter & TIPC_SUB_SERVICE)) || (sub->seq.lower > sub->seq.upper)) { - pr_warn("Subscription rejected, illegal request\n"); + warn("Subscription rejected, illegal request\n"); kfree(sub); subscr_terminate(subscriber); return NULL; @@ -440,7 +440,7 @@ static void subscr_named_msg_event(void *usr_handle, /* Create subscriber object */ subscriber = kzalloc(sizeof(struct tipc_subscriber), GFP_ATOMIC); if (subscriber == NULL) { - pr_warn("Subscriber rejected, no memory\n"); + warn("Subscriber rejected, no memory\n"); return; } INIT_LIST_HEAD(&subscriber->subscription_list); @@ -458,7 +458,7 @@ static void subscr_named_msg_event(void *usr_handle, NULL, &subscriber->port_ref); if (subscriber->port_ref == 0) { - pr_warn("Subscriber rejected, unable to create port\n"); + warn("Subscriber rejected, unable to create port\n"); kfree(subscriber); return; } @@ -517,7 +517,7 @@ int tipc_subscr_start(void) return 0; failed: - pr_err("Failed to create subscription service\n"); + err("Failed to create subscription service\n"); return res; } diff --git a/trunk/net/unix/diag.c b/trunk/net/unix/diag.c index 750b13408449..a74864eedfcd 100644 --- a/trunk/net/unix/diag.c +++ b/trunk/net/unix/diag.c @@ -177,7 +177,6 @@ static int unix_diag_dump(struct sk_buff *skb, struct netlink_callback *cb) { struct unix_diag_req *req; int num, s_num, slot, s_slot; - struct net *net = sock_net(skb->sk); req = nlmsg_data(cb->nlh); @@ -193,8 +192,6 @@ static int unix_diag_dump(struct sk_buff *skb, struct netlink_callback *cb) num = 0; sk_for_each(sk, node, &unix_socket_table[slot]) { - if (!net_eq(sock_net(sk), net)) - continue; if (num < s_num) goto next; if (!(req->udiag_states & (1 << sk->sk_state))) @@ -246,7 +243,6 @@ static int unix_diag_get_exact(struct sk_buff *in_skb, struct sock *sk; struct sk_buff *rep; unsigned int extra_len; - struct net *net = sock_net(in_skb->sk); if (req->udiag_ino == 0) goto out_nosk; @@ -277,7 +273,7 @@ static int unix_diag_get_exact(struct sk_buff *in_skb, goto again; } - err = netlink_unicast(net->diag_nlsk, rep, NETLINK_CB(in_skb).pid, + err = netlink_unicast(sock_diag_nlsk, rep, NETLINK_CB(in_skb).pid, MSG_DONTWAIT); if (err > 0) err = 0; @@ -291,7 +287,6 @@ static int unix_diag_get_exact(struct sk_buff *in_skb, static int unix_diag_handler_dump(struct sk_buff *skb, struct nlmsghdr *h) { int hdrlen = sizeof(struct unix_diag_req); - struct net *net = sock_net(skb->sk); if (nlmsg_len(h) < hdrlen) return -EINVAL; @@ -300,7 +295,7 @@ static int unix_diag_handler_dump(struct sk_buff *skb, struct nlmsghdr *h) struct netlink_dump_control c = { .dump = unix_diag_dump, }; - return netlink_dump_start(net->diag_nlsk, skb, h, &c); + return netlink_dump_start(sock_diag_nlsk, skb, h, &c); } else return unix_diag_get_exact(skb, h, nlmsg_data(h)); }