]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/net/wireless/brcm80211/brcmfmac/nvram.c
brcmfmac: Create common nvram parsing routines.
[karo-tx-linux.git] / drivers / net / wireless / brcm80211 / brcmfmac / nvram.c
1 /*
2  * Copyright (c) 2013 Broadcom Corporation
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16
17 #include <linux/kernel.h>
18 #include <linux/slab.h>
19 #include <linux/firmware.h>
20
21 #include "nvram.h"
22
23 /* brcmf_nvram_strip :Takes a buffer of "<var>=<value>\n" lines read from a file
24  * and ending in a NUL. Removes carriage returns, empty lines, comment lines,
25  * and converts newlines to NULs. Shortens buffer as needed and pads with NULs.
26  * End of buffer is completed with token identifying length of buffer.
27  */
28 void *brcmf_nvram_strip(const struct firmware *nv, u32 *new_length)
29 {
30         u8 *nvram;
31         u32 i;
32         u32 len;
33         u32 column;
34         u8 val;
35         bool comment;
36         u32 token;
37         __le32 token_le;
38
39         /* Alloc for extra 0 byte + roundup by 4 + length field */
40         nvram = kmalloc(nv->size + 1 + 3 + sizeof(token_le), GFP_KERNEL);
41         if (!nvram)
42                 return NULL;
43
44         len = 0;
45         column = 0;
46         comment = false;
47         for (i = 0; i < nv->size; i++) {
48                 val = nv->data[i];
49                 if (val == 0)
50                         break;
51                 if (val == '\r')
52                         continue;
53                 if (comment && (val != '\n'))
54                         continue;
55                 comment = false;
56                 if (val == '#') {
57                         comment = true;
58                         continue;
59                 }
60                 if (val == '\n') {
61                         if (column == 0)
62                                 continue;
63                         nvram[len] = 0;
64                         len++;
65                         column = 0;
66                         continue;
67                 }
68                 nvram[len] = val;
69                 len++;
70                 column++;
71         }
72         column = len;
73         *new_length = roundup(len + 1, 4);
74         while (column != *new_length) {
75                 nvram[column] = 0;
76                 column++;
77         }
78
79         token = *new_length / 4;
80         token = (~token << 16) | (token & 0x0000FFFF);
81         token_le = cpu_to_le32(token);
82
83         memcpy(&nvram[*new_length], &token_le, sizeof(token_le));
84         *new_length += sizeof(token_le);
85
86         return nvram;
87 }
88
89 void brcmf_nvram_free(void *nvram)
90 {
91         kfree(nvram);
92 }
93
94