Commit 94956eed authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (47 commits)
  forcedeth: fix a few sparse warnings (variable shadowing)
  forcedeth: Improve stats counters
  forcedeth: remove unneeded stats updates
  forcedeth: Acknowledge only interrupts that are being processed
  forcedeth: fix race when unloading module
  MAINTAINERS/rds: update maintainer
  wanrouter: Remove kernel_lock annotations
  usbnet: fix oops in usbnet_start_xmit
  ixgbe: Fix compile for kernel without CONFIG_PCI_IOV defined
  etherh: Add MAINTAINERS entry for etherh
  bonding: comparing a u8 with -1 is always false
  sky2: fix regression on Yukon Optima
  netlink: clarify attribute length check documentation
  netlink: validate NLA_MSECS length
  i825xx:xscale:8390:freescale: Fix Kconfig dependancies
  macvlan: receive multicast with local address
  tg3: Update version to 3.121
  tg3: Eliminate timer race with reset_task
  tg3: Schedule at most one tg3_reset_task run
  tg3: Obtain PCI function number from device
  ...
parents 50e69630 e45a6187
...@@ -1032,6 +1032,7 @@ F: arch/arm/include/asm/hardware/ioc.h ...@@ -1032,6 +1032,7 @@ F: arch/arm/include/asm/hardware/ioc.h
F: arch/arm/include/asm/hardware/iomd.h F: arch/arm/include/asm/hardware/iomd.h
F: arch/arm/include/asm/hardware/memc.h F: arch/arm/include/asm/hardware/memc.h
F: arch/arm/mach-rpc/ F: arch/arm/mach-rpc/
F: drivers/net/ethernet/8390/etherh.c
F: drivers/net/ethernet/i825xx/ether1* F: drivers/net/ethernet/i825xx/ether1*
F: drivers/net/ethernet/seeq/ether3* F: drivers/net/ethernet/seeq/ether3*
F: drivers/scsi/arm/ F: drivers/scsi/arm/
...@@ -5470,7 +5471,7 @@ S: Maintained ...@@ -5470,7 +5471,7 @@ S: Maintained
F: drivers/net/ethernet/rdc/r6040.c F: drivers/net/ethernet/rdc/r6040.c
RDS - RELIABLE DATAGRAM SOCKETS RDS - RELIABLE DATAGRAM SOCKETS
M: Andy Grover <andy.grover@oracle.com> M: Venkat Venkatsubra <venkat.x.venkatsubra@oracle.com>
L: rds-devel@oss.oracle.com (moderated for non-subscribers) L: rds-devel@oss.oracle.com (moderated for non-subscribers)
S: Supported S: Supported
F: net/rds/ F: net/rds/
......
...@@ -105,7 +105,7 @@ static int ath3k_load_firmware(struct usb_device *udev, ...@@ -105,7 +105,7 @@ static int ath3k_load_firmware(struct usb_device *udev,
pipe = usb_sndctrlpipe(udev, 0); pipe = usb_sndctrlpipe(udev, 0);
send_buf = kmalloc(BULK_SIZE, GFP_ATOMIC); send_buf = kmalloc(BULK_SIZE, GFP_KERNEL);
if (!send_buf) { if (!send_buf) {
BT_ERR("Can't allocate memory chunk for firmware"); BT_ERR("Can't allocate memory chunk for firmware");
return -ENOMEM; return -ENOMEM;
...@@ -176,7 +176,7 @@ static int ath3k_load_fwfile(struct usb_device *udev, ...@@ -176,7 +176,7 @@ static int ath3k_load_fwfile(struct usb_device *udev,
count = firmware->size; count = firmware->size;
send_buf = kmalloc(BULK_SIZE, GFP_ATOMIC); send_buf = kmalloc(BULK_SIZE, GFP_KERNEL);
if (!send_buf) { if (!send_buf) {
BT_ERR("Can't allocate memory chunk for firmware"); BT_ERR("Can't allocate memory chunk for firmware");
return -ENOMEM; return -ENOMEM;
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/atomic.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/slab.h> #include <linux/slab.h>
...@@ -65,6 +66,7 @@ struct bcm203x_data { ...@@ -65,6 +66,7 @@ struct bcm203x_data {
unsigned long state; unsigned long state;
struct work_struct work; struct work_struct work;
atomic_t shutdown;
struct urb *urb; struct urb *urb;
unsigned char *buffer; unsigned char *buffer;
...@@ -97,6 +99,7 @@ static void bcm203x_complete(struct urb *urb) ...@@ -97,6 +99,7 @@ static void bcm203x_complete(struct urb *urb)
data->state = BCM203X_SELECT_MEMORY; data->state = BCM203X_SELECT_MEMORY;
/* use workqueue to have a small delay */
schedule_work(&data->work); schedule_work(&data->work);
break; break;
...@@ -155,7 +158,10 @@ static void bcm203x_work(struct work_struct *work) ...@@ -155,7 +158,10 @@ static void bcm203x_work(struct work_struct *work)
struct bcm203x_data *data = struct bcm203x_data *data =
container_of(work, struct bcm203x_data, work); container_of(work, struct bcm203x_data, work);
if (usb_submit_urb(data->urb, GFP_ATOMIC) < 0) if (atomic_read(&data->shutdown))
return;
if (usb_submit_urb(data->urb, GFP_KERNEL) < 0)
BT_ERR("Can't submit URB"); BT_ERR("Can't submit URB");
} }
...@@ -243,6 +249,7 @@ static int bcm203x_probe(struct usb_interface *intf, const struct usb_device_id ...@@ -243,6 +249,7 @@ static int bcm203x_probe(struct usb_interface *intf, const struct usb_device_id
usb_set_intfdata(intf, data); usb_set_intfdata(intf, data);
/* use workqueue to have a small delay */
schedule_work(&data->work); schedule_work(&data->work);
return 0; return 0;
...@@ -254,6 +261,9 @@ static void bcm203x_disconnect(struct usb_interface *intf) ...@@ -254,6 +261,9 @@ static void bcm203x_disconnect(struct usb_interface *intf)
BT_DBG("intf %p", intf); BT_DBG("intf %p", intf);
atomic_inc(&data->shutdown);
cancel_work_sync(&data->work);
usb_kill_urb(data->urb); usb_kill_urb(data->urb);
usb_set_intfdata(intf, NULL); usb_set_intfdata(intf, NULL);
......
...@@ -568,22 +568,23 @@ static int bfusb_load_firmware(struct bfusb_data *data, ...@@ -568,22 +568,23 @@ static int bfusb_load_firmware(struct bfusb_data *data,
BT_INFO("BlueFRITZ! USB loading firmware"); BT_INFO("BlueFRITZ! USB loading firmware");
buf = kmalloc(BFUSB_MAX_BLOCK_SIZE + 3, GFP_KERNEL);
if (!buf) {
BT_ERR("Can't allocate memory chunk for firmware");
return -ENOMEM;
}
pipe = usb_sndctrlpipe(data->udev, 0); pipe = usb_sndctrlpipe(data->udev, 0);
if (usb_control_msg(data->udev, pipe, USB_REQ_SET_CONFIGURATION, if (usb_control_msg(data->udev, pipe, USB_REQ_SET_CONFIGURATION,
0, 1, 0, NULL, 0, USB_CTRL_SET_TIMEOUT) < 0) { 0, 1, 0, NULL, 0, USB_CTRL_SET_TIMEOUT) < 0) {
BT_ERR("Can't change to loading configuration"); BT_ERR("Can't change to loading configuration");
kfree(buf);
return -EBUSY; return -EBUSY;
} }
data->udev->toggle[0] = data->udev->toggle[1] = 0; data->udev->toggle[0] = data->udev->toggle[1] = 0;
buf = kmalloc(BFUSB_MAX_BLOCK_SIZE + 3, GFP_ATOMIC);
if (!buf) {
BT_ERR("Can't allocate memory chunk for firmware");
return -ENOMEM;
}
pipe = usb_sndbulkpipe(data->udev, data->bulk_out_ep); pipe = usb_sndbulkpipe(data->udev, data->bulk_out_ep);
while (count) { while (count) {
......
...@@ -560,8 +560,8 @@ static int bond_update_speed_duplex(struct slave *slave) ...@@ -560,8 +560,8 @@ static int bond_update_speed_duplex(struct slave *slave)
u32 slave_speed; u32 slave_speed;
int res; int res;
slave->speed = -1; slave->speed = SPEED_UNKNOWN;
slave->duplex = -1; slave->duplex = DUPLEX_UNKNOWN;
res = __ethtool_get_settings(slave_dev, &ecmd); res = __ethtool_get_settings(slave_dev, &ecmd);
if (res < 0) if (res < 0)
......
...@@ -158,12 +158,12 @@ static void bond_info_show_slave(struct seq_file *seq, ...@@ -158,12 +158,12 @@ static void bond_info_show_slave(struct seq_file *seq,
seq_printf(seq, "\nSlave Interface: %s\n", slave->dev->name); seq_printf(seq, "\nSlave Interface: %s\n", slave->dev->name);
seq_printf(seq, "MII Status: %s\n", seq_printf(seq, "MII Status: %s\n",
(slave->link == BOND_LINK_UP) ? "up" : "down"); (slave->link == BOND_LINK_UP) ? "up" : "down");
if (slave->speed == -1) if (slave->speed == SPEED_UNKNOWN)
seq_printf(seq, "Speed: %s\n", "Unknown"); seq_printf(seq, "Speed: %s\n", "Unknown");
else else
seq_printf(seq, "Speed: %d Mbps\n", slave->speed); seq_printf(seq, "Speed: %d Mbps\n", slave->speed);
if (slave->duplex == -1) if (slave->duplex == DUPLEX_UNKNOWN)
seq_printf(seq, "Duplex: %s\n", "Unknown"); seq_printf(seq, "Duplex: %s\n", "Unknown");
else else
seq_printf(seq, "Duplex: %s\n", slave->duplex ? "full" : "half"); seq_printf(seq, "Duplex: %s\n", slave->duplex ? "full" : "half");
......
...@@ -89,10 +89,10 @@ static inline void _tg3_flag_clear(enum TG3_FLAGS flag, unsigned long *bits) ...@@ -89,10 +89,10 @@ static inline void _tg3_flag_clear(enum TG3_FLAGS flag, unsigned long *bits)
#define DRV_MODULE_NAME "tg3" #define DRV_MODULE_NAME "tg3"
#define TG3_MAJ_NUM 3 #define TG3_MAJ_NUM 3
#define TG3_MIN_NUM 120 #define TG3_MIN_NUM 121
#define DRV_MODULE_VERSION \ #define DRV_MODULE_VERSION \
__stringify(TG3_MAJ_NUM) "." __stringify(TG3_MIN_NUM) __stringify(TG3_MAJ_NUM) "." __stringify(TG3_MIN_NUM)
#define DRV_MODULE_RELDATE "August 18, 2011" #define DRV_MODULE_RELDATE "November 2, 2011"
#define RESET_KIND_SHUTDOWN 0 #define RESET_KIND_SHUTDOWN 0
#define RESET_KIND_INIT 1 #define RESET_KIND_INIT 1
...@@ -628,19 +628,23 @@ static void tg3_ape_lock_init(struct tg3 *tp) ...@@ -628,19 +628,23 @@ static void tg3_ape_lock_init(struct tg3 *tp)
regbase = TG3_APE_PER_LOCK_GRANT; regbase = TG3_APE_PER_LOCK_GRANT;
/* Make sure the driver hasn't any stale locks. */ /* Make sure the driver hasn't any stale locks. */
for (i = 0; i < 8; i++) { for (i = TG3_APE_LOCK_PHY0; i <= TG3_APE_LOCK_GPIO; i++) {
if (i == TG3_APE_LOCK_GPIO) switch (i) {
continue; case TG3_APE_LOCK_PHY0:
tg3_ape_write32(tp, regbase + 4 * i, APE_LOCK_GRANT_DRIVER); case TG3_APE_LOCK_PHY1:
case TG3_APE_LOCK_PHY2:
case TG3_APE_LOCK_PHY3:
bit = APE_LOCK_GRANT_DRIVER;
break;
default:
if (!tp->pci_fn)
bit = APE_LOCK_GRANT_DRIVER;
else
bit = 1 << tp->pci_fn;
}
tg3_ape_write32(tp, regbase + 4 * i, bit);
} }
/* Clear the correct bit of the GPIO lock too. */
if (!tp->pci_fn)
bit = APE_LOCK_GRANT_DRIVER;
else
bit = 1 << tp->pci_fn;
tg3_ape_write32(tp, regbase + 4 * TG3_APE_LOCK_GPIO, bit);
} }
static int tg3_ape_lock(struct tg3 *tp, int locknum) static int tg3_ape_lock(struct tg3 *tp, int locknum)
...@@ -658,6 +662,10 @@ static int tg3_ape_lock(struct tg3 *tp, int locknum) ...@@ -658,6 +662,10 @@ static int tg3_ape_lock(struct tg3 *tp, int locknum)
return 0; return 0;
case TG3_APE_LOCK_GRC: case TG3_APE_LOCK_GRC:
case TG3_APE_LOCK_MEM: case TG3_APE_LOCK_MEM:
if (!tp->pci_fn)
bit = APE_LOCK_REQ_DRIVER;
else
bit = 1 << tp->pci_fn;
break; break;
default: default:
return -EINVAL; return -EINVAL;
...@@ -673,11 +681,6 @@ static int tg3_ape_lock(struct tg3 *tp, int locknum) ...@@ -673,11 +681,6 @@ static int tg3_ape_lock(struct tg3 *tp, int locknum)
off = 4 * locknum; off = 4 * locknum;
if (locknum != TG3_APE_LOCK_GPIO || !tp->pci_fn)
bit = APE_LOCK_REQ_DRIVER;
else
bit = 1 << tp->pci_fn;
tg3_ape_write32(tp, req + off, bit); tg3_ape_write32(tp, req + off, bit);
/* Wait for up to 1 millisecond to acquire lock. */ /* Wait for up to 1 millisecond to acquire lock. */
...@@ -710,6 +713,10 @@ static void tg3_ape_unlock(struct tg3 *tp, int locknum) ...@@ -710,6 +713,10 @@ static void tg3_ape_unlock(struct tg3 *tp, int locknum)
return; return;
case TG3_APE_LOCK_GRC: case TG3_APE_LOCK_GRC:
case TG3_APE_LOCK_MEM: case TG3_APE_LOCK_MEM:
if (!tp->pci_fn)
bit = APE_LOCK_GRANT_DRIVER;
else
bit = 1 << tp->pci_fn;
break; break;
default: default:
return; return;
...@@ -720,11 +727,6 @@ static void tg3_ape_unlock(struct tg3 *tp, int locknum) ...@@ -720,11 +727,6 @@ static void tg3_ape_unlock(struct tg3 *tp, int locknum)
else else
gnt = TG3_APE_PER_LOCK_GRANT; gnt = TG3_APE_PER_LOCK_GRANT;
if (locknum != TG3_APE_LOCK_GPIO || !tp->pci_fn)
bit = APE_LOCK_GRANT_DRIVER;
else
bit = 1 << tp->pci_fn;
tg3_ape_write32(tp, gnt + 4 * locknum, bit); tg3_ape_write32(tp, gnt + 4 * locknum, bit);
} }
...@@ -5927,6 +5929,18 @@ static int tg3_poll_work(struct tg3_napi *tnapi, int work_done, int budget) ...@@ -5927,6 +5929,18 @@ static int tg3_poll_work(struct tg3_napi *tnapi, int work_done, int budget)
return work_done; return work_done;
} }
static inline void tg3_reset_task_schedule(struct tg3 *tp)
{
if (!test_and_set_bit(TG3_FLAG_RESET_TASK_PENDING, tp->tg3_flags))
schedule_work(&tp->reset_task);
}
static inline void tg3_reset_task_cancel(struct tg3 *tp)
{
cancel_work_sync(&tp->reset_task);
tg3_flag_clear(tp, RESET_TASK_PENDING);
}
static int tg3_poll_msix(struct napi_struct *napi, int budget) static int tg3_poll_msix(struct napi_struct *napi, int budget)
{ {
struct tg3_napi *tnapi = container_of(napi, struct tg3_napi, napi); struct tg3_napi *tnapi = container_of(napi, struct tg3_napi, napi);
...@@ -5967,7 +5981,7 @@ static int tg3_poll_msix(struct napi_struct *napi, int budget) ...@@ -5967,7 +5981,7 @@ static int tg3_poll_msix(struct napi_struct *napi, int budget)
tx_recovery: tx_recovery:
/* work_done is guaranteed to be less than budget. */ /* work_done is guaranteed to be less than budget. */
napi_complete(napi); napi_complete(napi);
schedule_work(&tp->reset_task); tg3_reset_task_schedule(tp);
return work_done; return work_done;
} }
...@@ -6002,7 +6016,7 @@ static void tg3_process_error(struct tg3 *tp) ...@@ -6002,7 +6016,7 @@ static void tg3_process_error(struct tg3 *tp)
tg3_dump_state(tp); tg3_dump_state(tp);
tg3_flag_set(tp, ERROR_PROCESSED); tg3_flag_set(tp, ERROR_PROCESSED);
schedule_work(&tp->reset_task); tg3_reset_task_schedule(tp);
} }
static int tg3_poll(struct napi_struct *napi, int budget) static int tg3_poll(struct napi_struct *napi, int budget)
...@@ -6049,7 +6063,7 @@ static int tg3_poll(struct napi_struct *napi, int budget) ...@@ -6049,7 +6063,7 @@ static int tg3_poll(struct napi_struct *napi, int budget)
tx_recovery: tx_recovery:
/* work_done is guaranteed to be less than budget. */ /* work_done is guaranteed to be less than budget. */
napi_complete(napi); napi_complete(napi);
schedule_work(&tp->reset_task); tg3_reset_task_schedule(tp);
return work_done; return work_done;
} }
...@@ -6338,11 +6352,11 @@ static void tg3_reset_task(struct work_struct *work) ...@@ -6338,11 +6352,11 @@ static void tg3_reset_task(struct work_struct *work)
{ {
struct tg3 *tp = container_of(work, struct tg3, reset_task); struct tg3 *tp = container_of(work, struct tg3, reset_task);
int err; int err;
unsigned int restart_timer;
tg3_full_lock(tp, 0); tg3_full_lock(tp, 0);
if (!netif_running(tp->dev)) { if (!netif_running(tp->dev)) {
tg3_flag_clear(tp, RESET_TASK_PENDING);
tg3_full_unlock(tp); tg3_full_unlock(tp);
return; return;
} }
...@@ -6355,9 +6369,6 @@ static void tg3_reset_task(struct work_struct *work) ...@@ -6355,9 +6369,6 @@ static void tg3_reset_task(struct work_struct *work)
tg3_full_lock(tp, 1); tg3_full_lock(tp, 1);
restart_timer = tg3_flag(tp, RESTART_TIMER);
tg3_flag_clear(tp, RESTART_TIMER);
if (tg3_flag(tp, TX_RECOVERY_PENDING)) { if (tg3_flag(tp, TX_RECOVERY_PENDING)) {
tp->write32_tx_mbox = tg3_write32_tx_mbox; tp->write32_tx_mbox = tg3_write32_tx_mbox;
tp->write32_rx_mbox = tg3_write_flush_reg32; tp->write32_rx_mbox = tg3_write_flush_reg32;
...@@ -6372,14 +6383,13 @@ static void tg3_reset_task(struct work_struct *work) ...@@ -6372,14 +6383,13 @@ static void tg3_reset_task(struct work_struct *work)
tg3_netif_start(tp); tg3_netif_start(tp);
if (restart_timer)
mod_timer(&tp->timer, jiffies + 1);
out: out:
tg3_full_unlock(tp); tg3_full_unlock(tp);
if (!err) if (!err)
tg3_phy_start(tp); tg3_phy_start(tp);
tg3_flag_clear(tp, RESET_TASK_PENDING);
} }
static void tg3_tx_timeout(struct net_device *dev) static void tg3_tx_timeout(struct net_device *dev)
...@@ -6391,7 +6401,7 @@ static void tg3_tx_timeout(struct net_device *dev) ...@@ -6391,7 +6401,7 @@ static void tg3_tx_timeout(struct net_device *dev)
tg3_dump_state(tp); tg3_dump_state(tp);
} }
schedule_work(&tp->reset_task); tg3_reset_task_schedule(tp);
} }
/* Test for DMA buffers crossing any 4GB boundaries: 4G, 8G, etc */ /* Test for DMA buffers crossing any 4GB boundaries: 4G, 8G, etc */
...@@ -6442,31 +6452,26 @@ static bool tg3_tx_frag_set(struct tg3_napi *tnapi, u32 *entry, u32 *budget, ...@@ -6442,31 +6452,26 @@ static bool tg3_tx_frag_set(struct tg3_napi *tnapi, u32 *entry, u32 *budget,
hwbug = 1; hwbug = 1;
if (tg3_flag(tp, 4K_FIFO_LIMIT)) { if (tg3_flag(tp, 4K_FIFO_LIMIT)) {
u32 prvidx = *entry;
u32 tmp_flag = flags & ~TXD_FLAG_END; u32 tmp_flag = flags & ~TXD_FLAG_END;
while (len > TG3_TX_BD_DMA_MAX) { while (len > TG3_TX_BD_DMA_MAX && *budget) {
u32 frag_len = TG3_TX_BD_DMA_MAX; u32 frag_len = TG3_TX_BD_DMA_MAX;
len -= TG3_TX_BD_DMA_MAX; len -= TG3_TX_BD_DMA_MAX;
if (len) { /* Avoid the 8byte DMA problem */
tnapi->tx_buffers[*entry].fragmented = true; if (len <= 8) {
/* Avoid the 8byte DMA problem */ len += TG3_TX_BD_DMA_MAX / 2;
if (len <= 8) { frag_len = TG3_TX_BD_DMA_MAX / 2;
len += TG3_TX_BD_DMA_MAX / 2;
frag_len = TG3_TX_BD_DMA_MAX / 2;
}
} else
tmp_flag = flags;
if (*budget) {
tg3_tx_set_bd(&tnapi->tx_ring[*entry], map,
frag_len, tmp_flag, mss, vlan);
(*budget)--;
*entry = NEXT_TX(*entry);
} else {
hwbug = 1;
break;
} }
tnapi->tx_buffers[*entry].fragmented = true;
tg3_tx_set_bd(&tnapi->tx_ring[*entry], map,
frag_len, tmp_flag, mss, vlan);
*budget -= 1;
prvidx = *entry;
*entry = NEXT_TX(*entry);
map += frag_len; map += frag_len;
} }
...@@ -6474,10 +6479,11 @@ static bool tg3_tx_frag_set(struct tg3_napi *tnapi, u32 *entry, u32 *budget, ...@@ -6474,10 +6479,11 @@ static bool tg3_tx_frag_set(struct tg3_napi *tnapi, u32 *entry, u32 *budget,
if (*budget) { if (*budget) {
tg3_tx_set_bd(&tnapi->tx_ring[*entry], map, tg3_tx_set_bd(&tnapi->tx_ring[*entry], map,
len, flags, mss, vlan); len, flags, mss, vlan);
(*budget)--; *budget -= 1;
*entry = NEXT_TX(*entry); *entry = NEXT_TX(*entry);
} else { } else {
hwbug = 1; hwbug = 1;
tnapi->tx_buffers[prvidx].fragmented = false;
} }
} }
} else { } else {
...@@ -6509,7 +6515,7 @@ static void tg3_tx_skb_unmap(struct tg3_napi *tnapi, u32 entry, int last) ...@@ -6509,7 +6515,7 @@ static void tg3_tx_skb_unmap(struct tg3_napi *tnapi, u32 entry, int last)
txb = &tnapi->tx_buffers[entry]; txb = &tnapi->tx_buffers[entry];
} }
for (i = 0; i < last; i++) { for (i = 0; i <= last; i++) {
const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; const skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
entry = NEXT_TX(entry); entry = NEXT_TX(entry);
...@@ -6559,6 +6565,8 @@ static int tigon3_dma_hwbug_workaround(struct tg3_napi *tnapi, ...@@ -6559,6 +6565,8 @@ static int tigon3_dma_hwbug_workaround(struct tg3_napi *tnapi,
dev_kfree_skb(new_skb); dev_kfree_skb(new_skb);
ret = -1; ret = -1;
} else { } else {
u32 save_entry = *entry;
base_flags |= TXD_FLAG_END; base_flags |= TXD_FLAG_END;
tnapi->tx_buffers[*entry].skb = new_skb; tnapi->tx_buffers[*entry].skb = new_skb;
...@@ -6568,7 +6576,7 @@ static int tigon3_dma_hwbug_workaround(struct tg3_napi *tnapi, ...@@ -6568,7 +6576,7 @@ static int tigon3_dma_hwbug_workaround(struct tg3_napi *tnapi,
if (tg3_tx_frag_set(tnapi, entry, budget, new_addr, if (tg3_tx_frag_set(tnapi, entry, budget, new_addr,
new_skb->len, base_flags, new_skb->len, base_flags,
mss, vlan)) { mss, vlan)) {
tg3_tx_skb_unmap(tnapi, *entry, 0); tg3_tx_skb_unmap(tnapi, save_entry, -1);
dev_kfree_skb(new_skb); dev_kfree_skb(new_skb);
ret = -1; ret = -1;
} }
...@@ -6758,11 +6766,10 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -6758,11 +6766,10 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (tg3_tx_frag_set(tnapi, &entry, &budget, mapping, len, base_flags | if (tg3_tx_frag_set(tnapi, &entry, &budget, mapping, len, base_flags |
((skb_shinfo(skb)->nr_frags == 0) ? TXD_FLAG_END : 0), ((skb_shinfo(skb)->nr_frags == 0) ? TXD_FLAG_END : 0),
mss, vlan)) mss, vlan)) {
would_hit_hwbug = 1; would_hit_hwbug = 1;
/* Now loop through additional data fragments, and queue them. */ /* Now loop through additional data fragments, and queue them. */
if (skb_shinfo(skb)->nr_frags > 0) { } else if (skb_shinfo(skb)->nr_frags > 0) {
u32 tmp_mss = mss; u32 tmp_mss = mss;
if (!tg3_flag(tp, HW_TSO_1) &&