Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 352489
b: refs/heads/master
c: f85b02c
h: refs/heads/master
i:
  352487: ac7b382
v: v3
  • Loading branch information
David S. Miller committed Feb 15, 2013
1 parent eccfdbe commit e18d12b
Show file tree
Hide file tree
Showing 28 changed files with 328 additions and 70 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 8fc3bb6daab26e0c40c19040208091f140b6f8d5
refs/heads/master: f85b02c2bd7be7832f4d1ff55f401fcf38573e47
32 changes: 26 additions & 6 deletions trunk/drivers/net/ethernet/broadcom/tg3.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,10 @@ static inline void _tg3_flag_clear(enum TG3_FLAGS flag, unsigned long *bits)

#define DRV_MODULE_NAME "tg3"
#define TG3_MAJ_NUM 3
#define TG3_MIN_NUM 129
#define TG3_MIN_NUM 130
#define DRV_MODULE_VERSION \
__stringify(TG3_MAJ_NUM) "." __stringify(TG3_MIN_NUM)
#define DRV_MODULE_RELDATE "January 06, 2013"
#define DRV_MODULE_RELDATE "February 14, 2013"

#define RESET_KIND_SHUTDOWN 0
#define RESET_KIND_INIT 1
Expand Down Expand Up @@ -332,6 +332,7 @@ static DEFINE_PCI_DEVICE_TABLE(tg3_pci_tbl) = {
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5719)},
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5720)},
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57762)},
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57766)},
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5762)},
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5725)},
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5727)},
Expand Down Expand Up @@ -9179,7 +9180,14 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
}

if (GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_57765_AX) {
u32 grc_mode = tr32(GRC_MODE);
u32 grc_mode;

/* Fix transmit hangs */
val = tr32(TG3_CPMU_PADRNG_CTL);
val |= TG3_CPMU_PADRNG_CTL_RDIV2;
tw32(TG3_CPMU_PADRNG_CTL, val);

grc_mode = tr32(GRC_MODE);

/* Access the lower 1K of DL PCIE block registers. */
val = grc_mode & ~GRC_MODE_PCIE_PORT_MASK;
Expand Down Expand Up @@ -9492,6 +9500,14 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
if (tg3_flag(tp, PCI_EXPRESS))
rdmac_mode |= RDMAC_MODE_FIFO_LONG_BURST;

if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57766) {
tp->dma_limit = 0;
if (tp->dev->mtu <= ETH_DATA_LEN) {
rdmac_mode |= RDMAC_MODE_JMB_2K_MMRR;
tp->dma_limit = TG3_TX_BD_DMA_MAX_2K;
}
}

