#define MX140_FW_VARIANT_DEFAULT "mx140"
+#define MX140_FW_MAC_FILE_SIZE (24)
+
/* Table of suffixes to append to f/w name */
struct fw_suffix {
char suffix[6];
}
EXPORT_SYMBOL(mx140_request_file);
+int mx140_request_proc_file(struct scsc_mx *mx, char *path, const struct firmware **firmp)
+{
+ struct file *f;
+ mm_segment_t fs;
+ struct kstat stat;
+ int r;
+ struct firmware *firm;
+ char *buf;
+
+ SCSC_TAG_DEBUG(MX_FILE, "request proc %s\n", path);
+
+ *firmp = NULL;
+
+ /* Current segment. */
+ fs = get_fs();
+ /* Set to kernel segment. */
+ set_fs(get_ds());
+
+ /* Check f/w bin */
+ r = vfs_stat(path, &stat);
+ if (r != 0) {
+ set_fs(fs);
+ SCSC_TAG_ERR(MX_FILE, "vfs_stat() failed for %s\n", path);
+ return -ENOENT;
+ }
+ /* Revert to original segment. */
+ set_fs(fs);
+
+ /* Get memory for file contents. */
+ buf = vzalloc(MX140_FW_MAC_FILE_SIZE);
+ if (!buf) {
+ SCSC_TAG_ERR(MX_FILE, "kzalloc(%d) failed for %s\n", MX140_FW_MAC_FILE_SIZE, path);
+ return -ENOMEM;
+ }
+
+ /* Get firmware structure. */
+ firm = kzalloc(sizeof(*firm), GFP_KERNEL);
+ if (!firm) {
+ vfree(buf);
+ SCSC_TAG_ERR(MX_FILE, "kzalloc(%zu) failed for %s\n", sizeof(*firmp), path);
+ return -ENOMEM;
+ }
+
+ /* Open the file for reading. */
+ f = filp_open(path, O_RDONLY, 0);
+ if (IS_ERR(f)) {
+ vfree(buf);
+ kfree(firm);
+ SCSC_TAG_ERR(MX_FILE, "filp_open() failed for %s with %ld\n", path, PTR_ERR(f));
+ return -ENOENT;
+ }
+
+ fs = get_fs();
+ set_fs(get_ds());
+
+ r = vfs_read(f, buf, MX140_FW_MAC_FILE_SIZE, &f->f_pos);
+ if (r < 0) {
+ SCSC_TAG_ERR(MX_FILE, "error reading %s\n", path);
+ return -ENOENT;
+ }
+
+ set_fs(fs);
+ filp_close(f, NULL);
+
+ if (r >= 0) {
+ r = 0;
+ /* Pass to caller. Caller will free allocated memory through
+ * mx140_release_file().
+ */
+ firm->size = MX140_FW_MAC_FILE_SIZE;
+ firm->data = buf;
+ *firmp = firm;
+ } else {
+ vfree(buf);
+ kfree(firm);
+ }
+ return r;
+}
+EXPORT_SYMBOL(mx140_request_proc_file);
+
+
int mx140_release_file(struct scsc_mx *mx, const struct firmware *firmp)
{
if (!firmp || !firmp->data) {
SCSC_TAG_DEBUG(BT_COMMON,
"loading Bluetooth address configuration file: "
SCSC_BT_ADDR "\n");
- err = mx140_request_file(common_service.maxwell_core, SCSC_BT_ADDR, &firm);
+ err = mx140_request_proc_file(common_service.maxwell_core, SCSC_BT_ADDR, &firm);
if (err) {
/* Not found - just silently ignore this */
SCSC_TAG_DEBUG(BT_COMMON, "Bluetooth address not found\n");
#define SCSC_BT_ADDR "/csa/bluetooth/.bd_addr"
#define SCSC_BT_ADDR_LEN (3)
#else
-#define SCSC_BT_ADDR "/mnt/vendor/efs/bluetooth/bt_addr"
+#define SCSC_BT_ADDR "/proc/config/bt_mac/ascii"
#define SCSC_BT_ADDR_LEN (6)
#endif
int r;
/* read maddr_file */
- if (sdev->maddr_file_name) {
- scnprintf(path_name, MX_WLAN_FILE_PATH_LEN_MAX, "wlan/%s", sdev->maddr_file_name);
- SLSI_DBG1(sdev, SLSI_INIT_DEINIT, "MAC address file : %s\n", path_name);
+ r = mx140_request_proc_file(sdev->maxwell_core, SLSI_WIFI_ADDR, &e);
- r = mx140_file_request_device_conf(sdev->maxwell_core, &e, path_name);
- if (r != 0)
- goto mac_efs;
+ if (r != 0)
+ goto mac_efs;
- if (!e) {
- SLSI_ERR(sdev, "mx140_file_request_device_conf() returned succes, but firmware was null\n");
- goto mac_efs;
- }
- r = sscanf(e->data, "%02X:%02X:%02X:%02X:%02X:%02X", &u[0], &u[1], &u[2], &u[3], &u[4], &u[5]);
- mx140_file_release_conf(sdev->maxwell_core, e);
- if (r != ETH_ALEN) {
- SLSI_ERR(sdev, "%s exists, but format is incorrect (should be e.g. xx:xx:xx:xx:xx:xx)\n", path_name);
- goto mac_efs;
- }
- for (i = 0; i < ETH_ALEN; i++)
- addr[i] = u[i] & 0xff;
- SLSI_INFO(sdev, "MAC address loaded from %s: %02X:%02X:%02X:%02X:%02X:%02X\n", path_name, u[0], u[1], u[2], u[3], u[4], u[5]);
- return;
+ if (!e) {
+ SLSI_ERR(sdev, "mx140_file_request_device_conf() returned succes, but firmware was null\n");
+ goto mac_efs;
+ }
+ r = sscanf(e->data, "%02X:%02X:%02X:%02X:%02X:%02X", &u[0], &u[1], &u[2], &u[3], &u[4], &u[5]);
+ mx140_file_release_conf(sdev->maxwell_core, e);
+ if (r != ETH_ALEN) {
+ SLSI_ERR(sdev, "%s exists, but format is incorrect (should be e.g. xx:xx:xx:xx:xx:xx)\n", SLSI_WIFI_ADDR);
+ goto mac_efs;
}
+ for (i = 0; i < ETH_ALEN; i++)
+ addr[i] = u[i] & 0xff;
+ SLSI_INFO(sdev, "MAC address loaded from %s: %02X:%02X:%02X:%02X:%02X:%02X\n", path_name, u[0], u[1], u[2], u[3], u[4], u[5]);
+ return;
+
mac_efs:
#ifdef CONFIG_SCSC_WLAN_MAC_ADDRESS_FILENAME
r = mx140_request_file(sdev->maxwell_core, CONFIG_SCSC_WLAN_MAC_ADDRESS_FILENAME, &e);
for (i = 0; i < ETH_ALEN; i++)
addr[i] = u[i] & 0xff;
SLSI_INFO(sdev, "MAC address loaded from %s: %02X:%02X:%02X:%02X:%02X:%02X\n", CONFIG_SCSC_WLAN_MAC_ADDRESS_FILENAME, u[0], u[1], u[2], u[3], u[4], u[5]);
+
+ /* MAC address in efs could be invalid, try to fix it to normal address */
+ if (addr[0] & 0x01) {
+ addr[0] = addr[0] & 0xfe;
+ SLSI_INFO(sdev, "MAC address invalid, fixed address: %pM", addr);
+ }
mx140_release_file(sdev->maxwell_core, e);
return;
#endif
#define SLSI_RX_SEQ_NUM_MASK 0xFFF
#define SLSI_RX_VIA_TDLS_LINK 0x8000
+#define SLSI_WIFI_ADDR "/proc/config/wifi_mac/ascii"
+
#define SET_ETHERTYPE_PATTERN_DESC(pd, ethertype) \
pd.offset = 0x0C; \
pd.mask_length = 2; \
*/
int mx140_request_file(struct scsc_mx *mx, char *path, const struct firmware **firmp);
+/* Read device configuration proc file into memory.
+ *
+ * Path is absolute.
+ * Returns pointer to data or NULL if file not found.
+ * Call mx140_release_file() to release the memory.
+ */
+int mx140_request_proc_file(struct scsc_mx *mx, char *path, const struct firmware **firmp);
+
/* Release configuration file memory allocated with mx140_request_file()
*
* If firmp is NULL, has no effect.