2013/12/20 Arend van Spriel <arend@xxxxxxxxxxxx>: > On 12/20/2013 08:57 AM, Rafał Miłecki wrote: >> 2013/12/19 Arend van Spriel <arend@xxxxxxxxxxxx>: >>> It is in the kernel tree under >>> 'drivers/net/wireless/brcm80211/brcmfmac'. We only support rev 3 because >>> rev 2 and earlier do not have enough memory to run fullmac firmware. >>> However, I have not found any rev 3 on the market. If you have please >>> let me know. >> >> Could you say something more about rev 2? How does it work with >> internal Broadcom driver? Is the firmware stored somewhere else? Does >> it have some another kind of memory? > > It has a split-mac design. So at one end the spectrum there is > mac80211-type drivers and at the other side are fullmac drivers like > brcmfmac. rev 2 driver sits right in the middle of that with part of the > 802.11 stack running on the host and part on the device. This device has > not enough memory to run the fullmac firmware. Thanks for your explanation. I think I understand now what means WLC_HIGH, WLC_LOW, WLC_SPLIT you can see in 0001-Staging-Add-initial-release-of-brcm80211-Broadcom-80.patch. I guess that softmac devices need WLC_HIGH and WLC_LOW, split devices (like BCM43231) need WLC_HIGH (because LOW is implemented in firmware) and full MAC devices need none of above. As questions about these chipset come over and over, I added a new section to the brcm80211 wiki page: http://wireless.kernel.org/en/users/Drivers/brcm80211#Unsupported_Chips I hope it's OK for you. Btw. if anyone is interested, I've written a minimal user-space app to read device info (DL_GETVER) from Broadcom USB dongle. gcc -lusb-1.0 main.c -o bcmid -- Rafał
#include <stdio.h> #include <endian.h> #include <libusb-1.0/libusb.h> #define BCM_VENDOR_ID 0x0846 #define BCM_DEVICE_ID 0x9011 #define DL_GETVER 5 struct bcmusb_id { uint32_t chip; uint32_t chiprev; /* Below are returned by recent cards only */ uint32_t ramsize; uint32_t remapbase; uint32_t boardtype; uint32_t boardrev; }; int main() { libusb_context *context = NULL; libusb_device_handle *handle; struct bcmusb_id id; int bytes, err; libusb_init(&context); handle = libusb_open_device_with_vid_pid(context, BCM_VENDOR_ID, BCM_DEVICE_ID); if (!handle) { printf("Couldn't find/open %04X:%04X device (is it available? are you root?)\n", BCM_VENDOR_ID, BCM_DEVICE_ID); return -1; } err = libusb_claim_interface(handle, 0); if (err) { printf("Couldn't claim %04X:%04X device interface (another driver using it?)\n", BCM_VENDOR_ID, BCM_DEVICE_ID); return -2; } bytes = libusb_control_transfer(handle, LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_INTERFACE, DL_GETVER, 0, /* wValue */ 0, /* wIndex */ (unsigned char *)&id, sizeof(struct bcmusb_id), 500); if (bytes < 0) { printf("libusb_control_transfer error: %d\n", bytes); return bytes; } if (bytes == 8 || bytes == 24) { printf("[id] chip: %04X\n", le32toh(id.chip)); printf("[id] chiprev: %04X\n", le32toh(id.chiprev)); if (bytes == 24) { printf("[id] ramsize: %04X\n", le32toh(id.ramsize)); printf("[id] remapbase: %04X\n", le32toh(id.remapbase)); printf("[id] boardtype: %04X\n", le32toh(id.boardtype)); printf("[id] boardrev: %04X\n", le32toh(id.boardrev)); } } else { printf("libusb_control_transfer returned unexpected amount of bytes (%d)\n", bytes); return -3; } err = libusb_release_interface(handle, 0); if (err) { printf("Couldn't release %04X:%04X device interface\n", BCM_VENDOR_ID, BCM_DEVICE_ID); return -4; } libusb_close(handle); libusb_exit(context); }