mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 02:32:09 -04:00
Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
This commit is contained in:
commit
21f130a237
16 changed files with 380 additions and 232 deletions
|
|
@ -67,8 +67,8 @@
|
|||
|
||||
#define DRV_MODULE_NAME "tg3"
|
||||
#define PFX DRV_MODULE_NAME ": "
|
||||
#define DRV_MODULE_VERSION "3.39"
|
||||
#define DRV_MODULE_RELDATE "September 5, 2005"
|
||||
#define DRV_MODULE_VERSION "3.40"
|
||||
#define DRV_MODULE_RELDATE "September 15, 2005"
|
||||
|
||||
#define TG3_DEF_MAC_MODE 0
|
||||
#define TG3_DEF_RX_MODE 0
|
||||
|
|
@ -3442,31 +3442,47 @@ static void tg3_tx_timeout(struct net_device *dev)
|
|||
schedule_work(&tp->reset_task);
|
||||
}
|
||||
|
||||
/* Test for DMA buffers crossing any 4GB boundaries: 4G, 8G, etc */
|
||||
static inline int tg3_4g_overflow_test(dma_addr_t mapping, int len)
|
||||
{
|
||||
u32 base = (u32) mapping & 0xffffffff;
|
||||
|
||||
return ((base > 0xffffdcc0) &&
|
||||
(base + len + 8 < base));
|
||||
}
|
||||
|
||||
static void tg3_set_txd(struct tg3 *, int, dma_addr_t, int, u32, u32);
|
||||
|
||||
static int tigon3_4gb_hwbug_workaround(struct tg3 *tp, struct sk_buff *skb,
|
||||
u32 guilty_entry, int guilty_len,
|
||||
u32 last_plus_one, u32 *start, u32 mss)
|
||||
u32 last_plus_one, u32 *start,
|
||||
u32 base_flags, u32 mss)
|
||||
{
|
||||
struct sk_buff *new_skb = skb_copy(skb, GFP_ATOMIC);
|
||||
dma_addr_t new_addr;
|
||||
dma_addr_t new_addr = 0;
|
||||
u32 entry = *start;
|
||||
int i;
|
||||
int i, ret = 0;
|
||||
|
||||
if (!new_skb) {
|
||||
dev_kfree_skb(skb);
|
||||
return -1;
|
||||
ret = -1;
|
||||
} else {
|
||||
/* New SKB is guaranteed to be linear. */
|
||||
entry = *start;
|
||||
new_addr = pci_map_single(tp->pdev, new_skb->data, new_skb->len,
|
||||
PCI_DMA_TODEVICE);
|
||||
/* Make sure new skb does not cross any 4G boundaries.
|
||||
* Drop the packet if it does.
|
||||
*/
|
||||
if (tg3_4g_overflow_test(new_addr, new_skb->len)) {
|
||||
ret = -1;
|
||||
dev_kfree_skb(new_skb);
|
||||
new_skb = NULL;
|
||||
} else {
|
||||
tg3_set_txd(tp, entry, new_addr, new_skb->len,
|
||||
base_flags, 1 | (mss << 1));
|
||||
*start = NEXT_TX(entry);
|
||||
}
|
||||
}
|
||||
|
||||
/* New SKB is guaranteed to be linear. */
|
||||
entry = *start;
|
||||
new_addr = pci_map_single(tp->pdev, new_skb->data, new_skb->len,
|
||||
PCI_DMA_TODEVICE);
|
||||
tg3_set_txd(tp, entry, new_addr, new_skb->len,
|
||||
(skb->ip_summed == CHECKSUM_HW) ?
|
||||
TXD_FLAG_TCPUDP_CSUM : 0, 1 | (mss << 1));
|
||||
*start = NEXT_TX(entry);
|
||||
|
||||
/* Now clean up the sw ring entries. */
|
||||
i = 0;
|
||||
while (entry != last_plus_one) {
|
||||
|
|
@ -3491,7 +3507,7 @@ static int tigon3_4gb_hwbug_workaround(struct tg3 *tp, struct sk_buff *skb,
|
|||
|
||||
dev_kfree_skb(skb);
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void tg3_set_txd(struct tg3 *tp, int entry,
|
||||
|
|
@ -3517,19 +3533,10 @@ static void tg3_set_txd(struct tg3 *tp, int entry,
|
|||
txd->vlan_tag = vlan_tag << TXD_VLAN_TAG_SHIFT;
|
||||
}
|
||||
|
||||
static inline int tg3_4g_overflow_test(dma_addr_t mapping, int len)
|
||||
{
|
||||
u32 base = (u32) mapping & 0xffffffff;
|
||||
|
||||
return ((base > 0xffffdcc0) &&
|
||||
(base + len + 8 < base));
|
||||
}
|
||||
|
||||
static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
{
|
||||
struct tg3 *tp = netdev_priv(dev);
|
||||
dma_addr_t mapping;
|
||||
unsigned int i;
|
||||
u32 len, entry, base_flags, mss;
|
||||
int would_hit_hwbug;
|
||||
|
||||
|
|
@ -3624,7 +3631,7 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
would_hit_hwbug = 0;
|
||||
|
||||
if (tg3_4g_overflow_test(mapping, len))
|
||||
would_hit_hwbug = entry + 1;
|
||||
would_hit_hwbug = 1;
|
||||
|
||||
tg3_set_txd(tp, entry, mapping, len, base_flags,
|
||||
(skb_shinfo(skb)->nr_frags == 0) | (mss << 1));
|
||||
|
|
@ -3648,12 +3655,8 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
tp->tx_buffers[entry].skb = NULL;
|
||||
pci_unmap_addr_set(&tp->tx_buffers[entry], mapping, mapping);
|
||||
|
||||
if (tg3_4g_overflow_test(mapping, len)) {
|
||||
/* Only one should match. */
|
||||
if (would_hit_hwbug)
|
||||
BUG();
|
||||
would_hit_hwbug = entry + 1;
|
||||
}
|
||||
if (tg3_4g_overflow_test(mapping, len))
|
||||
would_hit_hwbug = 1;
|
||||
|
||||
if (tp->tg3_flags2 & TG3_FLG2_HW_TSO)
|
||||
tg3_set_txd(tp, entry, mapping, len,
|
||||
|
|
@ -3669,34 +3672,15 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
if (would_hit_hwbug) {
|
||||
u32 last_plus_one = entry;
|
||||
u32 start;
|
||||
unsigned int len = 0;
|
||||
|
||||
would_hit_hwbug -= 1;
|
||||
entry = entry - 1 - skb_shinfo(skb)->nr_frags;
|
||||
entry &= (TG3_TX_RING_SIZE - 1);
|
||||
start = entry;
|
||||
i = 0;
|
||||
while (entry != last_plus_one) {
|
||||
if (i == 0)
|
||||
len = skb_headlen(skb);
|
||||
else
|
||||
len = skb_shinfo(skb)->frags[i-1].size;
|
||||
|
||||
if (entry == would_hit_hwbug)
|
||||
break;
|
||||
|
||||
i++;
|
||||
entry = NEXT_TX(entry);
|
||||
|
||||
}
|
||||
start = entry - 1 - skb_shinfo(skb)->nr_frags;
|
||||
start &= (TG3_TX_RING_SIZE - 1);
|
||||
|
||||
/* If the workaround fails due to memory/mapping
|
||||
* failure, silently drop this packet.
|
||||
*/
|
||||
if (tigon3_4gb_hwbug_workaround(tp, skb,
|
||||
entry, len,
|
||||
last_plus_one,
|
||||
&start, mss))
|
||||
if (tigon3_4gb_hwbug_workaround(tp, skb, last_plus_one,
|
||||
&start, base_flags, mss))
|
||||
goto out_unlock;
|
||||
|
||||
entry = start;
|
||||
|
|
@ -9271,6 +9255,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
|
|||
static struct pci_device_id write_reorder_chipsets[] = {
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_AMD,
|
||||
PCI_DEVICE_ID_AMD_FE_GATE_700C) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_AMD,
|
||||
PCI_DEVICE_ID_AMD_K8_NB) },
|
||||
{ },
|
||||
};
|
||||
u32 misc_ctrl_reg;
|
||||
|
|
@ -9285,7 +9271,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
|
|||
tp->tg3_flags2 |= TG3_FLG2_SUN_570X;
|
||||
#endif
|
||||
|
||||
/* If we have an AMD 762 chipset, write
|
||||
/* If we have an AMD 762 or K8 chipset, write
|
||||
* reordering to the mailbox registers done by the host
|
||||
* controller can cause major troubles. We read back from
|
||||
* every mailbox register write to force the writes to be
|
||||
|
|
@ -9532,7 +9518,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
|
|||
tp->write32_rx_mbox = tg3_write_indirect_mbox;
|
||||
|
||||
iounmap(tp->regs);
|
||||
tp->regs = 0;
|
||||
tp->regs = NULL;
|
||||
|
||||
pci_read_config_word(tp->pdev, PCI_COMMAND, &pci_cmd);
|
||||
pci_cmd &= ~PCI_COMMAND_MEMORY;
|
||||
|
|
@ -10680,7 +10666,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
|
|||
err_out_iounmap:
|
||||
if (tp->regs) {
|
||||
iounmap(tp->regs);
|
||||
tp->regs = 0;
|
||||
tp->regs = NULL;
|
||||
}
|
||||
|
||||
err_out_free_dev:
|
||||
|
|
@ -10705,7 +10691,7 @@ static void __devexit tg3_remove_one(struct pci_dev *pdev)
|
|||
unregister_netdev(dev);
|
||||
if (tp->regs) {
|
||||
iounmap(tp->regs);
|
||||
tp->regs = 0;
|
||||
tp->regs = NULL;
|
||||
}
|
||||
free_netdev(dev);
|
||||
pci_release_regions(pdev);
|
||||
|
|
|
|||
Loading…
Reference in a new issue