aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c')
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c90
1 files changed, 55 insertions, 35 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
index 8c28a1518409..14b8fdde6954 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
@@ -14,8 +14,6 @@
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */ 15 */
16 16
17#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
18
19#include <linux/kernel.h> 17#include <linux/kernel.h>
20#include <linux/etherdevice.h> 18#include <linux/etherdevice.h>
21#include <linux/module.h> 19#include <linux/module.h>
@@ -162,28 +160,31 @@ static void brcmf_netdev_set_multicast_list(struct net_device *ndev)
162 schedule_work(&ifp->multicast_work); 160 schedule_work(&ifp->multicast_work);
163} 161}
164 162
165static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *ndev) 163static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb,
164 struct net_device *ndev)
166{ 165{
167 int ret; 166 int ret;
168 struct brcmf_if *ifp = netdev_priv(ndev); 167 struct brcmf_if *ifp = netdev_priv(ndev);
169 struct brcmf_pub *drvr = ifp->drvr; 168 struct brcmf_pub *drvr = ifp->drvr;
169 struct ethhdr *eh;
170 170
171 brcmf_dbg(TRACE, "Enter\n"); 171 brcmf_dbg(TRACE, "Enter\n");
172 172
173 /* Reject if down */ 173 /* Can the device send data? */
174 if (!drvr->bus_if->drvr_up || 174 if (drvr->bus_if->state != BRCMF_BUS_DATA) {
175 (drvr->bus_if->state != BRCMF_BUS_DATA)) { 175 brcmf_err("xmit rejected state=%d\n", drvr->bus_if->state);
176 brcmf_err("xmit rejected drvup=%d state=%d\n",
177 drvr->bus_if->drvr_up,
178 drvr->bus_if->state);
179 netif_stop_queue(ndev); 176 netif_stop_queue(ndev);
180 return -ENODEV; 177 dev_kfree_skb(skb);
178 ret = -ENODEV;
179 goto done;
181 } 180 }
182 181
183 if (!drvr->iflist[ifp->idx]) { 182 if (!drvr->iflist[ifp->idx]) {
184 brcmf_err("bad ifidx %d\n", ifp->idx); 183 brcmf_err("bad ifidx %d\n", ifp->idx);
185 netif_stop_queue(ndev); 184 netif_stop_queue(ndev);
186 return -ENODEV; 185 dev_kfree_skb(skb);
186 ret = -ENODEV;
187 goto done;
187 } 188 }
188 189
189 /* Make sure there's enough room for any header */ 190 /* Make sure there's enough room for any header */
@@ -204,17 +205,20 @@ static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *ndev)
204 } 205 }
205 } 206 }
206 207
207 /* Update multicast statistic */ 208 /* validate length for ether packet */
208 if (skb->len >= ETH_ALEN) { 209 if (skb->len < sizeof(*eh)) {
209 u8 *pktdata = (u8 *)(skb->data); 210 ret = -EINVAL;
210 struct ethhdr *eh = (struct ethhdr *)pktdata; 211 dev_kfree_skb(skb);
211 212 goto done;
212 if (is_multicast_ether_addr(eh->h_dest))
213 drvr->tx_multicast++;
214 if (ntohs(eh->h_proto) == ETH_P_PAE)
215 atomic_inc(&drvr->pend_8021x_cnt);
216 } 213 }
217 214
215 /* handle ethernet header */
216 eh = (struct ethhdr *)(skb->data);
217 if (is_multicast_ether_addr(eh->h_dest))
218 drvr->tx_multicast++;
219 if (ntohs(eh->h_proto) == ETH_P_PAE)
220 atomic_inc(&drvr->pend_8021x_cnt);
221
218 /* If the protocol uses a data header, apply it */ 222 /* If the protocol uses a data header, apply it */
219 brcmf_proto_hdrpush(drvr, ifp->idx, skb); 223 brcmf_proto_hdrpush(drvr, ifp->idx, skb);
220 224
@@ -228,7 +232,7 @@ done:
228 drvr->bus_if->dstats.tx_packets++; 232 drvr->bus_if->dstats.tx_packets++;
229 233
230 /* Return ok: we always eat the packet */ 234 /* Return ok: we always eat the packet */
231 return 0; 235 return NETDEV_TX_OK;
232} 236}
233 237
234void brcmf_txflowblock(struct device *dev, bool state) 238void brcmf_txflowblock(struct device *dev, bool state)
@@ -250,8 +254,7 @@ void brcmf_txflowblock(struct device *dev, bool state)
250 } 254 }
251} 255}
252 256
253void brcmf_rx_frame(struct device *dev, u8 ifidx, 257void brcmf_rx_frames(struct device *dev, struct sk_buff_head *skb_list)
254 struct sk_buff_head *skb_list)
255{ 258{
256 unsigned char *eth; 259 unsigned char *eth;
257 uint len; 260 uint len;
@@ -259,12 +262,24 @@ void brcmf_rx_frame(struct device *dev, u8 ifidx,
259 struct brcmf_if *ifp; 262 struct brcmf_if *ifp;
260 struct brcmf_bus *bus_if = dev_get_drvdata(dev); 263 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
261 struct brcmf_pub *drvr = bus_if->drvr; 264 struct brcmf_pub *drvr = bus_if->drvr;
265 u8 ifidx;
266 int ret;
262 267
263 brcmf_dbg(TRACE, "Enter\n"); 268 brcmf_dbg(TRACE, "Enter\n");
264 269
265 skb_queue_walk_safe(skb_list, skb, pnext) { 270 skb_queue_walk_safe(skb_list, skb, pnext) {
266 skb_unlink(skb, skb_list); 271 skb_unlink(skb, skb_list);
267 272
273 /* process and remove protocol-specific header
274 */
275 ret = brcmf_proto_hdrpull(drvr, &ifidx, skb);
276 if (ret < 0) {
277 if (ret != -ENODATA)
278 bus_if->dstats.rx_errors++;
279 brcmu_pkt_buf_free_skb(skb);
280 continue;
281 }
282
268 /* Get the protocol, maintain skb around eth_type_trans() 283 /* Get the protocol, maintain skb around eth_type_trans()
269 * The main reason for this hack is for the limitation of 284 * The main reason for this hack is for the limitation of
270 * Linux 2.4 where 'eth_type_trans' uses the 285 * Linux 2.4 where 'eth_type_trans' uses the
@@ -328,13 +343,13 @@ void brcmf_rx_frame(struct device *dev, u8 ifidx,
328 343
329void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success) 344void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success)
330{ 345{
331 uint ifidx; 346 u8 ifidx;
332 struct ethhdr *eh; 347 struct ethhdr *eh;
333 u16 type; 348 u16 type;
334 struct brcmf_bus *bus_if = dev_get_drvdata(dev); 349 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
335 struct brcmf_pub *drvr = bus_if->drvr; 350 struct brcmf_pub *drvr = bus_if->drvr;
336 351
337 brcmf_proto_hdrpull(dev, &ifidx, txp); 352 brcmf_proto_hdrpull(drvr, &ifidx, txp);
338 353
339 eh = (struct ethhdr *)(txp->data); 354 eh = (struct ethhdr *)(txp->data);
340 type = ntohs(eh->h_proto); 355 type = ntohs(eh->h_proto);
@@ -452,7 +467,7 @@ static int brcmf_ethtool(struct brcmf_if *ifp, void __user *uaddr)
452 sprintf(info.version, "%lu", drvr->drv_version); 467 sprintf(info.version, "%lu", drvr->drv_version);
453 if (copy_to_user(uaddr, &info, sizeof(info))) 468 if (copy_to_user(uaddr, &info, sizeof(info)))
454 return -EFAULT; 469 return -EFAULT;
455 brcmf_dbg(CTL, "given %*s, returning %s\n", 470 brcmf_dbg(TRACE, "given %*s, returning %s\n",
456 (int)sizeof(drvname), drvname, info.driver); 471 (int)sizeof(drvname), drvname, info.driver);
457 break; 472 break;
458 473
@@ -572,14 +587,9 @@ static int brcmf_netdev_open(struct net_device *ndev)
572 /* Get current TOE mode from dongle */ 587 /* Get current TOE mode from dongle */
573 if (brcmf_fil_iovar_int_get(ifp, "toe_ol", &toe_ol) >= 0 588 if (brcmf_fil_iovar_int_get(ifp, "toe_ol", &toe_ol) >= 0
574 && (toe_ol & TOE_TX_CSUM_OL) != 0) 589 && (toe_ol & TOE_TX_CSUM_OL) != 0)
575 drvr->iflist[ifp->idx]->ndev->features |= 590 ndev->features |= NETIF_F_IP_CSUM;
576 NETIF_F_IP_CSUM;
577 else 591 else
578 drvr->iflist[ifp->idx]->ndev->features &= 592 ndev->features &= ~NETIF_F_IP_CSUM;
579 ~NETIF_F_IP_CSUM;
580
581 /* make sure RF is ready for work */
582 brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0);
583 593
584 /* Allow transmit calls */ 594 /* Allow transmit calls */
585 netif_start_queue(ndev); 595 netif_start_queue(ndev);
@@ -847,6 +857,17 @@ static void brcmf_bus_detach(struct brcmf_pub *drvr)
847 } 857 }
848} 858}
849 859
860void brcmf_dev_reset(struct device *dev)
861{
862 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
863 struct brcmf_pub *drvr = bus_if->drvr;
864
865 if (drvr == NULL)
866 return;
867
868 brcmf_fil_cmd_int_set(drvr->iflist[0], BRCMF_C_TERMINATED, 1);
869}
870
850void brcmf_detach(struct device *dev) 871void brcmf_detach(struct device *dev)
851{ 872{
852 int i; 873 int i;
@@ -868,9 +889,8 @@ void brcmf_detach(struct device *dev)
868 889
869 brcmf_bus_detach(drvr); 890 brcmf_bus_detach(drvr);
870 891
871 if (drvr->prot) { 892 if (drvr->prot)
872 brcmf_proto_detach(drvr); 893 brcmf_proto_detach(drvr);
873 }
874 894
875 brcmf_debugfs_detach(drvr); 895 brcmf_debugfs_detach(drvr);
876 bus_if->drvr = NULL; 896 bus_if->drvr = NULL;