diff options
-rw-r--r-- | drivers/net/ethernet/ezchip/nps_enet.c | 37 | ||||
-rw-r--r-- | drivers/net/ethernet/ezchip/nps_enet.h | 20 |
2 files changed, 19 insertions, 38 deletions
diff --git a/drivers/net/ethernet/ezchip/nps_enet.c b/drivers/net/ethernet/ezchip/nps_enet.c index 24a85b292007..63c2bcf8031a 100644 --- a/drivers/net/ethernet/ezchip/nps_enet.c +++ b/drivers/net/ethernet/ezchip/nps_enet.c | |||
@@ -150,6 +150,9 @@ static void nps_enet_tx_handler(struct net_device *ndev) | |||
150 | if (!priv->tx_packet_sent || tx_ctrl.ct) | 150 | if (!priv->tx_packet_sent || tx_ctrl.ct) |
151 | return; | 151 | return; |
152 | 152 | ||
153 | /* Ack Tx ctrl register */ | ||
154 | nps_enet_reg_set(priv, NPS_ENET_REG_TX_CTL, 0); | ||
155 | |||
153 | /* Check Tx transmit error */ | 156 | /* Check Tx transmit error */ |
154 | if (unlikely(tx_ctrl.et)) { | 157 | if (unlikely(tx_ctrl.et)) { |
155 | ndev->stats.tx_errors++; | 158 | ndev->stats.tx_errors++; |
@@ -158,11 +161,7 @@ static void nps_enet_tx_handler(struct net_device *ndev) | |||
158 | ndev->stats.tx_bytes += tx_ctrl.nt; | 161 | ndev->stats.tx_bytes += tx_ctrl.nt; |
159 | } | 162 | } |
160 | 163 | ||
161 | if (priv->tx_skb) { | 164 | dev_kfree_skb(priv->tx_skb); |
162 | dev_kfree_skb(priv->tx_skb); | ||
163 | priv->tx_skb = NULL; | ||
164 | } | ||
165 | |||
166 | priv->tx_packet_sent = false; | 165 | priv->tx_packet_sent = false; |
167 | 166 | ||
168 | if (netif_queue_stopped(ndev)) | 167 | if (netif_queue_stopped(ndev)) |
@@ -180,15 +179,16 @@ static int nps_enet_poll(struct napi_struct *napi, int budget) | |||
180 | { | 179 | { |
181 | struct net_device *ndev = napi->dev; | 180 | struct net_device *ndev = napi->dev; |
182 | struct nps_enet_priv *priv = netdev_priv(ndev); | 181 | struct nps_enet_priv *priv = netdev_priv(ndev); |
183 | struct nps_enet_buf_int_enable buf_int_enable; | ||
184 | u32 work_done; | 182 | u32 work_done; |
185 | 183 | ||
186 | buf_int_enable.rx_rdy = NPS_ENET_ENABLE; | ||
187 | buf_int_enable.tx_done = NPS_ENET_ENABLE; | ||
188 | nps_enet_tx_handler(ndev); | 184 | nps_enet_tx_handler(ndev); |
189 | work_done = nps_enet_rx_handler(ndev); | 185 | work_done = nps_enet_rx_handler(ndev); |
190 | if (work_done < budget) { | 186 | if (work_done < budget) { |
187 | struct nps_enet_buf_int_enable buf_int_enable; | ||
188 | |||
191 | napi_complete(napi); | 189 | napi_complete(napi); |
190 | buf_int_enable.rx_rdy = NPS_ENET_ENABLE; | ||
191 | buf_int_enable.tx_done = NPS_ENET_ENABLE; | ||
192 | nps_enet_reg_set(priv, NPS_ENET_REG_BUF_INT_ENABLE, | 192 | nps_enet_reg_set(priv, NPS_ENET_REG_BUF_INT_ENABLE, |
193 | buf_int_enable.value); | 193 | buf_int_enable.value); |
194 | } | 194 | } |
@@ -211,12 +211,13 @@ static irqreturn_t nps_enet_irq_handler(s32 irq, void *dev_instance) | |||
211 | { | 211 | { |
212 | struct net_device *ndev = dev_instance; | 212 | struct net_device *ndev = dev_instance; |
213 | struct nps_enet_priv *priv = netdev_priv(ndev); | 213 | struct nps_enet_priv *priv = netdev_priv(ndev); |
214 | struct nps_enet_buf_int_cause buf_int_cause; | 214 | struct nps_enet_rx_ctl rx_ctrl; |
215 | struct nps_enet_tx_ctl tx_ctrl; | ||
215 | 216 | ||
216 | buf_int_cause.value = | 217 | rx_ctrl.value = nps_enet_reg_get(priv, NPS_ENET_REG_RX_CTL); |
217 | nps_enet_reg_get(priv, NPS_ENET_REG_BUF_INT_CAUSE); | 218 | tx_ctrl.value = nps_enet_reg_get(priv, NPS_ENET_REG_TX_CTL); |
218 | 219 | ||
219 | if (buf_int_cause.tx_done || buf_int_cause.rx_rdy) | 220 | if ((!tx_ctrl.ct && priv->tx_packet_sent) || rx_ctrl.cr) |
220 | if (likely(napi_schedule_prep(&priv->napi))) { | 221 | if (likely(napi_schedule_prep(&priv->napi))) { |
221 | nps_enet_reg_set(priv, NPS_ENET_REG_BUF_INT_ENABLE, 0); | 222 | nps_enet_reg_set(priv, NPS_ENET_REG_BUF_INT_ENABLE, 0); |
222 | __napi_schedule(&priv->napi); | 223 | __napi_schedule(&priv->napi); |
@@ -307,11 +308,8 @@ static void nps_enet_hw_enable_control(struct net_device *ndev) | |||
307 | 308 | ||
308 | /* Discard Packets bigger than max frame length */ | 309 | /* Discard Packets bigger than max frame length */ |
309 | max_frame_length = ETH_HLEN + ndev->mtu + ETH_FCS_LEN; | 310 | max_frame_length = ETH_HLEN + ndev->mtu + ETH_FCS_LEN; |
310 | if (max_frame_length <= NPS_ENET_MAX_FRAME_LENGTH) { | 311 | if (max_frame_length <= NPS_ENET_MAX_FRAME_LENGTH) |
311 | ge_mac_cfg_3->max_len = max_frame_length; | 312 | ge_mac_cfg_3->max_len = max_frame_length; |
312 | nps_enet_reg_set(priv, NPS_ENET_REG_GE_MAC_CFG_3, | ||
313 | ge_mac_cfg_3->value); | ||
314 | } | ||
315 | 313 | ||
316 | /* Enable interrupts */ | 314 | /* Enable interrupts */ |
317 | buf_int_enable.rx_rdy = NPS_ENET_ENABLE; | 315 | buf_int_enable.rx_rdy = NPS_ENET_ENABLE; |
@@ -339,11 +337,14 @@ static void nps_enet_hw_enable_control(struct net_device *ndev) | |||
339 | ge_mac_cfg_0.tx_fc_en = NPS_ENET_ENABLE; | 337 | ge_mac_cfg_0.tx_fc_en = NPS_ENET_ENABLE; |
340 | ge_mac_cfg_0.rx_fc_en = NPS_ENET_ENABLE; | 338 | ge_mac_cfg_0.rx_fc_en = NPS_ENET_ENABLE; |
341 | ge_mac_cfg_0.tx_fc_retr = NPS_ENET_GE_MAC_CFG_0_TX_FC_RETR; | 339 | ge_mac_cfg_0.tx_fc_retr = NPS_ENET_GE_MAC_CFG_0_TX_FC_RETR; |
340 | ge_mac_cfg_3->cf_drop = NPS_ENET_ENABLE; | ||
342 | 341 | ||
343 | /* Enable Rx and Tx */ | 342 | /* Enable Rx and Tx */ |
344 | ge_mac_cfg_0.rx_en = NPS_ENET_ENABLE; | 343 | ge_mac_cfg_0.rx_en = NPS_ENET_ENABLE; |
345 | ge_mac_cfg_0.tx_en = NPS_ENET_ENABLE; | 344 | ge_mac_cfg_0.tx_en = NPS_ENET_ENABLE; |
346 | 345 | ||
346 | nps_enet_reg_set(priv, NPS_ENET_REG_GE_MAC_CFG_3, | ||
347 | ge_mac_cfg_3->value); | ||
347 | nps_enet_reg_set(priv, NPS_ENET_REG_GE_MAC_CFG_0, | 348 | nps_enet_reg_set(priv, NPS_ENET_REG_GE_MAC_CFG_0, |
348 | ge_mac_cfg_0.value); | 349 | ge_mac_cfg_0.value); |
349 | } | 350 | } |
@@ -527,10 +528,10 @@ static netdev_tx_t nps_enet_start_xmit(struct sk_buff *skb, | |||
527 | /* This driver handles one frame at a time */ | 528 | /* This driver handles one frame at a time */ |
528 | netif_stop_queue(ndev); | 529 | netif_stop_queue(ndev); |
529 | 530 | ||
530 | nps_enet_send_frame(ndev, skb); | ||
531 | |||
532 | priv->tx_skb = skb; | 531 | priv->tx_skb = skb; |
533 | 532 | ||
533 | nps_enet_send_frame(ndev, skb); | ||
534 | |||
534 | return NETDEV_TX_OK; | 535 | return NETDEV_TX_OK; |
535 | } | 536 | } |
536 | 537 | ||
diff --git a/drivers/net/ethernet/ezchip/nps_enet.h b/drivers/net/ethernet/ezchip/nps_enet.h index fc45c9daa1c2..6703674d679c 100644 --- a/drivers/net/ethernet/ezchip/nps_enet.h +++ b/drivers/net/ethernet/ezchip/nps_enet.h | |||
@@ -36,7 +36,6 @@ | |||
36 | #define NPS_ENET_REG_RX_CTL 0x810 | 36 | #define NPS_ENET_REG_RX_CTL 0x810 |
37 | #define NPS_ENET_REG_RX_BUF 0x818 | 37 | #define NPS_ENET_REG_RX_BUF 0x818 |
38 | #define NPS_ENET_REG_BUF_INT_ENABLE 0x8C0 | 38 | #define NPS_ENET_REG_BUF_INT_ENABLE 0x8C0 |
39 | #define NPS_ENET_REG_BUF_INT_CAUSE 0x8C4 | ||
40 | #define NPS_ENET_REG_GE_MAC_CFG_0 0x1000 | 39 | #define NPS_ENET_REG_GE_MAC_CFG_0 0x1000 |
41 | #define NPS_ENET_REG_GE_MAC_CFG_1 0x1004 | 40 | #define NPS_ENET_REG_GE_MAC_CFG_1 0x1004 |
42 | #define NPS_ENET_REG_GE_MAC_CFG_2 0x1008 | 41 | #define NPS_ENET_REG_GE_MAC_CFG_2 0x1008 |
@@ -108,25 +107,6 @@ struct nps_enet_buf_int_enable { | |||
108 | }; | 107 | }; |
109 | }; | 108 | }; |
110 | 109 | ||
111 | /* Interrupt cause for data buffer events register */ | ||
112 | struct nps_enet_buf_int_cause { | ||
113 | union { | ||
114 | /* tx_done: Interrupt in the case when current frame was | ||
115 | * read from TX buffer. | ||
116 | * rx_rdy: Interrupt in the case when new frame is ready | ||
117 | * in RX buffer. | ||
118 | */ | ||
119 | struct { | ||
120 | u32 | ||
121 | __reserved:30, | ||
122 | tx_done:1, | ||
123 | rx_rdy:1; | ||
124 | }; | ||
125 | |||
126 | u32 value; | ||
127 | }; | ||
128 | }; | ||
129 | |||
130 | /* Gbps Eth MAC Configuration 0 register */ | 110 | /* Gbps Eth MAC Configuration 0 register */ |
131 | struct nps_enet_ge_mac_cfg_0 { | 111 | struct nps_enet_ge_mac_cfg_0 { |
132 | union { | 112 | union { |