mirror of
https://github.com/torvalds/linux.git
synced 2024-11-25 13:41:51 +00:00
Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6: [TG3]: Update driver version and reldate. [TG3]: Add 5755 nvram support [TG3]: Add 5755 support [IPV6]: ip6_xmit: remove unnecessary NULL ptr check [NET_SCHED]: cls_u32: remove unnecessary NULL-ptr check [IPV4]: Add fib rule netlink notifications [BNX2]: Update version and reldate [BNX2]: Separate tx producer and consumer fields [BNX2]: Move .h files to bnx2.c [BNX2]: Combine small mem allocations [BNX2]: Fix link change handling [PKTGEN]: Add MPLS extension.
This commit is contained in:
commit
554f593d6c
@ -109,6 +109,22 @@ Examples:
|
||||
cycle through the port range.
|
||||
pgset "udp_dst_max 9" set UDP destination port max.
|
||||
|
||||
pgset "mpls 0001000a,0002000a,0000000a" set MPLS labels (in this example
|
||||
outer label=16,middle label=32,
|
||||
inner label=0 (IPv4 NULL)) Note that
|
||||
there must be no spaces between the
|
||||
arguments. Leading zeros are required.
|
||||
Do not set the bottom of stack bit,
|
||||
thats done automatically. If you do
|
||||
set the bottom of stack bit, that
|
||||
indicates that you want to randomly
|
||||
generate that address and the flag
|
||||
MPLS_RND will be turned on. You
|
||||
can have any mix of random and fixed
|
||||
labels in the label stack.
|
||||
|
||||
pgset "mpls 0" turn off mpls (or any invalid argument works too!)
|
||||
|
||||
pgset stop aborts injection. Also, ^C aborts generator.
|
||||
|
||||
|
||||
@ -167,6 +183,8 @@ pkt_size
|
||||
min_pkt_size
|
||||
max_pkt_size
|
||||
|
||||
mpls
|
||||
|
||||
udp_src_min
|
||||
udp_src_max
|
||||
|
||||
@ -211,4 +229,4 @@ Grant Grundler for testing on IA-64 and parisc, Harald Welte, Lennert Buytenhek
|
||||
Stephen Hemminger, Andi Kleen, Dave Miller and many others.
|
||||
|
||||
|
||||
Good luck with the linux net-development.
|
||||
Good luck with the linux net-development.
|
||||
|
@ -9,13 +9,54 @@
|
||||
* Written by: Michael Chan (mchan@broadcom.com)
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <asm/bitops.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/irq.h>
|
||||
#include <linux/delay.h>
|
||||
#include <asm/byteorder.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/ethtool.h>
|
||||
#include <linux/mii.h>
|
||||
#ifdef NETIF_F_HW_VLAN_TX
|
||||
#include <linux/if_vlan.h>
|
||||
#define BCM_VLAN 1
|
||||
#endif
|
||||
#ifdef NETIF_F_TSO
|
||||
#include <net/ip.h>
|
||||
#include <net/tcp.h>
|
||||
#include <net/checksum.h>
|
||||
#define BCM_TSO 1
|
||||
#endif
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/crc32.h>
|
||||
#include <linux/prefetch.h>
|
||||
#include <linux/cache.h>
|
||||
|
||||
#include "bnx2.h"
|
||||
#include "bnx2_fw.h"
|
||||
|
||||
#define DRV_MODULE_NAME "bnx2"
|
||||
#define PFX DRV_MODULE_NAME ": "
|
||||
#define DRV_MODULE_VERSION "1.4.38"
|
||||
#define DRV_MODULE_RELDATE "February 10, 2006"
|
||||
#define DRV_MODULE_VERSION "1.4.39"
|
||||
#define DRV_MODULE_RELDATE "March 22, 2006"
|
||||
|
||||
#define RUN_AT(x) (jiffies + (x))
|
||||
|
||||
@ -313,8 +354,6 @@ bnx2_disable_int(struct bnx2 *bp)
|
||||
static void
|
||||
bnx2_enable_int(struct bnx2 *bp)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
|
||||
BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
|
||||
BNX2_PCICFG_INT_ACK_CMD_MASK_INT | bp->last_status_idx);
|
||||
@ -322,8 +361,7 @@ bnx2_enable_int(struct bnx2 *bp)
|
||||
REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
|
||||
BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | bp->last_status_idx);
|
||||
|
||||
val = REG_RD(bp, BNX2_HC_COMMAND);
|
||||
REG_WR(bp, BNX2_HC_COMMAND, val | BNX2_HC_COMMAND_COAL_NOW);
|
||||
REG_WR(bp, BNX2_HC_COMMAND, bp->hc_cmd | BNX2_HC_COMMAND_COAL_NOW);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -362,15 +400,11 @@ bnx2_free_mem(struct bnx2 *bp)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (bp->stats_blk) {
|
||||
pci_free_consistent(bp->pdev, sizeof(struct statistics_block),
|
||||
bp->stats_blk, bp->stats_blk_mapping);
|
||||
bp->stats_blk = NULL;
|
||||
}
|
||||
if (bp->status_blk) {
|
||||
pci_free_consistent(bp->pdev, sizeof(struct status_block),
|
||||
pci_free_consistent(bp->pdev, bp->status_stats_size,
|
||||
bp->status_blk, bp->status_blk_mapping);
|
||||
bp->status_blk = NULL;
|
||||
bp->stats_blk = NULL;
|
||||
}
|
||||
if (bp->tx_desc_ring) {
|
||||
pci_free_consistent(bp->pdev,
|
||||
@ -395,14 +429,13 @@ bnx2_free_mem(struct bnx2 *bp)
|
||||
static int
|
||||
bnx2_alloc_mem(struct bnx2 *bp)
|
||||
{
|
||||
int i;
|
||||
int i, status_blk_size;
|
||||
|
||||
bp->tx_buf_ring = kmalloc(sizeof(struct sw_bd) * TX_DESC_CNT,
|
||||
GFP_KERNEL);
|
||||
bp->tx_buf_ring = kzalloc(sizeof(struct sw_bd) * TX_DESC_CNT,
|
||||
GFP_KERNEL);
|
||||
if (bp->tx_buf_ring == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
memset(bp->tx_buf_ring, 0, sizeof(struct sw_bd) * TX_DESC_CNT);
|
||||
bp->tx_desc_ring = pci_alloc_consistent(bp->pdev,
|
||||
sizeof(struct tx_bd) *
|
||||
TX_DESC_CNT,
|
||||
@ -428,21 +461,22 @@ bnx2_alloc_mem(struct bnx2 *bp)
|
||||
|
||||
}
|
||||
|
||||
bp->status_blk = pci_alloc_consistent(bp->pdev,
|
||||
sizeof(struct status_block),
|
||||
/* Combine status and statistics blocks into one allocation. */
|
||||
status_blk_size = L1_CACHE_ALIGN(sizeof(struct status_block));
|
||||
bp->status_stats_size = status_blk_size +
|
||||
sizeof(struct statistics_block);
|
||||
|
||||
bp->status_blk = pci_alloc_consistent(bp->pdev, bp->status_stats_size,
|
||||
&bp->status_blk_mapping);
|
||||
if (bp->status_blk == NULL)
|
||||
goto alloc_mem_err;
|
||||
|
||||
memset(bp->status_blk, 0, sizeof(struct status_block));
|
||||
memset(bp->status_blk, 0, bp->status_stats_size);
|
||||
|
||||
bp->stats_blk = pci_alloc_consistent(bp->pdev,
|
||||
sizeof(struct statistics_block),
|
||||
&bp->stats_blk_mapping);
|
||||
if (bp->stats_blk == NULL)
|
||||
goto alloc_mem_err;
|
||||
bp->stats_blk = (void *) ((unsigned long) bp->status_blk +
|
||||
status_blk_size);
|
||||
|
||||
memset(bp->stats_blk, 0, sizeof(struct statistics_block));
|
||||
bp->stats_blk_mapping = bp->status_blk_mapping + status_blk_size;
|
||||
|
||||
return 0;
|
||||
|
||||
@ -1926,6 +1960,13 @@ bnx2_poll(struct net_device *dev, int *budget)
|
||||
spin_lock(&bp->phy_lock);
|
||||
bnx2_phy_int(bp);
|
||||
spin_unlock(&bp->phy_lock);
|
||||
|
||||
/* This is needed to take care of transient status
|
||||
* during link changes.
|
||||
*/
|
||||
REG_WR(bp, BNX2_HC_COMMAND,
|
||||
bp->hc_cmd | BNX2_HC_COMMAND_COAL_NOW_WO_INT);
|
||||
REG_RD(bp, BNX2_HC_COMMAND);
|
||||
}
|
||||
|
||||
if (bp->status_blk->status_tx_quick_consumer_index0 != bp->hw_tx_cons)
|
||||
@ -3307,6 +3348,8 @@ bnx2_init_chip(struct bnx2 *bp)
|
||||
|
||||
udelay(20);
|
||||
|
||||
bp->hc_cmd = REG_RD(bp, BNX2_HC_COMMAND);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -3746,7 +3789,6 @@ bnx2_run_loopback(struct bnx2 *bp, int loopback_mode)
|
||||
struct sk_buff *skb, *rx_skb;
|
||||
unsigned char *packet;
|
||||
u16 rx_start_idx, rx_idx;
|
||||
u32 val;
|
||||
dma_addr_t map;
|
||||
struct tx_bd *txbd;
|
||||
struct sw_bd *rx_buf;
|
||||
@ -3777,8 +3819,9 @@ bnx2_run_loopback(struct bnx2 *bp, int loopback_mode)
|
||||
map = pci_map_single(bp->pdev, skb->data, pkt_size,
|
||||
PCI_DMA_TODEVICE);
|
||||
|
||||
val = REG_RD(bp, BNX2_HC_COMMAND);
|
||||
REG_WR(bp, BNX2_HC_COMMAND, val | BNX2_HC_COMMAND_COAL_NOW_WO_INT);
|
||||
REG_WR(bp, BNX2_HC_COMMAND,
|
||||
bp->hc_cmd | BNX2_HC_COMMAND_COAL_NOW_WO_INT);
|
||||
|
||||
REG_RD(bp, BNX2_HC_COMMAND);
|
||||
|
||||
udelay(5);
|
||||
@ -3802,8 +3845,9 @@ bnx2_run_loopback(struct bnx2 *bp, int loopback_mode)
|
||||
|
||||
udelay(100);
|
||||
|
||||
val = REG_RD(bp, BNX2_HC_COMMAND);
|
||||
REG_WR(bp, BNX2_HC_COMMAND, val | BNX2_HC_COMMAND_COAL_NOW_WO_INT);
|
||||
REG_WR(bp, BNX2_HC_COMMAND,
|
||||
bp->hc_cmd | BNX2_HC_COMMAND_COAL_NOW_WO_INT);
|
||||
|
||||
REG_RD(bp, BNX2_HC_COMMAND);
|
||||
|
||||
udelay(5);
|
||||
@ -3939,7 +3983,6 @@ static int
|
||||
bnx2_test_intr(struct bnx2 *bp)
|
||||
{
|
||||
int i;
|
||||
u32 val;
|
||||
u16 status_idx;
|
||||
|
||||
if (!netif_running(bp->dev))
|
||||
@ -3948,8 +3991,7 @@ bnx2_test_intr(struct bnx2 *bp)
|
||||
status_idx = REG_RD(bp, BNX2_PCICFG_INT_ACK_CMD) & 0xffff;
|
||||
|
||||
/* This register is not touched during run-time. */
|
||||
val = REG_RD(bp, BNX2_HC_COMMAND);
|
||||
REG_WR(bp, BNX2_HC_COMMAND, val | BNX2_HC_COMMAND_COAL_NOW);
|
||||
REG_WR(bp, BNX2_HC_COMMAND, bp->hc_cmd | BNX2_HC_COMMAND_COAL_NOW);
|
||||
REG_RD(bp, BNX2_HC_COMMAND);
|
||||
|
||||
for (i = 0; i < 10; i++) {
|
||||
|
@ -13,46 +13,6 @@
|
||||
#ifndef BNX2_H
|
||||
#define BNX2_H
|
||||
|
||||
#include <linux/config.h>
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <asm/bitops.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/irq.h>
|
||||
#include <linux/delay.h>
|
||||
#include <asm/byteorder.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/ethtool.h>
|
||||
#include <linux/mii.h>
|
||||
#ifdef NETIF_F_HW_VLAN_TX
|
||||
#include <linux/if_vlan.h>
|
||||
#define BCM_VLAN 1
|
||||
#endif
|
||||
#ifdef NETIF_F_TSO
|
||||
#include <net/ip.h>
|
||||
#include <net/tcp.h>
|
||||
#include <net/checksum.h>
|
||||
#define BCM_TSO 1
|
||||
#endif
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/crc32.h>
|
||||
#include <linux/prefetch.h>
|
||||
|
||||
/* Hardware data structures and register definitions automatically
|
||||
* generated from RTL code. Do not modify.
|
||||
*/
|
||||
@ -3917,15 +3877,17 @@ struct bnx2 {
|
||||
#define USING_MSI_FLAG 0x20
|
||||
#define ASF_ENABLE_FLAG 0x40
|
||||
|
||||
struct tx_bd *tx_desc_ring;
|
||||
struct sw_bd *tx_buf_ring;
|
||||
u32 tx_prod_bseq;
|
||||
u16 tx_prod;
|
||||
u16 tx_cons;
|
||||
int tx_ring_size;
|
||||
/* Put tx producer and consumer fields in separate cache lines. */
|
||||
|
||||
u16 hw_tx_cons;
|
||||
u16 hw_rx_cons;
|
||||
u32 tx_prod_bseq __attribute__((aligned(L1_CACHE_BYTES)));
|
||||
u16 tx_prod;
|
||||
|
||||
struct tx_bd *tx_desc_ring;
|
||||
struct sw_bd *tx_buf_ring;
|
||||
int tx_ring_size;
|
||||
|
||||
u16 tx_cons __attribute__((aligned(L1_CACHE_BYTES)));
|
||||
u16 hw_tx_cons;
|
||||
|
||||
#ifdef BCM_VLAN
|
||||
struct vlan_group *vlgrp;
|
||||
@ -3939,6 +3901,7 @@ struct bnx2 {
|
||||
u32 rx_prod_bseq;
|
||||
u16 rx_prod;
|
||||
u16 rx_cons;
|
||||
u16 hw_rx_cons;
|
||||
|
||||
u32 rx_csum;
|
||||
|
||||
@ -4038,6 +4001,7 @@ struct bnx2 {
|
||||
struct statistics_block *stats_blk;
|
||||
dma_addr_t stats_blk_mapping;
|
||||
|
||||
u32 hc_cmd;
|
||||
u32 rx_mode;
|
||||
|
||||
u16 req_line_speed;
|
||||
@ -4082,6 +4046,8 @@ struct bnx2 {
|
||||
|
||||
struct flash_spec *flash_info;
|
||||
u32 flash_size;
|
||||
|
||||
int status_stats_size;
|
||||
};
|
||||
|
||||
static u32 bnx2_reg_rd_ind(struct bnx2 *bp, u32 offset);
|
||||
|
@ -69,8 +69,8 @@
|
||||
|
||||
#define DRV_MODULE_NAME "tg3"
|
||||
#define PFX DRV_MODULE_NAME ": "
|
||||
#define DRV_MODULE_VERSION "3.53"
|
||||
#define DRV_MODULE_RELDATE "Mar 22, 2006"
|
||||
#define DRV_MODULE_VERSION "3.54"
|
||||
#define DRV_MODULE_RELDATE "Mar 23, 2006"
|
||||
|
||||
#define TG3_DEF_MAC_MODE 0
|
||||
#define TG3_DEF_RX_MODE 0
|
||||
@ -225,6 +225,10 @@ static struct pci_device_id tg3_pci_tbl[] = {
|
||||
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
|
||||
{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5754M,
|
||||
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
|
||||
{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5755,
|
||||
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
|
||||
{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5755M,
|
||||
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
|
||||
{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5787,
|
||||
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
|
||||
{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5787M,
|
||||
@ -4557,6 +4561,7 @@ static int tg3_chip_reset(struct tg3 *tp)
|
||||
}
|
||||
|
||||
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752 ||
|
||||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
|
||||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787)
|
||||
tw32(GRC_FASTBOOT_PC, 0);
|
||||
|
||||
@ -6152,6 +6157,9 @@ static int tg3_reset_hw(struct tg3 *tp)
|
||||
gpio_mask |= GRC_LCLCTRL_GPIO_OE3 |
|
||||
GRC_LCLCTRL_GPIO_OUTPUT3;
|
||||
|
||||
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755)
|
||||
gpio_mask |= GRC_LCLCTRL_GPIO_UART_SEL;
|
||||
|
||||
tp->grc_local_ctrl |= tr32(GRC_LOCAL_CTRL) & gpio_mask;
|
||||
|
||||
/* GPIO1 must be driven high for eeprom write protect */
|
||||
@ -6191,7 +6199,8 @@ static int tg3_reset_hw(struct tg3 *tp)
|
||||
}
|
||||
|
||||
/* Enable host coalescing bug fix */
|
||||
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787)
|
||||
if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755) ||
|
||||
(GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787))
|
||||
val |= (1 << 29);
|
||||
|
||||
tw32_f(WDMAC_MODE, val);
|
||||
@ -6249,6 +6258,9 @@ static int tg3_reset_hw(struct tg3 *tp)
|
||||
udelay(100);
|
||||
|
||||
tp->rx_mode = RX_MODE_ENABLE;
|
||||
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755)
|
||||
tp->rx_mode |= RX_MODE_IPV6_CSUM_ENABLE;
|
||||
|
||||
tw32_f(MAC_RX_MODE, tp->rx_mode);
|
||||
udelay(10);
|
||||
|
||||
@ -7907,7 +7919,8 @@ static int tg3_set_tx_csum(struct net_device *dev, u32 data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787)
|
||||
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
|
||||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787)
|
||||
ethtool_op_set_tx_hw_csum(dev, data);
|
||||
else
|
||||
ethtool_op_set_tx_csum(dev, data);
|
||||
@ -8332,7 +8345,8 @@ static int tg3_test_memory(struct tg3 *tp)
|
||||
int i;
|
||||
|
||||
if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) {
|
||||
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787)
|
||||
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
|
||||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787)
|
||||
mem_tbl = mem_tbl_5755;
|
||||
else
|
||||
mem_tbl = mem_tbl_5705;
|
||||
@ -8924,6 +8938,47 @@ static void __devinit tg3_get_5752_nvram_info(struct tg3 *tp)
|
||||
}
|
||||
}
|
||||
|
||||
static void __devinit tg3_get_5755_nvram_info(struct tg3 *tp)
|
||||
{
|
||||
u32 nvcfg1;
|
||||
|
||||
nvcfg1 = tr32(NVRAM_CFG1);
|
||||
|
||||
/* NVRAM protection for TPM */
|
||||
if (nvcfg1 & (1 << 27))
|
||||
tp->tg3_flags2 |= TG3_FLG2_PROTECTED_NVRAM;
|
||||
|
||||
switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) {
|
||||
case FLASH_5755VENDOR_ATMEL_EEPROM_64KHZ:
|
||||
case FLASH_5755VENDOR_ATMEL_EEPROM_376KHZ:
|
||||
tp->nvram_jedecnum = JEDEC_ATMEL;
|
||||
tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
|
||||
tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE;
|
||||
|
||||
nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS;
|
||||
tw32(NVRAM_CFG1, nvcfg1);
|
||||
break;
|
||||
case FLASH_5752VENDOR_ATMEL_FLASH_BUFFERED:
|
||||
case FLASH_5755VENDOR_ATMEL_FLASH_1:
|
||||
case FLASH_5755VENDOR_ATMEL_FLASH_2:
|
||||
case FLASH_5755VENDOR_ATMEL_FLASH_3:
|
||||
case FLASH_5755VENDOR_ATMEL_FLASH_4:
|
||||
tp->nvram_jedecnum = JEDEC_ATMEL;
|
||||
tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
|
||||
tp->tg3_flags2 |= TG3_FLG2_FLASH;
|
||||
tp->nvram_pagesize = 264;
|
||||
break;
|
||||
case FLASH_5752VENDOR_ST_M45PE10:
|
||||
case FLASH_5752VENDOR_ST_M45PE20:
|
||||
case FLASH_5752VENDOR_ST_M45PE40:
|
||||
tp->nvram_jedecnum = JEDEC_ST;
|
||||
tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
|
||||
tp->tg3_flags2 |= TG3_FLG2_FLASH;
|
||||
tp->nvram_pagesize = 256;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void __devinit tg3_get_5787_nvram_info(struct tg3 *tp)
|
||||
{
|
||||
u32 nvcfg1;
|
||||
@ -8997,6 +9052,8 @@ static void __devinit tg3_nvram_init(struct tg3 *tp)
|
||||
|
||||
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752)
|
||||
tg3_get_5752_nvram_info(tp);
|
||||
else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755)
|
||||
tg3_get_5755_nvram_info(tp);
|
||||
else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787)
|
||||
tg3_get_5787_nvram_info(tp);
|
||||
else
|
||||
@ -9310,6 +9367,7 @@ static int tg3_nvram_write_block_buffered(struct tg3 *tp, u32 offset, u32 len,
|
||||
nvram_cmd |= NVRAM_CMD_LAST;
|
||||
|
||||
if ((GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5752) &&
|
||||
(GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5755) &&
|
||||
(GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5787) &&
|
||||
(tp->nvram_jedecnum == JEDEC_ST) &&
|
||||
(nvram_cmd & NVRAM_CMD_FIRST)) {
|
||||
@ -10044,6 +10102,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
|
||||
|
||||
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750 ||
|
||||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752 ||
|
||||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
|
||||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 ||
|
||||
(tp->tg3_flags2 & TG3_FLG2_5780_CLASS))
|
||||
tp->tg3_flags2 |= TG3_FLG2_5750_PLUS;
|
||||
@ -10053,7 +10112,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
|
||||
tp->tg3_flags2 |= TG3_FLG2_5705_PLUS;
|
||||
|
||||
if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS) {
|
||||
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787) {
|
||||
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
|
||||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787) {
|
||||
tp->tg3_flags2 |= TG3_FLG2_HW_TSO_2;
|
||||
tp->tg3_flags2 |= TG3_FLG2_1SHOT_MSI;
|
||||
} else
|
||||
@ -10063,6 +10123,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
|
||||
if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705 &&
|
||||
GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5750 &&
|
||||
GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5752 &&
|
||||
GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5755 &&
|
||||
GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5787)
|
||||
tp->tg3_flags2 |= TG3_FLG2_JUMBO_CAPABLE;
|
||||
|
||||
@ -10219,6 +10280,9 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
|
||||
else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752)
|
||||
tp->grc_local_ctrl |= GRC_LCLCTRL_GPIO_OE3;
|
||||
|
||||
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755)
|
||||
tp->grc_local_ctrl |= GRC_LCLCTRL_GPIO_UART_SEL;
|
||||
|
||||
/* Force the chip into D0. */
|
||||
err = tg3_set_power_state(tp, PCI_D0);
|
||||
if (err) {
|
||||
@ -10274,6 +10338,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
|
||||
tp->tg3_flags2 |= TG3_FLG2_PHY_5704_A0_BUG;
|
||||
|
||||
if ((tp->tg3_flags2 & TG3_FLG2_5705_PLUS) &&
|
||||
(GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5755) &&
|
||||
(GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5787))
|
||||
tp->tg3_flags2 |= TG3_FLG2_PHY_BER_BUG;
|
||||
|
||||
@ -10413,7 +10478,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
|
||||
/* All chips before 5787 can get confused if TX buffers
|
||||
* straddle the 4GB address boundary in some cases.
|
||||
*/
|
||||
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787)
|
||||
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
|
||||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787)
|
||||
tp->dev->hard_start_xmit = tg3_start_xmit;
|
||||
else
|
||||
tp->dev->hard_start_xmit = tg3_start_xmit_dma_bug;
|
||||
@ -11002,6 +11068,7 @@ static char * __devinit tg3_phy_string(struct tg3 *tp)
|
||||
case PHY_ID_BCM5752: return "5752";
|
||||
case PHY_ID_BCM5714: return "5714";
|
||||
case PHY_ID_BCM5780: return "5780";
|
||||
case PHY_ID_BCM5755: return "5755";
|
||||
case PHY_ID_BCM5787: return "5787";
|
||||
case PHY_ID_BCM8002: return "8002/serdes";
|
||||
case 0: return "serdes";
|
||||
@ -11350,7 +11417,8 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
|
||||
* checksumming.
|
||||
*/
|
||||
if ((tp->tg3_flags & TG3_FLAG_BROKEN_CHECKSUMS) == 0) {
|
||||
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787)
|
||||
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
|
||||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787)
|
||||
dev->features |= NETIF_F_HW_CSUM;
|
||||
else
|
||||
dev->features |= NETIF_F_IP_CSUM;
|
||||
|
@ -138,6 +138,7 @@
|
||||
#define ASIC_REV_5752 0x06
|
||||
#define ASIC_REV_5780 0x08
|
||||
#define ASIC_REV_5714 0x09
|
||||
#define ASIC_REV_5755 0x0a
|
||||
#define ASIC_REV_5787 0x0b
|
||||
#define GET_CHIP_REV(CHIP_REV_ID) ((CHIP_REV_ID) >> 8)
|
||||
#define CHIPREV_5700_AX 0x70
|
||||
@ -456,6 +457,7 @@
|
||||
#define RX_MODE_PROMISC 0x00000100
|
||||
#define RX_MODE_NO_CRC_CHECK 0x00000200
|
||||
#define RX_MODE_KEEP_VLAN_TAG 0x00000400
|
||||
#define RX_MODE_IPV6_CSUM_ENABLE 0x01000000
|
||||
#define MAC_RX_STATUS 0x0000046c
|
||||
#define RX_STATUS_REMOTE_TX_XOFFED 0x00000001
|
||||
#define RX_STATUS_XOFF_RCVD 0x00000002
|
||||
@ -1340,6 +1342,7 @@
|
||||
#define GRC_LCLCTRL_CLEARINT 0x00000002
|
||||
#define GRC_LCLCTRL_SETINT 0x00000004
|
||||
#define GRC_LCLCTRL_INT_ON_ATTN 0x00000008
|
||||
#define GRC_LCLCTRL_GPIO_UART_SEL 0x00000010 /* 5755 only */
|
||||
#define GRC_LCLCTRL_USE_SIG_DETECT 0x00000010 /* 5714/5780 only */
|
||||
#define GRC_LCLCTRL_USE_EXT_SIG_DETECT 0x00000020 /* 5714/5780 only */
|
||||
#define GRC_LCLCTRL_GPIO_INPUT3 0x00000020
|
||||
@ -1441,6 +1444,9 @@
|
||||
#define FLASH_5755VENDOR_ATMEL_FLASH_1 0x03400001
|
||||
#define FLASH_5755VENDOR_ATMEL_FLASH_2 0x03400002
|
||||
#define FLASH_5755VENDOR_ATMEL_FLASH_3 0x03400000
|
||||
#define FLASH_5755VENDOR_ATMEL_FLASH_4 0x00000003
|
||||
#define FLASH_5755VENDOR_ATMEL_EEPROM_64KHZ 0x03c00003
|
||||
#define FLASH_5755VENDOR_ATMEL_EEPROM_376KHZ 0x03c00002
|
||||
#define FLASH_5787VENDOR_ATMEL_EEPROM_64KHZ 0x03000003
|
||||
#define FLASH_5787VENDOR_ATMEL_EEPROM_376KHZ 0x03000002
|
||||
#define FLASH_5787VENDOR_MICRO_EEPROM_64KHZ 0x03000000
|
||||
@ -2259,6 +2265,7 @@ struct tg3 {
|
||||
#define PHY_ID_BCM5752 0x60008100
|
||||
#define PHY_ID_BCM5714 0x60008340
|
||||
#define PHY_ID_BCM5780 0x60008350
|
||||
#define PHY_ID_BCM5755 0xbc050cc0
|
||||
#define PHY_ID_BCM5787 0xbc050ce0
|
||||
#define PHY_ID_BCM8002 0x60010140
|
||||
#define PHY_ID_INVALID 0xffffffff
|
||||
@ -2286,7 +2293,7 @@ struct tg3 {
|
||||
(X) == PHY_ID_BCM5705 || (X) == PHY_ID_BCM5750 || \
|
||||
(X) == PHY_ID_BCM5752 || (X) == PHY_ID_BCM5714 || \
|
||||
(X) == PHY_ID_BCM5780 || (X) == PHY_ID_BCM5787 || \
|
||||
(X) == PHY_ID_BCM8002)
|
||||
(X) == PHY_ID_BCM5755 || (X) == PHY_ID_BCM8002)
|
||||
|
||||
struct tg3_hw_stats *hw_stats;
|
||||
dma_addr_t stats_mapping;
|
||||
|
@ -1864,11 +1864,13 @@
|
||||
#define PCI_DEVICE_ID_TIGON3_5780S 0x166b
|
||||
#define PCI_DEVICE_ID_TIGON3_5705F 0x166e
|
||||
#define PCI_DEVICE_ID_TIGON3_5754M 0x1672
|
||||
#define PCI_DEVICE_ID_TIGON3_5755M 0x1673
|
||||
#define PCI_DEVICE_ID_TIGON3_5750 0x1676
|
||||
#define PCI_DEVICE_ID_TIGON3_5751 0x1677
|
||||
#define PCI_DEVICE_ID_TIGON3_5715 0x1678
|
||||
#define PCI_DEVICE_ID_TIGON3_5715S 0x1679
|
||||
#define PCI_DEVICE_ID_TIGON3_5754 0x167a
|
||||
#define PCI_DEVICE_ID_TIGON3_5755 0x167b
|
||||
#define PCI_DEVICE_ID_TIGON3_5750M 0x167c
|
||||
#define PCI_DEVICE_ID_TIGON3_5751M 0x167d
|
||||
#define PCI_DEVICE_ID_TIGON3_5751F 0x167e
|
||||
|
@ -839,6 +839,7 @@ enum
|
||||
#define RTMGRP_IPV4_IFADDR 0x10
|
||||
#define RTMGRP_IPV4_MROUTE 0x20
|
||||
#define RTMGRP_IPV4_ROUTE 0x40
|
||||
#define RTMGRP_IPV4_RULE 0x80
|
||||
|
||||
#define RTMGRP_IPV6_IFADDR 0x100
|
||||
#define RTMGRP_IPV6_MROUTE 0x200
|
||||
@ -869,7 +870,8 @@ enum rtnetlink_groups {
|
||||
#define RTNLGRP_IPV4_MROUTE RTNLGRP_IPV4_MROUTE
|
||||
RTNLGRP_IPV4_ROUTE,
|
||||
#define RTNLGRP_IPV4_ROUTE RTNLGRP_IPV4_ROUTE
|
||||
RTNLGRP_NOP1,
|
||||
RTNLGRP_IPV4_RULE,
|
||||
#define RTNLGRP_IPV4_RULE RTNLGRP_IPV4_RULE
|
||||
RTNLGRP_IPV6_IFADDR,
|
||||
#define RTNLGRP_IPV6_IFADDR RTNLGRP_IPV6_IFADDR
|
||||
RTNLGRP_IPV6_MROUTE,
|
||||
|
@ -106,6 +106,9 @@
|
||||
*
|
||||
* interruptible_sleep_on_timeout() replaced Nishanth Aravamudan <nacc@us.ibm.com>
|
||||
* 050103
|
||||
*
|
||||
* MPLS support by Steven Whitehouse <steve@chygwyn.com>
|
||||
*
|
||||
*/
|
||||
#include <linux/sys.h>
|
||||
#include <linux/types.h>
|
||||
@ -154,7 +157,7 @@
|
||||
#include <asm/div64.h> /* do_div */
|
||||
#include <asm/timex.h>
|
||||
|
||||
#define VERSION "pktgen v2.66: Packet Generator for packet performance testing.\n"
|
||||
#define VERSION "pktgen v2.67: Packet Generator for packet performance testing.\n"
|
||||
|
||||
/* #define PG_DEBUG(a) a */
|
||||
#define PG_DEBUG(a)
|
||||
@ -162,6 +165,8 @@
|
||||
/* The buckets are exponential in 'width' */
|
||||
#define LAT_BUCKETS_MAX 32
|
||||
#define IP_NAME_SZ 32
|
||||
#define MAX_MPLS_LABELS 16 /* This is the max label stack depth */
|
||||
#define MPLS_STACK_BOTTOM __constant_htonl(0x00000100)
|
||||
|
||||
/* Device flag bits */
|
||||
#define F_IPSRC_RND (1<<0) /* IP-Src Random */
|
||||
@ -172,6 +177,7 @@
|
||||
#define F_MACDST_RND (1<<5) /* MAC-Dst Random */
|
||||
#define F_TXSIZE_RND (1<<6) /* Transmit size is random */
|
||||
#define F_IPV6 (1<<7) /* Interface in IPV6 Mode */
|
||||
#define F_MPLS_RND (1<<8) /* Random MPLS labels */
|
||||
|
||||
/* Thread control flag bits */
|
||||
#define T_TERMINATE (1<<0)
|
||||
@ -278,6 +284,10 @@ struct pktgen_dev {
|
||||
__u16 udp_dst_min; /* inclusive, dest UDP port */
|
||||
__u16 udp_dst_max; /* exclusive, dest UDP port */
|
||||
|
||||
/* MPLS */
|
||||
unsigned nr_labels; /* Depth of stack, 0 = no MPLS */
|
||||
__be32 labels[MAX_MPLS_LABELS];
|
||||
|
||||
__u32 src_mac_count; /* How many MACs to iterate through */
|
||||
__u32 dst_mac_count; /* How many MACs to iterate through */
|
||||
|
||||
@ -623,9 +633,19 @@ static int pktgen_if_show(struct seq_file *seq, void *v)
|
||||
pkt_dev->udp_dst_min, pkt_dev->udp_dst_max);
|
||||
|
||||
seq_printf(seq,
|
||||
" src_mac_count: %d dst_mac_count: %d \n Flags: ",
|
||||
" src_mac_count: %d dst_mac_count: %d\n",
|
||||
pkt_dev->src_mac_count, pkt_dev->dst_mac_count);
|
||||
|
||||
if (pkt_dev->nr_labels) {
|
||||
unsigned i;
|
||||
seq_printf(seq, " mpls: ");
|
||||
for(i = 0; i < pkt_dev->nr_labels; i++)
|
||||
seq_printf(seq, "%08x%s", ntohl(pkt_dev->labels[i]),
|
||||
i == pkt_dev->nr_labels-1 ? "\n" : ", ");
|
||||
}
|
||||
|
||||
seq_printf(seq, " Flags: ");
|
||||
|
||||
if (pkt_dev->flags & F_IPV6)
|
||||
seq_printf(seq, "IPV6 ");
|
||||
|
||||
@ -644,6 +664,9 @@ static int pktgen_if_show(struct seq_file *seq, void *v)
|
||||
if (pkt_dev->flags & F_UDPDST_RND)
|
||||
seq_printf(seq, "UDPDST_RND ");
|
||||
|
||||
if (pkt_dev->flags & F_MPLS_RND)
|
||||
seq_printf(seq, "MPLS_RND ");
|
||||
|
||||
if (pkt_dev->flags & F_MACSRC_RND)
|
||||
seq_printf(seq, "MACSRC_RND ");
|
||||
|
||||
@ -691,6 +714,29 @@ static int pktgen_if_show(struct seq_file *seq, void *v)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int hex32_arg(const char __user *user_buffer, __u32 *num)
|
||||
{
|
||||
int i = 0;
|
||||
*num = 0;
|
||||
|
||||
for(; i < 8; i++) {
|
||||
char c;
|
||||
*num <<= 4;
|
||||
if (get_user(c, &user_buffer[i]))
|
||||
return -EFAULT;
|
||||
if ((c >= '0') && (c <= '9'))
|
||||
*num |= c - '0';
|
||||
else if ((c >= 'a') && (c <= 'f'))
|
||||
*num |= c - 'a' + 10;
|
||||
else if ((c >= 'A') && (c <= 'F'))
|
||||
*num |= c - 'A' + 10;
|
||||
else
|
||||
break;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
static int count_trail_chars(const char __user * user_buffer,
|
||||
unsigned int maxlen)
|
||||
{
|
||||
@ -759,6 +805,35 @@ done_str:
|
||||
return i;
|
||||
}
|
||||
|
||||
static ssize_t get_labels(const char __user *buffer, struct pktgen_dev *pkt_dev)
|
||||
{
|
||||
unsigned n = 0;
|
||||
char c;
|
||||
ssize_t i = 0;
|
||||
int len;
|
||||
|
||||
pkt_dev->nr_labels = 0;
|
||||
do {
|
||||
__u32 tmp;
|
||||
len = hex32_arg(&buffer[i], &tmp);
|
||||
if (len <= 0)
|
||||
return len;
|
||||
pkt_dev->labels[n] = htonl(tmp);
|
||||
if (pkt_dev->labels[n] & MPLS_STACK_BOTTOM)
|
||||
pkt_dev->flags |= F_MPLS_RND;
|
||||
i += len;
|
||||
if (get_user(c, &buffer[i]))
|
||||
return -EFAULT;
|
||||
i++;
|
||||
n++;
|
||||
if (n >= MAX_MPLS_LABELS)
|
||||
return -E2BIG;
|
||||
} while(c == ',');
|
||||
|
||||
pkt_dev->nr_labels = n;
|
||||
return i;
|
||||
}
|
||||
|
||||
static ssize_t pktgen_if_write(struct file *file,
|
||||
const char __user * user_buffer, size_t count,
|
||||
loff_t * offset)
|
||||
@ -1059,6 +1134,12 @@ static ssize_t pktgen_if_write(struct file *file,
|
||||
else if (strcmp(f, "!MACDST_RND") == 0)
|
||||
pkt_dev->flags &= ~F_MACDST_RND;
|
||||
|
||||
else if (strcmp(f, "MPLS_RND") == 0)
|
||||
pkt_dev->flags |= F_MPLS_RND;
|
||||
|
||||
else if (strcmp(f, "!MPLS_RND") == 0)
|
||||
pkt_dev->flags &= ~F_MPLS_RND;
|
||||
|
||||
else {
|
||||
sprintf(pg_result,
|
||||
"Flag -:%s:- unknown\nAvailable flags, (prepend ! to un-set flag):\n%s",
|
||||
@ -1354,6 +1435,19 @@ static ssize_t pktgen_if_write(struct file *file,
|
||||
return count;
|
||||
}
|
||||
|
||||
if (!strcmp(name, "mpls")) {
|
||||
unsigned n, offset;
|
||||
len = get_labels(&user_buffer[i], pkt_dev);
|
||||
if (len < 0) { return len; }
|
||||
i += len;
|
||||
offset = sprintf(pg_result, "OK: mpls=");
|
||||
for(n = 0; n < pkt_dev->nr_labels; n++)
|
||||
offset += sprintf(pg_result + offset,
|
||||
"%08x%s", ntohl(pkt_dev->labels[n]),
|
||||
n == pkt_dev->nr_labels-1 ? "" : ",");
|
||||
return count;
|
||||
}
|
||||
|
||||
sprintf(pkt_dev->result, "No such parameter \"%s\"", name);
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -1846,6 +1940,15 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev)
|
||||
pkt_dev->hh[1] = tmp;
|
||||
}
|
||||
|
||||
if (pkt_dev->flags & F_MPLS_RND) {
|
||||
unsigned i;
|
||||
for(i = 0; i < pkt_dev->nr_labels; i++)
|
||||
if (pkt_dev->labels[i] & MPLS_STACK_BOTTOM)
|
||||
pkt_dev->labels[i] = MPLS_STACK_BOTTOM |
|
||||
(pktgen_random() &
|
||||
htonl(0x000fffff));
|
||||
}
|
||||
|
||||
if (pkt_dev->udp_src_min < pkt_dev->udp_src_max) {
|
||||
if (pkt_dev->flags & F_UDPSRC_RND)
|
||||
pkt_dev->cur_udp_src =
|
||||
@ -1968,6 +2071,16 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev)
|
||||
pkt_dev->flows[flow].count++;
|
||||
}
|
||||
|
||||
static void mpls_push(__be32 *mpls, struct pktgen_dev *pkt_dev)
|
||||
{
|
||||
unsigned i;
|
||||
for(i = 0; i < pkt_dev->nr_labels; i++) {
|
||||
*mpls++ = pkt_dev->labels[i] & ~MPLS_STACK_BOTTOM;
|
||||
}
|
||||
mpls--;
|
||||
*mpls |= MPLS_STACK_BOTTOM;
|
||||
}
|
||||
|
||||
static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
|
||||
struct pktgen_dev *pkt_dev)
|
||||
{
|
||||
@ -1977,6 +2090,11 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
|
||||
int datalen, iplen;
|
||||
struct iphdr *iph;
|
||||
struct pktgen_hdr *pgh = NULL;
|
||||
__be16 protocol = __constant_htons(ETH_P_IP);
|
||||
__be32 *mpls;
|
||||
|
||||
if (pkt_dev->nr_labels)
|
||||
protocol = __constant_htons(ETH_P_MPLS_UC);
|
||||
|
||||
/* Update any of the values, used when we're incrementing various
|
||||
* fields.
|
||||
@ -1984,7 +2102,8 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
|
||||
mod_cur_headers(pkt_dev);
|
||||
|
||||
datalen = (odev->hard_header_len + 16) & ~0xf;
|
||||
skb = alloc_skb(pkt_dev->cur_pkt_size + 64 + datalen, GFP_ATOMIC);
|
||||
skb = alloc_skb(pkt_dev->cur_pkt_size + 64 + datalen +
|
||||
pkt_dev->nr_labels*sizeof(u32), GFP_ATOMIC);
|
||||
if (!skb) {
|
||||
sprintf(pkt_dev->result, "No memory");
|
||||
return NULL;
|
||||
@ -1994,13 +2113,18 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
|
||||
|
||||
/* Reserve for ethernet and IP header */
|
||||
eth = (__u8 *) skb_push(skb, 14);
|
||||
mpls = (__be32 *)skb_put(skb, pkt_dev->nr_labels*sizeof(__u32));
|
||||
if (pkt_dev->nr_labels)
|
||||
mpls_push(mpls, pkt_dev);
|
||||
iph = (struct iphdr *)skb_put(skb, sizeof(struct iphdr));
|
||||
udph = (struct udphdr *)skb_put(skb, sizeof(struct udphdr));
|
||||
|
||||
memcpy(eth, pkt_dev->hh, 12);
|
||||
*(u16 *) & eth[12] = __constant_htons(ETH_P_IP);
|
||||
*(u16 *) & eth[12] = protocol;
|
||||
|
||||
datalen = pkt_dev->cur_pkt_size - 14 - 20 - 8; /* Eth + IPh + UDPh */
|
||||
/* Eth + IPh + UDPh + mpls */
|
||||
datalen = pkt_dev->cur_pkt_size - 14 - 20 - 8 -
|
||||
pkt_dev->nr_labels*sizeof(u32);
|
||||
if (datalen < sizeof(struct pktgen_hdr))
|
||||
datalen = sizeof(struct pktgen_hdr);
|
||||
|
||||
@ -2021,8 +2145,8 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
|
||||
iph->tot_len = htons(iplen);
|
||||
iph->check = 0;
|
||||
iph->check = ip_fast_csum((void *)iph, iph->ihl);
|
||||
skb->protocol = __constant_htons(ETH_P_IP);
|
||||
skb->mac.raw = ((u8 *) iph) - 14;
|
||||
skb->protocol = protocol;
|
||||
skb->mac.raw = ((u8 *) iph) - 14 - pkt_dev->nr_labels*sizeof(u32);
|
||||
skb->dev = odev;
|
||||
skb->pkt_type = PACKET_HOST;
|
||||
|
||||
@ -2274,13 +2398,19 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
|
||||
int datalen;
|
||||
struct ipv6hdr *iph;
|
||||
struct pktgen_hdr *pgh = NULL;
|
||||
__be16 protocol = __constant_htons(ETH_P_IPV6);
|
||||
__be32 *mpls;
|
||||
|
||||
if (pkt_dev->nr_labels)
|
||||
protocol = __constant_htons(ETH_P_MPLS_UC);
|
||||
|
||||
/* Update any of the values, used when we're incrementing various
|
||||
* fields.
|
||||
*/
|
||||
mod_cur_headers(pkt_dev);
|
||||
|
||||
skb = alloc_skb(pkt_dev->cur_pkt_size + 64 + 16, GFP_ATOMIC);
|
||||
skb = alloc_skb(pkt_dev->cur_pkt_size + 64 + 16 +
|
||||
pkt_dev->nr_labels*sizeof(u32), GFP_ATOMIC);
|
||||
if (!skb) {
|
||||
sprintf(pkt_dev->result, "No memory");
|
||||
return NULL;
|
||||
@ -2290,13 +2420,19 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
|
||||
|
||||
/* Reserve for ethernet and IP header */
|
||||
eth = (__u8 *) skb_push(skb, 14);
|
||||
mpls = (__be32 *)skb_put(skb, pkt_dev->nr_labels*sizeof(__u32));
|
||||
if (pkt_dev->nr_labels)
|
||||
mpls_push(mpls, pkt_dev);
|
||||
iph = (struct ipv6hdr *)skb_put(skb, sizeof(struct ipv6hdr));
|
||||
udph = (struct udphdr *)skb_put(skb, sizeof(struct udphdr));
|
||||
|
||||
memcpy(eth, pkt_dev->hh, 12);
|
||||
*(u16 *) & eth[12] = __constant_htons(ETH_P_IPV6);
|
||||
|
||||
datalen = pkt_dev->cur_pkt_size - 14 - sizeof(struct ipv6hdr) - sizeof(struct udphdr); /* Eth + IPh + UDPh */
|
||||
/* Eth + IPh + UDPh + mpls */
|
||||
datalen = pkt_dev->cur_pkt_size - 14 -
|
||||
sizeof(struct ipv6hdr) - sizeof(struct udphdr) -
|
||||
pkt_dev->nr_labels*sizeof(u32);
|
||||
|
||||
if (datalen < sizeof(struct pktgen_hdr)) {
|
||||
datalen = sizeof(struct pktgen_hdr);
|
||||
@ -2320,8 +2456,8 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
|
||||
ipv6_addr_copy(&iph->daddr, &pkt_dev->cur_in6_daddr);
|
||||
ipv6_addr_copy(&iph->saddr, &pkt_dev->cur_in6_saddr);
|
||||
|
||||
skb->mac.raw = ((u8 *) iph) - 14;
|
||||
skb->protocol = __constant_htons(ETH_P_IPV6);
|
||||
skb->mac.raw = ((u8 *) iph) - 14 - pkt_dev->nr_labels*sizeof(u32);
|
||||
skb->protocol = protocol;
|
||||
skb->dev = odev;
|
||||
skb->pkt_type = PACKET_HOST;
|
||||
|
||||
|
@ -104,6 +104,8 @@ static struct hlist_head fib_rules;
|
||||
|
||||
/* writer func called from netlink -- rtnl_sem hold*/
|
||||
|
||||
static void rtmsg_rule(int, struct fib_rule *);
|
||||
|
||||
int inet_rtm_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
|
||||
{
|
||||
struct rtattr **rta = arg;
|
||||
@ -131,6 +133,7 @@ int inet_rtm_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
|
||||
|
||||
hlist_del_rcu(&r->hlist);
|
||||
r->r_dead = 1;
|
||||
rtmsg_rule(RTM_DELRULE, r);
|
||||
fib_rule_put(r);
|
||||
err = 0;
|
||||
break;
|
||||
@ -253,6 +256,7 @@ int inet_rtm_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
|
||||
else
|
||||
hlist_add_before_rcu(&new_r->hlist, &r->hlist);
|
||||
|
||||
rtmsg_rule(RTM_NEWRULE, new_r);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -382,14 +386,14 @@ static struct notifier_block fib_rules_notifier = {
|
||||
|
||||
static __inline__ int inet_fill_rule(struct sk_buff *skb,
|
||||
struct fib_rule *r,
|
||||
struct netlink_callback *cb,
|
||||
u32 pid, u32 seq, int event,
|
||||
unsigned int flags)
|
||||
{
|
||||
struct rtmsg *rtm;
|
||||
struct nlmsghdr *nlh;
|
||||
unsigned char *b = skb->tail;
|
||||
|
||||
nlh = NLMSG_NEW_ANSWER(skb, cb, RTM_NEWRULE, sizeof(*rtm), flags);
|
||||
nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*rtm), flags);
|
||||
rtm = NLMSG_DATA(nlh);
|
||||
rtm->rtm_family = AF_INET;
|
||||
rtm->rtm_dst_len = r->r_dst_len;
|
||||
@ -430,6 +434,21 @@ rtattr_failure:
|
||||
|
||||
/* callers should hold rtnl semaphore */
|
||||
|
||||
static void rtmsg_rule(int event, struct fib_rule *r)
|
||||
{
|
||||
int size = NLMSG_SPACE(sizeof(struct rtmsg) + 128);
|
||||
struct sk_buff *skb = alloc_skb(size, GFP_KERNEL);
|
||||
|
||||
if (!skb)
|
||||
netlink_set_err(rtnl, 0, RTNLGRP_IPV4_RULE, ENOBUFS);
|
||||
else if (inet_fill_rule(skb, r, 0, 0, event, 0) < 0) {
|
||||
kfree_skb(skb);
|
||||
netlink_set_err(rtnl, 0, RTNLGRP_IPV4_RULE, EINVAL);
|
||||
} else {
|
||||
netlink_broadcast(rtnl, skb, 0, RTNLGRP_IPV4_RULE, GFP_KERNEL);
|
||||
}
|
||||
}
|
||||
|
||||
int inet_dump_rules(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
{
|
||||
int idx = 0;
|
||||
@ -442,7 +461,9 @@ int inet_dump_rules(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
|
||||
if (idx < s_idx)
|
||||
continue;
|
||||
if (inet_fill_rule(skb, r, cb, NLM_F_MULTI) < 0)
|
||||
if (inet_fill_rule(skb, r, NETLINK_CB(cb->skb).pid,
|
||||
cb->nlh->nlmsg_seq,
|
||||
RTM_NEWRULE, NLM_F_MULTI) < 0)
|
||||
break;
|
||||
idx++;
|
||||
}
|
||||
|
@ -161,7 +161,7 @@ int ip6_output(struct sk_buff *skb)
|
||||
int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
|
||||
struct ipv6_txoptions *opt, int ipfragok)
|
||||
{
|
||||
struct ipv6_pinfo *np = sk ? inet6_sk(sk) : NULL;
|
||||
struct ipv6_pinfo *np = inet6_sk(sk);
|
||||
struct in6_addr *first_hop = &fl->fl6_dst;
|
||||
struct dst_entry *dst = skb->dst;
|
||||
struct ipv6hdr *hdr;
|
||||
|
@ -347,8 +347,7 @@ static int u32_destroy_key(struct tcf_proto *tp, struct tc_u_knode *n)
|
||||
if (n->ht_down)
|
||||
n->ht_down->refcnt--;
|
||||
#ifdef CONFIG_CLS_U32_PERF
|
||||
if (n)
|
||||
kfree(n->pf);
|
||||
kfree(n->pf);
|
||||
#endif
|
||||
kfree(n);
|
||||
return 0;
|
||||
@ -680,8 +679,7 @@ static int u32_change(struct tcf_proto *tp, unsigned long base, u32 handle,
|
||||
return 0;
|
||||
}
|
||||
#ifdef CONFIG_CLS_U32_PERF
|
||||
if (n)
|
||||
kfree(n->pf);
|
||||
kfree(n->pf);
|
||||
#endif
|
||||
kfree(n);
|
||||
return err;
|
||||
|
Loading…
Reference in New Issue
Block a user