aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2011-10-07 13:38:43 -0400
committerDavid S. Miller <davem@davemloft.net>2011-10-07 13:38:43 -0400
commit88c5100c28b02c4b2b2c6f6fafbbd76d90f698b9 (patch)
tree08c4399e0341f7eb0ccb24e15f2cab687275c2a4 /drivers/net/ethernet
parent8083f0fc969d9b5353061a7a6f963405057e26b1 (diff)
parent3ee72ca99288f1de95ec9c570e43f531c8799f06 (diff)
Merge branch 'master' of github.com:davem330/net
Conflicts: net/batman-adv/soft-interface.c
Diffstat (limited to 'drivers/net/ethernet')
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c1
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c16
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h12
-rw-r--r--drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c23
-rw-r--r--drivers/net/ethernet/chelsio/cxgb3/l2t.c15
-rw-r--r--drivers/net/ethernet/chelsio/cxgb3/l2t.h16
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c3
-rw-r--r--drivers/net/ethernet/ibm/ibmveth.c4
-rw-r--r--drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c56
9 files changed, 100 insertions, 46 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c
index 0b9bd551580b..51bd7485ab18 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c
@@ -2123,6 +2123,7 @@ static u8 bnx2x_dcbnl_get_cap(struct net_device *netdev, int capid, u8 *cap)
2123 break; 2123 break;
2124 case DCB_CAP_ATTR_DCBX: 2124 case DCB_CAP_ATTR_DCBX:
2125 *cap = BNX2X_DCBX_CAPS; 2125 *cap = BNX2X_DCBX_CAPS;
2126 break;
2126 default: 2127 default:
2127 rval = -EINVAL; 2128 rval = -EINVAL;
2128 break; 2129 break;
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index 28bde1610ffb..6486ab8c8fc8 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -4937,7 +4937,7 @@ static void bnx2x_init_def_sb(struct bnx2x *bp)
4937 int igu_seg_id; 4937 int igu_seg_id;
4938 int port = BP_PORT(bp); 4938 int port = BP_PORT(bp);
4939 int func = BP_FUNC(bp); 4939 int func = BP_FUNC(bp);
4940 int reg_offset; 4940 int reg_offset, reg_offset_en5;
4941 u64 section; 4941 u64 section;
4942 int index; 4942 int index;
4943 struct hc_sp_status_block_data sp_sb_data; 4943 struct hc_sp_status_block_data sp_sb_data;
@@ -4960,6 +4960,8 @@ static void bnx2x_init_def_sb(struct bnx2x *bp)
4960 4960
4961 reg_offset = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 : 4961 reg_offset = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 :
4962 MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0); 4962 MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0);
4963 reg_offset_en5 = (port ? MISC_REG_AEU_ENABLE5_FUNC_1_OUT_0 :
4964 MISC_REG_AEU_ENABLE5_FUNC_0_OUT_0);
4963 for (index = 0; index < MAX_DYNAMIC_ATTN_GRPS; index++) { 4965 for (index = 0; index < MAX_DYNAMIC_ATTN_GRPS; index++) {
4964 int sindex; 4966 int sindex;
4965 /* take care of sig[0]..sig[4] */ 4967 /* take care of sig[0]..sig[4] */
@@ -4974,7 +4976,7 @@ static void bnx2x_init_def_sb(struct bnx2x *bp)
4974 * and not 16 between the different groups 4976 * and not 16 between the different groups
4975 */ 4977 */
4976 bp->attn_group[index].sig[4] = REG_RD(bp, 4978 bp->attn_group[index].sig[4] = REG_RD(bp,
4977 reg_offset + 0x10 + 0x4*index); 4979 reg_offset_en5 + 0x4*index);
4978 else 4980 else
4979 bp->attn_group[index].sig[4] = 0; 4981 bp->attn_group[index].sig[4] = 0;
4980 } 4982 }
@@ -7619,8 +7621,11 @@ u32 bnx2x_send_unload_req(struct bnx2x *bp, int unload_mode)
7619 u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0; 7621 u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
7620 u8 *mac_addr = bp->dev->dev_addr; 7622 u8 *mac_addr = bp->dev->dev_addr;
7621 u32 val; 7623 u32 val;
7624 u16 pmc;
7625
7622 /* The mac address is written to entries 1-4 to 7626 /* The mac address is written to entries 1-4 to
7623 preserve entry 0 which is used by the PMF */ 7627 * preserve entry 0 which is used by the PMF
7628 */
7624 u8 entry = (BP_VN(bp) + 1)*8; 7629 u8 entry = (BP_VN(bp) + 1)*8;
7625 7630
7626 val = (mac_addr[0] << 8) | mac_addr[1]; 7631 val = (mac_addr[0] << 8) | mac_addr[1];
@@ -7630,6 +7635,11 @@ u32 bnx2x_send_unload_req(struct bnx2x *bp, int unload_mode)
7630 (mac_addr[4] << 8) | mac_addr[5]; 7635 (mac_addr[4] << 8) | mac_addr[5];
7631 EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH + entry + 4, val); 7636 EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH + entry + 4, val);
7632 7637
7638 /* Enable the PME and clear the status */
7639 pci_read_config_word(bp->pdev, bp->pm_cap + PCI_PM_CTRL, &pmc);
7640 pmc |= PCI_PM_CTRL_PME_ENABLE | PCI_PM_CTRL_PME_STATUS;
7641 pci_write_config_word(bp->pdev, bp->pm_cap + PCI_PM_CTRL, pmc);
7642
7633 reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_EN; 7643 reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_EN;
7634 7644
7635 } else 7645 } else
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h
index 750e8445dac4..fc7bd0f23c0b 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h
@@ -1384,6 +1384,18 @@
1384 Latched ump_tx_parity; [31] MCP Latched scpad_parity; */ 1384 Latched ump_tx_parity; [31] MCP Latched scpad_parity; */
1385#define MISC_REG_AEU_ENABLE4_PXP_0 0xa108 1385#define MISC_REG_AEU_ENABLE4_PXP_0 0xa108
1386#define MISC_REG_AEU_ENABLE4_PXP_1 0xa1a8 1386#define MISC_REG_AEU_ENABLE4_PXP_1 0xa1a8
1387/* [RW 32] fifth 32b for enabling the output for function 0 output0. Mapped
1388 * as follows: [0] PGLUE config_space; [1] PGLUE misc_flr; [2] PGLUE B RBC
1389 * attention [3] PGLUE B RBC parity; [4] ATC attention; [5] ATC parity; [6]
1390 * mstat0 attention; [7] mstat0 parity; [8] mstat1 attention; [9] mstat1
1391 * parity; [31-10] Reserved; */
1392#define MISC_REG_AEU_ENABLE5_FUNC_0_OUT_0 0xa688
1393/* [RW 32] Fifth 32b for enabling the output for function 1 output0. Mapped
1394 * as follows: [0] PGLUE config_space; [1] PGLUE misc_flr; [2] PGLUE B RBC
1395 * attention [3] PGLUE B RBC parity; [4] ATC attention; [5] ATC parity; [6]
1396 * mstat0 attention; [7] mstat0 parity; [8] mstat1 attention; [9] mstat1
1397 * parity; [31-10] Reserved; */
1398#define MISC_REG_AEU_ENABLE5_FUNC_1_OUT_0 0xa6b0
1387/* [RW 1] set/clr general attention 0; this will set/clr bit 94 in the aeu 1399/* [RW 1] set/clr general attention 0; this will set/clr bit 94 in the aeu
1388 128 bit vector */ 1400 128 bit vector */
1389#define MISC_REG_AEU_GENERAL_ATTN_0 0xa000 1401#define MISC_REG_AEU_GENERAL_ATTN_0 0xa000
diff --git a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c
index 805076c54f1b..da5a5d9b8aff 100644
--- a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c
+++ b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c
@@ -1146,12 +1146,14 @@ static void cxgb_redirect(struct dst_entry *old, struct dst_entry *new)
1146 if (te && te->ctx && te->client && te->client->redirect) { 1146 if (te && te->ctx && te->client && te->client->redirect) {
1147 update_tcb = te->client->redirect(te->ctx, old, new, e); 1147 update_tcb = te->client->redirect(te->ctx, old, new, e);
1148 if (update_tcb) { 1148 if (update_tcb) {
1149 rcu_read_lock();
1149 l2t_hold(L2DATA(tdev), e); 1150 l2t_hold(L2DATA(tdev), e);
1151 rcu_read_unlock();
1150 set_l2t_ix(tdev, tid, e); 1152 set_l2t_ix(tdev, tid, e);
1151 } 1153 }
1152 } 1154 }
1153 } 1155 }
1154 l2t_release(L2DATA(tdev), e); 1156 l2t_release(tdev, e);
1155} 1157}
1156 1158
1157/* 1159/*
@@ -1264,7 +1266,7 @@ int cxgb3_offload_activate(struct adapter *adapter)
1264 goto out_free; 1266 goto out_free;
1265 1267
1266 err = -ENOMEM; 1268 err = -ENOMEM;
1267 L2DATA(dev) = t3_init_l2t(l2t_capacity); 1269 RCU_INIT_POINTER(dev->l2opt, t3_init_l2t(l2t_capacity));
1268 if (!L2DATA(dev)) 1270 if (!L2DATA(dev))
1269 goto out_free; 1271 goto out_free;
1270 1272
@@ -1298,16 +1300,24 @@ int cxgb3_offload_activate(struct adapter *adapter)
1298 1300
1299out_free_l2t: 1301out_free_l2t:
1300 t3_free_l2t(L2DATA(dev)); 1302 t3_free_l2t(L2DATA(dev));
1301 L2DATA(dev) = NULL; 1303 rcu_assign_pointer(dev->l2opt, NULL);
1302out_free: 1304out_free:
1303 kfree(t); 1305 kfree(t);
1304 return err; 1306 return err;
1305} 1307}
1306 1308
1309static void clean_l2_data(struct rcu_head *head)
1310{
1311 struct l2t_data *d = container_of(head, struct l2t_data, rcu_head);
1312 t3_free_l2t(d);
1313}
1314
1315
1307void cxgb3_offload_deactivate(struct adapter *adapter) 1316void cxgb3_offload_deactivate(struct adapter *adapter)
1308{ 1317{
1309 struct t3cdev *tdev = &adapter->tdev; 1318 struct t3cdev *tdev = &adapter->tdev;
1310 struct t3c_data *t = T3C_DATA(tdev); 1319 struct t3c_data *t = T3C_DATA(tdev);
1320 struct l2t_data *d;
1311 1321
1312 remove_adapter(adapter); 1322 remove_adapter(adapter);
1313 if (list_empty(&adapter_list)) 1323 if (list_empty(&adapter_list))
@@ -1315,8 +1325,11 @@ void cxgb3_offload_deactivate(struct adapter *adapter)
1315 1325
1316 free_tid_maps(&t->tid_maps); 1326 free_tid_maps(&t->tid_maps);
1317 T3C_DATA(tdev) = NULL; 1327 T3C_DATA(tdev) = NULL;
1318 t3_free_l2t(L2DATA(tdev)); 1328 rcu_read_lock();
1319 L2DATA(tdev) = NULL; 1329 d = L2DATA(tdev);
1330 rcu_read_unlock();
1331 rcu_assign_pointer(tdev->l2opt, NULL);
1332 call_rcu(&d->rcu_head, clean_l2_data);
1320 if (t->nofail_skb) 1333 if (t->nofail_skb)
1321 kfree_skb(t->nofail_skb); 1334 kfree_skb(t->nofail_skb);
1322 kfree(t); 1335 kfree(t);
diff --git a/drivers/net/ethernet/chelsio/cxgb3/l2t.c b/drivers/net/ethernet/chelsio/cxgb3/l2t.c
index f452c4003253..41540978a173 100644
--- a/drivers/net/ethernet/chelsio/cxgb3/l2t.c
+++ b/drivers/net/ethernet/chelsio/cxgb3/l2t.c
@@ -300,14 +300,21 @@ static inline void reuse_entry(struct l2t_entry *e, struct neighbour *neigh)
300struct l2t_entry *t3_l2t_get(struct t3cdev *cdev, struct neighbour *neigh, 300struct l2t_entry *t3_l2t_get(struct t3cdev *cdev, struct neighbour *neigh,
301 struct net_device *dev) 301 struct net_device *dev)
302{ 302{
303 struct l2t_entry *e; 303 struct l2t_entry *e = NULL;
304 struct l2t_data *d = L2DATA(cdev); 304 struct l2t_data *d;
305 int hash;
305 u32 addr = *(u32 *) neigh->primary_key; 306 u32 addr = *(u32 *) neigh->primary_key;
306 int ifidx = neigh->dev->ifindex; 307 int ifidx = neigh->dev->ifindex;
307 int hash = arp_hash(addr, ifidx, d);
308 struct port_info *p = netdev_priv(dev); 308 struct port_info *p = netdev_priv(dev);
309 int smt_idx = p->port_id; 309 int smt_idx = p->port_id;
310 310
311 rcu_read_lock();
312 d = L2DATA(cdev);
313 if (!d)
314 goto done_rcu;
315
316 hash = arp_hash(addr, ifidx, d);
317
311 write_lock_bh(&d->lock); 318 write_lock_bh(&d->lock);
312 for (e = d->l2tab[hash].first; e; e = e->next) 319 for (e = d->l2tab[hash].first; e; e = e->next)
313 if (e->addr == addr && e->ifindex == ifidx && 320 if (e->addr == addr && e->ifindex == ifidx &&
@@ -338,6 +345,8 @@ struct l2t_entry *t3_l2t_get(struct t3cdev *cdev, struct neighbour *neigh,
338 } 345 }
339done: 346done:
340 write_unlock_bh(&d->lock); 347 write_unlock_bh(&d->lock);
348done_rcu:
349 rcu_read_unlock();
341 return e; 350 return e;
342} 351}
343 352
diff --git a/drivers/net/ethernet/chelsio/cxgb3/l2t.h b/drivers/net/ethernet/chelsio/cxgb3/l2t.h
index 7a12d52ed4fc..c5f54796e2cb 100644
--- a/drivers/net/ethernet/chelsio/cxgb3/l2t.h
+++ b/drivers/net/ethernet/chelsio/cxgb3/l2t.h
@@ -76,6 +76,7 @@ struct l2t_data {
76 atomic_t nfree; /* number of free entries */ 76 atomic_t nfree; /* number of free entries */
77 rwlock_t lock; 77 rwlock_t lock;
78 struct l2t_entry l2tab[0]; 78 struct l2t_entry l2tab[0];
79 struct rcu_head rcu_head; /* to handle rcu cleanup */
79}; 80};
80 81
81typedef void (*arp_failure_handler_func)(struct t3cdev * dev, 82typedef void (*arp_failure_handler_func)(struct t3cdev * dev,
@@ -99,7 +100,7 @@ static inline void set_arp_failure_handler(struct sk_buff *skb,
99/* 100/*
100 * Getting to the L2 data from an offload device. 101 * Getting to the L2 data from an offload device.
101 */ 102 */
102#define L2DATA(dev) ((dev)->l2opt) 103#define L2DATA(cdev) (rcu_dereference((cdev)->l2opt))
103 104
104#define W_TCB_L2T_IX 0 105#define W_TCB_L2T_IX 0
105#define S_TCB_L2T_IX 7 106#define S_TCB_L2T_IX 7
@@ -126,15 +127,22 @@ static inline int l2t_send(struct t3cdev *dev, struct sk_buff *skb,
126 return t3_l2t_send_slow(dev, skb, e); 127 return t3_l2t_send_slow(dev, skb, e);
127} 128}
128 129
129static inline void l2t_release(struct l2t_data *d, struct l2t_entry *e) 130static inline void l2t_release(struct t3cdev *t, struct l2t_entry *e)
130{ 131{
131 if (atomic_dec_and_test(&e->refcnt)) 132 struct l2t_data *d;
133
134 rcu_read_lock();
135 d = L2DATA(t);
136
137 if (atomic_dec_and_test(&e->refcnt) && d)
132 t3_l2e_free(d, e); 138 t3_l2e_free(d, e);
139
140 rcu_read_unlock();
133} 141}
134 142
135static inline void l2t_hold(struct l2t_data *d, struct l2t_entry *e) 143static inline void l2t_hold(struct l2t_data *d, struct l2t_entry *e)
136{ 144{
137 if (atomic_add_return(1, &e->refcnt) == 1) /* 0 -> 1 transition */ 145 if (d && atomic_add_return(1, &e->refcnt) == 1) /* 0 -> 1 transition */
138 atomic_dec(&d->nfree); 146 atomic_dec(&d->nfree);
139} 147}
140 148
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index 40b395f932cf..4c8f42afa3c6 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -3715,6 +3715,9 @@ static int __devinit init_one(struct pci_dev *pdev,
3715 setup_debugfs(adapter); 3715 setup_debugfs(adapter);
3716 } 3716 }
3717 3717
3718 /* PCIe EEH recovery on powerpc platforms needs fundamental reset */
3719 pdev->needs_freset = 1;
3720
3718 if (is_offload(adapter)) 3721 if (is_offload(adapter))
3719 attach_ulds(adapter); 3722 attach_ulds(adapter);
3720 3723
diff --git a/drivers/net/ethernet/ibm/ibmveth.c b/drivers/net/ethernet/ibm/ibmveth.c
index 72b84de48756..4da972eaabb4 100644
--- a/drivers/net/ethernet/ibm/ibmveth.c
+++ b/drivers/net/ethernet/ibm/ibmveth.c
@@ -636,8 +636,8 @@ static int ibmveth_open(struct net_device *netdev)
636 netdev_err(netdev, "unable to request irq 0x%x, rc %d\n", 636 netdev_err(netdev, "unable to request irq 0x%x, rc %d\n",
637 netdev->irq, rc); 637 netdev->irq, rc);
638 do { 638 do {
639 rc = h_free_logical_lan(adapter->vdev->unit_address); 639 lpar_rc = h_free_logical_lan(adapter->vdev->unit_address);
640 } while (H_IS_LONG_BUSY(rc) || (rc == H_BUSY)); 640 } while (H_IS_LONG_BUSY(lpar_rc) || (lpar_rc == H_BUSY));
641 641
642 goto err_out; 642 goto err_out;
643 } 643 }
diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
index 5dc61b4ef3cd..b89f3a684aec 100644
--- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
+++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
@@ -1198,6 +1198,8 @@ static irqreturn_t pch_gbe_intr(int irq, void *data)
1198 iowrite32((int_en & ~PCH_GBE_INT_RX_FIFO_ERR), 1198 iowrite32((int_en & ~PCH_GBE_INT_RX_FIFO_ERR),
1199 &hw->reg->INT_EN); 1199 &hw->reg->INT_EN);
1200 pch_gbe_stop_receive(adapter); 1200 pch_gbe_stop_receive(adapter);
1201 int_st |= ioread32(&hw->reg->INT_ST);
1202 int_st = int_st & ioread32(&hw->reg->INT_EN);
1201 } 1203 }
1202 if (int_st & PCH_GBE_INT_RX_DMA_ERR) 1204 if (int_st & PCH_GBE_INT_RX_DMA_ERR)
1203 adapter->stats.intr_rx_dma_err_count++; 1205 adapter->stats.intr_rx_dma_err_count++;
@@ -1217,14 +1219,11 @@ static irqreturn_t pch_gbe_intr(int irq, void *data)
1217 /* Set Pause packet */ 1219 /* Set Pause packet */
1218 pch_gbe_mac_set_pause_packet(hw); 1220 pch_gbe_mac_set_pause_packet(hw);
1219 } 1221 }
1220 if ((int_en & (PCH_GBE_INT_RX_DMA_CMPLT | PCH_GBE_INT_TX_CMPLT))
1221 == 0) {
1222 return IRQ_HANDLED;
1223 }
1224 } 1222 }
1225 1223
1226 /* When request status is Receive interruption */ 1224 /* When request status is Receive interruption */
1227 if ((int_st & (PCH_GBE_INT_RX_DMA_CMPLT | PCH_GBE_INT_TX_CMPLT))) { 1225 if ((int_st & (PCH_GBE_INT_RX_DMA_CMPLT | PCH_GBE_INT_TX_CMPLT)) ||
1226 (adapter->rx_stop_flag == true)) {
1228 if (likely(napi_schedule_prep(&adapter->napi))) { 1227 if (likely(napi_schedule_prep(&adapter->napi))) {
1229 /* Enable only Rx Descriptor empty */ 1228 /* Enable only Rx Descriptor empty */
1230 atomic_inc(&adapter->irq_sem); 1229 atomic_inc(&adapter->irq_sem);
@@ -1384,7 +1383,7 @@ pch_gbe_clean_tx(struct pch_gbe_adapter *adapter,
1384 struct sk_buff *skb; 1383 struct sk_buff *skb;
1385 unsigned int i; 1384 unsigned int i;
1386 unsigned int cleaned_count = 0; 1385 unsigned int cleaned_count = 0;
1387 bool cleaned = false; 1386 bool cleaned = true;
1388 1387
1389 pr_debug("next_to_clean : %d\n", tx_ring->next_to_clean); 1388 pr_debug("next_to_clean : %d\n", tx_ring->next_to_clean);
1390 1389
@@ -1395,7 +1394,6 @@ pch_gbe_clean_tx(struct pch_gbe_adapter *adapter,
1395 1394
1396 while ((tx_desc->gbec_status & DSC_INIT16) == 0x0000) { 1395 while ((tx_desc->gbec_status & DSC_INIT16) == 0x0000) {
1397 pr_debug("gbec_status:0x%04x\n", tx_desc->gbec_status); 1396 pr_debug("gbec_status:0x%04x\n", tx_desc->gbec_status);
1398 cleaned = true;
1399 buffer_info = &tx_ring->buffer_info[i]; 1397 buffer_info = &tx_ring->buffer_info[i];
1400 skb = buffer_info->skb; 1398 skb = buffer_info->skb;
1401 1399
@@ -1438,8 +1436,10 @@ pch_gbe_clean_tx(struct pch_gbe_adapter *adapter,
1438 tx_desc = PCH_GBE_TX_DESC(*tx_ring, i); 1436 tx_desc = PCH_GBE_TX_DESC(*tx_ring, i);
1439 1437
1440 /* weight of a sort for tx, to avoid endless transmit cleanup */ 1438 /* weight of a sort for tx, to avoid endless transmit cleanup */
1441 if (cleaned_count++ == PCH_GBE_TX_WEIGHT) 1439 if (cleaned_count++ == PCH_GBE_TX_WEIGHT) {
1440 cleaned = false;
1442 break; 1441 break;
1442 }
1443 } 1443 }
1444 pr_debug("called pch_gbe_unmap_and_free_tx_resource() %d count\n", 1444 pr_debug("called pch_gbe_unmap_and_free_tx_resource() %d count\n",
1445 cleaned_count); 1445 cleaned_count);
@@ -2167,7 +2167,6 @@ static int pch_gbe_napi_poll(struct napi_struct *napi, int budget)
2167{ 2167{
2168 struct pch_gbe_adapter *adapter = 2168 struct pch_gbe_adapter *adapter =
2169 container_of(napi, struct pch_gbe_adapter, napi); 2169 container_of(napi, struct pch_gbe_adapter, napi);
2170 struct net_device *netdev = adapter->netdev;
2171 int work_done = 0; 2170 int work_done = 0;
2172 bool poll_end_flag = false; 2171 bool poll_end_flag = false;
2173 bool cleaned = false; 2172 bool cleaned = false;
@@ -2175,33 +2174,32 @@ static int pch_gbe_napi_poll(struct napi_struct *napi, int budget)
2175 2174
2176 pr_debug("budget : %d\n", budget); 2175 pr_debug("budget : %d\n", budget);
2177 2176
2178 /* Keep link state information with original netdev */ 2177 pch_gbe_clean_rx(adapter, adapter->rx_ring, &work_done, budget);
2179 if (!netif_carrier_ok(netdev)) { 2178 cleaned = pch_gbe_clean_tx(adapter, adapter->tx_ring);
2179
2180 if (!cleaned)
2181 work_done = budget;
2182 /* If no Tx and not enough Rx work done,
2183 * exit the polling mode
2184 */
2185 if (work_done < budget)
2180 poll_end_flag = true; 2186 poll_end_flag = true;
2181 } else { 2187
2182 pch_gbe_clean_rx(adapter, adapter->rx_ring, &work_done, budget); 2188 if (poll_end_flag) {
2189 napi_complete(napi);
2190 if (adapter->rx_stop_flag) {
2191 adapter->rx_stop_flag = false;
2192 pch_gbe_start_receive(&adapter->hw);
2193 }
2194 pch_gbe_irq_enable(adapter);
2195 } else
2183 if (adapter->rx_stop_flag) { 2196 if (adapter->rx_stop_flag) {
2184 adapter->rx_stop_flag = false; 2197 adapter->rx_stop_flag = false;
2185 pch_gbe_start_receive(&adapter->hw); 2198 pch_gbe_start_receive(&adapter->hw);
2186 int_en = ioread32(&adapter->hw.reg->INT_EN); 2199 int_en = ioread32(&adapter->hw.reg->INT_EN);
2187 iowrite32((int_en | PCH_GBE_INT_RX_FIFO_ERR), 2200 iowrite32((int_en | PCH_GBE_INT_RX_FIFO_ERR),
2188 &adapter->hw.reg->INT_EN); 2201 &adapter->hw.reg->INT_EN);
2189 } 2202 }
2190 cleaned = pch_gbe_clean_tx(adapter, adapter->tx_ring);
2191
2192 if (cleaned)
2193 work_done = budget;
2194 /* If no Tx and not enough Rx work done,
2195 * exit the polling mode
2196 */
2197 if ((work_done < budget) || !netif_running(netdev))
2198 poll_end_flag = true;
2199 }
2200
2201 if (poll_end_flag) {
2202 napi_complete(napi);
2203 pch_gbe_irq_enable(adapter);
2204 }
2205 2203
2206 pr_debug("poll_end_flag : %d work_done : %d budget : %d\n", 2204 pr_debug("poll_end_flag : %d work_done : %d budget : %d\n",
2207 poll_end_flag, work_done, budget); 2205 poll_end_flag, work_done, budget);