if (tg3_flag(tp, HW_TSO_1) ||
tg3_flag(tp, HW_TSO_2) ||
tg3_flag(tp, HW_TSO_3))
Expand Down Expand Up @@ -13867,7 +13883,8 @@ static void tg3_get_5720_nvram_info(struct tg3 *tp)
tp->nvram_size = TG3_NVRAM_SIZE_1MB;
break;
default:
tp->nvram_size = TG3_NVRAM_SIZE_128KB;
if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5762)
tp->nvram_size = TG3_NVRAM_SIZE_128KB;
break;
}
break;
Expand Down Expand Up @@ -13913,7 +13930,8 @@ static void tg3_get_5720_nvram_info(struct tg3 *tp)
tp->nvram_size = TG3_NVRAM_SIZE_1MB;
break;
default:
tp->nvram_size = TG3_NVRAM_SIZE_128KB;
if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5762)
tp->nvram_size = TG3_NVRAM_SIZE_128KB;
break;
}
break;
Expand Down Expand Up @@ -14498,7 +14516,7 @@ static int tg3_phy_probe(struct tg3 *tp)
(GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762 ||
(tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718 &&
(GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 &&
tp->pci_chip_rev_id != CHIPREV_ID_5717_A0) ||
(GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765 &&
tp->pci_chip_rev_id != CHIPREV_ID_57765_A0)))
Expand Down Expand Up @@ -16884,6 +16902,8 @@ static int tg3_init_one(struct pci_dev *pdev,

tg3_timer_init(tp);

tg3_carrier_off(tp);

err = register_netdev(dev);
if (err) {
dev_err(&pdev->dev, "Cannot register net device, aborting\n");
Expand Down
2 changes: 2 additions & 0 deletions trunk/drivers/net/ethernet/broadcom/tg3.h
Original file line number Diff line number Diff line change
Expand Up @@ -1164,6 +1164,8 @@
#define CPMU_MUTEX_GNT_DRIVER 0x00001000
#define TG3_CPMU_PHY_STRAP 0x00003664
#define TG3_CPMU_PHY_STRAP_IS_SERDES 0x00000020
#define TG3_CPMU_PADRNG_CTL 0x00003668
#define TG3_CPMU_PADRNG_CTL_RDIV2 0x00040000
/* 0x3664 --> 0x36b0 unused */

#define TG3_CPMU_EEE_MODE 0x000036b0
Expand Down
3 changes: 1 addition & 2 deletions trunk/drivers/net/ppp/ppp_generic.c
Original file line number Diff line number Diff line change
Expand Up @@ -1805,8 +1805,7 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb)
/* the filter instructions are constructed assuming
a four-byte PPP header on each packet */
if (ppp->pass_filter || ppp->active_filter) {
if (skb_cloned(skb) &&
pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
if (skb_unclone(skb, GFP_ATOMIC))
goto err;

*skb_push(skb, 2) = 0;
Expand Down
3 changes: 2 additions & 1 deletion trunk/include/linux/netdev_features.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ enum {
NETIF_F_TSO_ECN_BIT, /* ... TCP ECN support */
NETIF_F_TSO6_BIT, /* ... TCPv6 segmentation */
NETIF_F_FSO_BIT, /* ... FCoE segmentation */
NETIF_F_GSO_RESERVED1, /* ... free (fill GSO_MASK to 8 bits) */
NETIF_F_GSO_GRE_BIT, /* ... GRE with TSO */
/**/NETIF_F_GSO_LAST, /* [can't be last bit, see GSO_MASK] */
NETIF_F_GSO_RESERVED2 /* ... free (fill GSO_MASK to 8 bits) */
= NETIF_F_GSO_LAST,
Expand Down Expand Up @@ -102,6 +102,7 @@ enum {
#define NETIF_F_VLAN_CHALLENGED __NETIF_F(VLAN_CHALLENGED)
#define NETIF_F_RXFCS __NETIF_F(RXFCS)
#define NETIF_F_RXALL __NETIF_F(RXALL)
#define NETIF_F_GRE_GSO __NETIF_F(GSO_GRE)

/* Features valid for ethtool to change */
/* = all defined minus driver/device-class-related */
Expand Down
2 changes: 2 additions & 0 deletions trunk/include/linux/netdevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -2671,6 +2671,8 @@ extern void netdev_upper_dev_unlink(struct net_device *dev,
extern int skb_checksum_help(struct sk_buff *skb);
extern struct sk_buff *__skb_gso_segment(struct sk_buff *skb,
netdev_features_t features, bool tx_path);
extern struct sk_buff *skb_mac_gso_segment(struct sk_buff *skb,
netdev_features_t features);

static inline
struct sk_buff *skb_gso_segment(struct sk_buff *skb, netdev_features_t features)
Expand Down
27 changes: 27 additions & 0 deletions trunk/include/linux/skbuff.h
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,8 @@ enum {
SKB_GSO_TCPV6 = 1 << 4,

SKB_GSO_FCOE = 1 << 5,

SKB_GSO_GRE = 1 << 6,
};

#if BITS_PER_LONG > 32
Expand Down Expand Up @@ -804,6 +806,16 @@ static inline int skb_cloned(const struct sk_buff *skb)
(atomic_read(&skb_shinfo(skb)->dataref) & SKB_DATAREF_MASK) != 1;
}

static inline int skb_unclone(struct sk_buff *skb, gfp_t pri)
{
might_sleep_if(pri & __GFP_WAIT);

if (skb_cloned(skb))
return pskb_expand_head(skb, 0, 0, pri);

return 0;
}

/**
* skb_header_cloned - is the header a clone
* @skb: buffer to check
Expand Down Expand Up @@ -2722,6 +2734,21 @@ static inline struct sec_path *skb_sec_path(struct sk_buff *skb)
}
#endif

/* Keeps track of mac header offset relative to skb->head.
* It is useful for TSO of Tunneling protocol. e.g. GRE.
* For non-tunnel skb it points to skb_mac_header() and for
* tunnel skb it points to outer mac header. */
struct skb_gso_cb {
int mac_offset;
};
#define SKB_GSO_CB(skb) ((struct skb_gso_cb *)(skb)->cb)

static inline int skb_tnl_header_len(const struct sk_buff *inner_skb)
{
return (skb_mac_header(inner_skb) - inner_skb->head) -
SKB_GSO_CB(inner_skb)->mac_offset;
}

static inline bool skb_is_gso(const struct sk_buff *skb)
{
return skb_shinfo(skb)->gso_size;
Expand Down
80 changes: 49 additions & 31 deletions trunk/net/core/dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -2327,37 +2327,20 @@ int skb_checksum_help(struct sk_buff *skb)
}
EXPORT_SYMBOL(skb_checksum_help);

/* openvswitch calls this on rx path, so we need a different check.
*/
static inline bool skb_needs_check(struct sk_buff *skb, bool tx_path)
{
if (tx_path)
return skb->ip_summed != CHECKSUM_PARTIAL;
else
return skb->ip_summed == CHECKSUM_NONE;
}

/**
* __skb_gso_segment - Perform segmentation on skb.
* skb_mac_gso_segment - mac layer segmentation handler.
* @skb: buffer to segment
* @features: features for the output path (see dev->features)
* @tx_path: whether it is called in TX path
*
* This function segments the given skb and returns a list of segments.
*
* It may return NULL if the skb requires no segmentation. This is
* only possible when GSO is used for verifying header integrity.
*/
struct sk_buff *__skb_gso_segment(struct sk_buff *skb,
netdev_features_t features, bool tx_path)
struct sk_buff *skb_mac_gso_segment(struct sk_buff *skb,
netdev_features_t features)
{
struct sk_buff *segs = ERR_PTR(-EPROTONOSUPPORT);
struct packet_offload *ptype;
__be16 type = skb->protocol;
int vlan_depth = ETH_HLEN;
int err;

while (type == htons(ETH_P_8021Q)) {
int vlan_depth = ETH_HLEN;
struct vlan_hdr *vh;

if (unlikely(!pskb_may_pull(skb, vlan_depth + VLAN_HLEN)))
Expand All @@ -2368,22 +2351,14 @@ struct sk_buff *__skb_gso_segment(struct sk_buff *skb,
vlan_depth += VLAN_HLEN;
}

skb_reset_mac_header(skb);
skb->mac_len = skb->network_header - skb->mac_header;
__skb_pull(skb, skb->mac_len);

if (unlikely(skb_needs_check(skb, tx_path))) {
skb_warn_bad_offload(skb);

if (skb_header_cloned(skb) &&
(err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC)))
return ERR_PTR(err);
}

rcu_read_lock();
list_for_each_entry_rcu(ptype, &offload_base, list) {
if (ptype->type == type && ptype->callbacks.gso_segment) {
if (unlikely(skb->ip_summed != CHECKSUM_PARTIAL)) {
int err;

err = ptype->callbacks.gso_send_check(skb);
segs = ERR_PTR(err);
if (err || skb_gso_ok(skb, features))
Expand All @@ -2401,6 +2376,49 @@ struct sk_buff *__skb_gso_segment(struct sk_buff *skb,

return segs;
}
EXPORT_SYMBOL(skb_mac_gso_segment);


/* openvswitch calls this on rx path, so we need a different check.
*/
static inline bool skb_needs_check(struct sk_buff *skb, bool tx_path)
{
if (tx_path)
return skb->ip_summed != CHECKSUM_PARTIAL;
else
return skb->ip_summed == CHECKSUM_NONE;
}

/**
* __skb_gso_segment - Perform segmentation on skb.
* @skb: buffer to segment
* @features: features for the output path (see dev->features)
* @tx_path: whether it is called in TX path
*
* This function segments the given skb and returns a list of segments.
*
* It may return NULL if the skb requires no segmentation. This is
* only possible when GSO is used for verifying header integrity.
*/
struct sk_buff *__skb_gso_segment(struct sk_buff *skb,
netdev_features_t features, bool tx_path)
{
if (unlikely(skb_needs_check(skb, tx_path))) {
int err;

skb_warn_bad_offload(skb);

if (skb_header_cloned(skb) &&
(err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC)))
return ERR_PTR(err);
}

SKB_GSO_CB(skb)->mac_offset = skb_headroom(skb);
skb_reset_mac_header(skb);
skb_reset_mac_len(skb);

return skb_mac_gso_segment(skb, features);
}
EXPORT_SYMBOL(__skb_gso_segment);

/* Take action when hardware reception checksum errors are detected. */
Expand Down
1 change: 1 addition & 0 deletions trunk/net/core/ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ static const char netdev_features_strings[NETDEV_FEATURE_COUNT][ETH_GSTRING_LEN]
[NETIF_F_TSO_ECN_BIT] = "tx-tcp-ecn-segmentation",
[NETIF_F_TSO6_BIT] = "tx-tcp6-segmentation",
[NETIF_F_FSO_BIT] = "tx-fcoe-segmentation",
[NETIF_F_GSO_GRE_BIT] = "tx-gre-segmentation",

[NETIF_F_FCOE_CRC_BIT] = "tx-checksum-fcoe-crc",
[NETIF_F_SCTP_CSUM_BIT] = "tx-checksum-sctp",
Expand Down
6 changes: 5 additions & 1 deletion trunk/net/core/skbuff.c
Original file line number Diff line number Diff line change
Expand Up @@ -2738,6 +2738,7 @@ struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features)
unsigned int mss = skb_shinfo(skb)->gso_size;
unsigned int doffset = skb->data - skb_mac_header(skb);
unsigned int offset = doffset;
unsigned int tnl_hlen = skb_tnl_header_len(skb);
unsigned int headroom;
unsigned int len;
int sg = !!(features & NETIF_F_SG);
Expand Down Expand Up @@ -2814,7 +2815,10 @@ struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features)
skb_set_network_header(nskb, skb->mac_len);
nskb->transport_header = (nskb->network_header +
skb_network_header_len(skb));
skb_copy_from_linear_data(skb, nskb->data, doffset);

skb_copy_from_linear_data_offset(skb, -tnl_hlen,
nskb->data - tnl_hlen,
doffset + tnl_hlen);

if (fskb != skb_shinfo(skb)->frag_list)
continue;
Expand Down
1 change: 1 addition & 0 deletions trunk/net/ipv4/af_inet.c
Original file line number Diff line number Diff line change
Expand Up @@ -1287,6 +1287,7 @@ static struct sk_buff *inet_gso_segment(struct sk_buff *skb,
SKB_GSO_UDP |
SKB_GSO_DODGY |
SKB_GSO_TCP_ECN |
SKB_GSO_GRE |
0)))
goto out;

Expand Down
3 changes: 1 addition & 2 deletions trunk/net/ipv4/ah4.c
Original file line number Diff line number Diff line change
Expand Up @@ -321,8 +321,7 @@ static int ah_input(struct xfrm_state *x, struct sk_buff *skb)

/* We are going to _remove_ AH header to keep sockets happy,
* so... Later this can change. */
if (skb_cloned(skb) &&
pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
if (skb_unclone(skb, GFP_ATOMIC))
goto out;

skb->ip_summed = CHECKSUM_NONE;
Expand Down
Loading

0 comments on commit e18d12b

Please sign in to comment.