aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/usb.c119
1 files changed, 39 insertions, 80 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
index 6e3ff6f61103..c6d5aeb27a02 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
@@ -80,20 +80,6 @@ enum usbdev_suspend_state {
80 USBOS_SUSPEND_STATE_SUSPENDED /* Device suspended */ 80 USBOS_SUSPEND_STATE_SUSPENDED /* Device suspended */
81}; 81};
82 82
83struct brcmf_usb_probe_info {
84 void *usbdev_info;
85 struct usb_device *usb; /* USB device pointer from OS */
86 uint rx_pipe, tx_pipe, intr_pipe, rx_pipe2;
87 int intr_size; /* Size of interrupt message */
88 int interval; /* Interrupt polling interval */
89 int vid;
90 int pid;
91 enum usb_device_speed device_speed;
92 enum usbdev_suspend_state suspend_state;
93 struct usb_interface *intf;
94};
95static struct brcmf_usb_probe_info usbdev_probe_info;
96
97struct brcmf_usb_image { 83struct brcmf_usb_image {
98 void *data; 84 void *data;
99 u32 len; 85 u32 len;
@@ -134,7 +120,6 @@ struct brcmf_usbdev_info {
134 120
135 struct usb_device *usbdev; 121 struct usb_device *usbdev;
136 struct device *dev; 122 struct device *dev;
137 enum usb_device_speed device_speed;
138 123
139 int ctl_in_pipe, ctl_out_pipe; 124 int ctl_in_pipe, ctl_out_pipe;
140 struct urb *ctl_urb; /* URB for control endpoint */ 125 struct urb *ctl_urb; /* URB for control endpoint */
@@ -154,9 +139,6 @@ struct brcmf_usbdev_info {
154 int intr_size; /* Size of interrupt message */ 139 int intr_size; /* Size of interrupt message */
155 int interval; /* Interrupt polling interval */ 140 int interval; /* Interrupt polling interval */
156 struct intr_transfer_buf intr; /* Data buffer for interrupt endpoint */ 141 struct intr_transfer_buf intr; /* Data buffer for interrupt endpoint */
157
158 struct brcmf_usb_probe_info probe_info;
159
160}; 142};
161 143
162static void brcmf_usb_rx_refill(struct brcmf_usbdev_info *devinfo, 144static void brcmf_usb_rx_refill(struct brcmf_usbdev_info *devinfo,
@@ -1166,11 +1148,8 @@ brcmf_usb_fw_download(struct brcmf_usbdev_info *devinfo)
1166} 1148}
1167 1149
1168 1150
1169static void brcmf_usb_detach(const struct brcmf_usbdev *bus_pub) 1151static void brcmf_usb_detach(struct brcmf_usbdev_info *devinfo)
1170{ 1152{
1171 struct brcmf_usbdev_info *devinfo =
1172 (struct brcmf_usbdev_info *)bus_pub;
1173
1174 brcmf_dbg(TRACE, "devinfo %p\n", devinfo); 1153 brcmf_dbg(TRACE, "devinfo %p\n", devinfo);
1175 1154
1176 /* store the image globally */ 1155 /* store the image globally */
@@ -1187,7 +1166,6 @@ static void brcmf_usb_detach(const struct brcmf_usbdev *bus_pub)
1187 1166
1188 kfree(devinfo->tx_reqs); 1167 kfree(devinfo->tx_reqs);
1189 kfree(devinfo->rx_reqs); 1168 kfree(devinfo->rx_reqs);
1190 kfree(devinfo);
1191} 1169}
1192 1170
1193#define TRX_MAGIC 0x30524448 /* "HDR0" */ 1171#define TRX_MAGIC 0x30524448 /* "HDR0" */
@@ -1280,14 +1258,9 @@ static int brcmf_usb_get_fw(struct brcmf_usbdev_info *devinfo)
1280 1258
1281 1259
1282static 1260static
1283struct brcmf_usbdev *brcmf_usb_attach(int nrxq, int ntxq, struct device *dev) 1261struct brcmf_usbdev *brcmf_usb_attach(struct brcmf_usbdev_info *devinfo,
1262 int nrxq, int ntxq)
1284{ 1263{
1285 struct brcmf_usbdev_info *devinfo;
1286
1287 devinfo = kzalloc(sizeof(struct brcmf_usbdev_info), GFP_ATOMIC);
1288 if (devinfo == NULL)
1289 return NULL;
1290
1291 devinfo->bus_pub.nrxq = nrxq; 1264 devinfo->bus_pub.nrxq = nrxq;
1292 devinfo->rx_low_watermark = nrxq / 2; 1265 devinfo->rx_low_watermark = nrxq / 2;
1293 devinfo->bus_pub.devinfo = devinfo; 1266 devinfo->bus_pub.devinfo = devinfo;
@@ -1296,18 +1269,6 @@ struct brcmf_usbdev *brcmf_usb_attach(int nrxq, int ntxq, struct device *dev)
1296 /* flow control when too many tx urbs posted */ 1269 /* flow control when too many tx urbs posted */
1297 devinfo->tx_low_watermark = ntxq / 4; 1270 devinfo->tx_low_watermark = ntxq / 4;
1298 devinfo->tx_high_watermark = devinfo->tx_low_watermark * 3; 1271 devinfo->tx_high_watermark = devinfo->tx_low_watermark * 3;
1299 devinfo->dev = dev;
1300 devinfo->usbdev = usbdev_probe_info.usb;
1301 devinfo->tx_pipe = usbdev_probe_info.tx_pipe;
1302 devinfo->rx_pipe = usbdev_probe_info.rx_pipe;
1303 devinfo->rx_pipe2 = usbdev_probe_info.rx_pipe2;
1304 devinfo->intr_pipe = usbdev_probe_info.intr_pipe;
1305
1306 devinfo->interval = usbdev_probe_info.interval;
1307 devinfo->intr_size = usbdev_probe_info.intr_size;
1308
1309 memcpy(&devinfo->probe_info, &usbdev_probe_info,
1310 sizeof(struct brcmf_usb_probe_info));
1311 devinfo->bus_pub.bus_mtu = BRCMF_USB_MAX_PKT_SIZE; 1272 devinfo->bus_pub.bus_mtu = BRCMF_USB_MAX_PKT_SIZE;
1312 1273
1313 /* Initialize other structure content */ 1274 /* Initialize other structure content */
@@ -1366,19 +1327,19 @@ struct brcmf_usbdev *brcmf_usb_attach(int nrxq, int ntxq, struct device *dev)
1366 1327
1367error: 1328error:
1368 brcmf_dbg(ERROR, "failed!\n"); 1329 brcmf_dbg(ERROR, "failed!\n");
1369 brcmf_usb_detach(&devinfo->bus_pub); 1330 brcmf_usb_detach(devinfo);
1370 return NULL; 1331 return NULL;
1371} 1332}
1372 1333
1373static int brcmf_usb_probe_cb(struct device *dev, const char *desc, 1334static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo,
1374 u32 bustype, u32 hdrlen) 1335 const char *desc, u32 bustype, u32 hdrlen)
1375{ 1336{
1376 struct brcmf_bus *bus = NULL; 1337 struct brcmf_bus *bus = NULL;
1377 struct brcmf_usbdev *bus_pub = NULL; 1338 struct brcmf_usbdev *bus_pub = NULL;
1378 int ret; 1339 int ret;
1340 struct device *dev = devinfo->dev;
1379 1341
1380 1342 bus_pub = brcmf_usb_attach(devinfo, BRCMF_USB_NRXQ, BRCMF_USB_NTXQ);
1381 bus_pub = brcmf_usb_attach(BRCMF_USB_NRXQ, BRCMF_USB_NTXQ, dev);
1382 if (!bus_pub) { 1343 if (!bus_pub) {
1383 ret = -ENODEV; 1344 ret = -ENODEV;
1384 goto fail; 1345 goto fail;
@@ -1417,23 +1378,21 @@ static int brcmf_usb_probe_cb(struct device *dev, const char *desc,
1417 return 0; 1378 return 0;
1418fail: 1379fail:
1419 /* Release resources in reverse order */ 1380 /* Release resources in reverse order */
1420 if (bus_pub)
1421 brcmf_usb_detach(bus_pub);
1422 kfree(bus); 1381 kfree(bus);
1382 brcmf_usb_detach(devinfo);
1423 return ret; 1383 return ret;
1424} 1384}
1425 1385
1426static void 1386static void
1427brcmf_usb_disconnect_cb(struct brcmf_usbdev *bus_pub) 1387brcmf_usb_disconnect_cb(struct brcmf_usbdev_info *devinfo)
1428{ 1388{
1429 if (!bus_pub) 1389 if (!devinfo)
1430 return; 1390 return;
1431 brcmf_dbg(TRACE, "enter: bus_pub %p\n", bus_pub); 1391 brcmf_dbg(TRACE, "enter: bus_pub %p\n", devinfo);
1432
1433 brcmf_detach(bus_pub->devinfo->dev);
1434 kfree(bus_pub->bus);
1435 brcmf_usb_detach(bus_pub);
1436 1392
1393 brcmf_detach(devinfo->dev);
1394 kfree(devinfo->bus_pub.bus);
1395 brcmf_usb_detach(devinfo);
1437} 1396}
1438 1397
1439static int 1398static int
@@ -1445,18 +1404,18 @@ brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
1445 struct usb_device *usb = interface_to_usbdev(intf); 1404 struct usb_device *usb = interface_to_usbdev(intf);
1446 int num_of_eps; 1405 int num_of_eps;
1447 u8 endpoint_num; 1406 u8 endpoint_num;
1407 struct brcmf_usbdev_info *devinfo;
1448 1408
1449 brcmf_dbg(TRACE, "enter\n"); 1409 brcmf_dbg(TRACE, "enter\n");
1450 1410
1451 usbdev_probe_info.usb = usb; 1411 devinfo = kzalloc(sizeof(*devinfo), GFP_ATOMIC);
1452 usbdev_probe_info.intf = intf; 1412 if (devinfo == NULL)
1413 return -ENOMEM;
1453 1414
1454 if (id != NULL) { 1415 devinfo->usbdev = usb;
1455 usbdev_probe_info.vid = id->idVendor; 1416 devinfo->dev = &usb->dev;
1456 usbdev_probe_info.pid = id->idProduct;
1457 }
1458 1417
1459 usb_set_intfdata(intf, &usbdev_probe_info); 1418 usb_set_intfdata(intf, devinfo);
1460 1419
1461 /* Check that the device supports only one configuration */ 1420 /* Check that the device supports only one configuration */
1462 if (usb->descriptor.bNumConfigurations != 1) { 1421 if (usb->descriptor.bNumConfigurations != 1) {
@@ -1505,11 +1464,11 @@ brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
1505 } 1464 }
1506 1465
1507 endpoint_num = endpoint->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; 1466 endpoint_num = endpoint->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
1508 usbdev_probe_info.intr_pipe = usb_rcvintpipe(usb, endpoint_num); 1467 devinfo->intr_pipe = usb_rcvintpipe(usb, endpoint_num);
1509 1468
1510 usbdev_probe_info.rx_pipe = 0; 1469 devinfo->rx_pipe = 0;
1511 usbdev_probe_info.rx_pipe2 = 0; 1470 devinfo->rx_pipe2 = 0;
1512 usbdev_probe_info.tx_pipe = 0; 1471 devinfo->tx_pipe = 0;
1513 num_of_eps = IFDESC(usb, BULK_IF).bNumEndpoints - 1; 1472 num_of_eps = IFDESC(usb, BULK_IF).bNumEndpoints - 1;
1514 1473
1515 /* Check data endpoints and get pipes */ 1474 /* Check data endpoints and get pipes */
@@ -1526,35 +1485,33 @@ brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
1526 USB_ENDPOINT_NUMBER_MASK; 1485 USB_ENDPOINT_NUMBER_MASK;
1527 if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) 1486 if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
1528 == USB_DIR_IN) { 1487 == USB_DIR_IN) {
1529 if (!usbdev_probe_info.rx_pipe) { 1488 if (!devinfo->rx_pipe) {
1530 usbdev_probe_info.rx_pipe = 1489 devinfo->rx_pipe =
1531 usb_rcvbulkpipe(usb, endpoint_num); 1490 usb_rcvbulkpipe(usb, endpoint_num);
1532 } else { 1491 } else {
1533 usbdev_probe_info.rx_pipe2 = 1492 devinfo->rx_pipe2 =
1534 usb_rcvbulkpipe(usb, endpoint_num); 1493 usb_rcvbulkpipe(usb, endpoint_num);
1535 } 1494 }
1536 } else { 1495 } else {
1537 usbdev_probe_info.tx_pipe = 1496 devinfo->tx_pipe = usb_sndbulkpipe(usb, endpoint_num);
1538 usb_sndbulkpipe(usb, endpoint_num);
1539 } 1497 }
1540 } 1498 }
1541 1499
1542 /* Allocate interrupt URB and data buffer */ 1500 /* Allocate interrupt URB and data buffer */
1543 /* RNDIS says 8-byte intr, our old drivers used 4-byte */ 1501 /* RNDIS says 8-byte intr, our old drivers used 4-byte */
1544 if (IFEPDESC(usb, CONTROL_IF, 0).wMaxPacketSize == cpu_to_le16(16)) 1502 if (IFEPDESC(usb, CONTROL_IF, 0).wMaxPacketSize == cpu_to_le16(16))
1545 usbdev_probe_info.intr_size = 8; 1503 devinfo->intr_size = 8;
1546 else 1504 else
1547 usbdev_probe_info.intr_size = 4; 1505 devinfo->intr_size = 4;
1548 1506
1549 usbdev_probe_info.interval = IFEPDESC(usb, CONTROL_IF, 0).bInterval; 1507 devinfo->interval = IFEPDESC(usb, CONTROL_IF, 0).bInterval;
1550 1508
1551 usbdev_probe_info.device_speed = usb->speed;
1552 if (usb->speed == USB_SPEED_HIGH) 1509 if (usb->speed == USB_SPEED_HIGH)
1553 brcmf_dbg(INFO, "Broadcom high speed USB wireless device detected\n"); 1510 brcmf_dbg(INFO, "Broadcom high speed USB wireless device detected\n");
1554 else 1511 else
1555 brcmf_dbg(INFO, "Broadcom full speed USB wireless device detected\n"); 1512 brcmf_dbg(INFO, "Broadcom full speed USB wireless device detected\n");
1556 1513
1557 ret = brcmf_usb_probe_cb(&usb->dev, "", USB_BUS, 0); 1514 ret = brcmf_usb_probe_cb(devinfo, "", USB_BUS, 0);
1558 if (ret) 1515 if (ret)
1559 goto fail; 1516 goto fail;
1560 1517
@@ -1563,6 +1520,7 @@ brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
1563 1520
1564fail: 1521fail:
1565 brcmf_dbg(ERROR, "failed with errno %d\n", ret); 1522 brcmf_dbg(ERROR, "failed with errno %d\n", ret);
1523 kfree(devinfo);
1566 usb_set_intfdata(intf, NULL); 1524 usb_set_intfdata(intf, NULL);
1567 return ret; 1525 return ret;
1568 1526
@@ -1571,11 +1529,12 @@ fail:
1571static void 1529static void
1572brcmf_usb_disconnect(struct usb_interface *intf) 1530brcmf_usb_disconnect(struct usb_interface *intf)
1573{ 1531{
1574 struct usb_device *usb = interface_to_usbdev(intf); 1532 struct brcmf_usbdev_info *devinfo;
1575 1533
1576 brcmf_dbg(TRACE, "enter\n"); 1534 brcmf_dbg(TRACE, "enter\n");
1577 brcmf_usb_disconnect_cb(brcmf_usb_get_buspub(&usb->dev)); 1535 devinfo = (struct brcmf_usbdev_info *)usb_get_intfdata(intf);
1578 usb_set_intfdata(intf, NULL); 1536 brcmf_usb_disconnect_cb(devinfo);
1537 kfree(devinfo);
1579} 1538}
1580 1539
1581/* 1540/*