@@ -101,7 +101,7 @@ void brcmf_c_set_joinpref_default(struct brcmf_if *ifp)
101101
102102static int brcmf_c_download (struct brcmf_if * ifp , u16 flag ,
103103 struct brcmf_dload_data_le * dload_buf ,
104- u32 len )
104+ u32 len , const char * var )
105105{
106106 s32 err ;
107107
@@ -111,18 +111,18 @@ static int brcmf_c_download(struct brcmf_if *ifp, u16 flag,
111111 dload_buf -> len = cpu_to_le32 (len );
112112 dload_buf -> crc = cpu_to_le32 (0 );
113113
114- err = brcmf_fil_iovar_data_set (ifp , "clmload" , dload_buf ,
114+ err = brcmf_fil_iovar_data_set (ifp , var , dload_buf ,
115115 struct_size (dload_buf , data , len ));
116116
117117 return err ;
118118}
119119
120- static int brcmf_c_process_clm_blob (struct brcmf_if * ifp )
120+ static int brcmf_c_download_blob (struct brcmf_if * ifp ,
121+ const void * data , size_t size ,
122+ const char * loadvar , const char * statvar )
121123{
122124 struct brcmf_pub * drvr = ifp -> drvr ;
123- struct brcmf_bus * bus = drvr -> bus_if ;
124125 struct brcmf_dload_data_le * chunk_buf ;
125- const struct firmware * clm = NULL ;
126126 u32 chunk_len ;
127127 u32 datalen ;
128128 u32 cumulative_len ;
@@ -132,21 +132,14 @@ static int brcmf_c_process_clm_blob(struct brcmf_if *ifp)
132132
133133 brcmf_dbg (TRACE , "Enter\n" );
134134
135- err = brcmf_bus_get_blob (bus , & clm , BRCMF_BLOB_CLM );
136- if (err || !clm ) {
137- brcmf_info ("no clm_blob available (err=%d), device may have limited channels available\n" ,
138- err );
139- return 0 ;
140- }
141-
142135 chunk_buf = kzalloc (struct_size (chunk_buf , data , MAX_CHUNK_LEN ),
143136 GFP_KERNEL );
144137 if (!chunk_buf ) {
145138 err = - ENOMEM ;
146- goto done ;
139+ return - ENOMEM ;
147140 }
148141
149- datalen = clm -> size ;
142+ datalen = size ;
150143 cumulative_len = 0 ;
151144 do {
152145 if (datalen > MAX_CHUNK_LEN ) {
@@ -155,9 +148,10 @@ static int brcmf_c_process_clm_blob(struct brcmf_if *ifp)
155148 chunk_len = datalen ;
156149 dl_flag |= DL_END ;
157150 }
158- memcpy (chunk_buf -> data , clm -> data + cumulative_len , chunk_len );
151+ memcpy (chunk_buf -> data , data + cumulative_len , chunk_len );
159152
160- err = brcmf_c_download (ifp , dl_flag , chunk_buf , chunk_len );
153+ err = brcmf_c_download (ifp , dl_flag , chunk_buf , chunk_len ,
154+ loadvar );
161155
162156 dl_flag &= ~DL_BEGIN ;
163157
@@ -166,20 +160,64 @@ static int brcmf_c_process_clm_blob(struct brcmf_if *ifp)
166160 } while ((datalen > 0 ) && (err == 0 ));
167161
168162 if (err ) {
169- bphy_err (drvr , "clmload (%zu byte file) failed (%d)\n" ,
170- clm -> size , err );
171- /* Retrieve clmload_status and print */
172- err = brcmf_fil_iovar_int_get (ifp , "clmload_status" , & status );
163+ bphy_err (drvr , "%s (%zu byte file) failed (%d)\n" ,
164+ loadvar , size , err );
165+ /* Retrieve status and print */
166+ err = brcmf_fil_iovar_int_get (ifp , statvar , & status );
173167 if (err )
174- bphy_err (drvr , "get clmload_status failed (%d)\n" , err );
168+ bphy_err (drvr , "get %s failed (%d)\n" , statvar , err );
175169 else
176- brcmf_dbg (INFO , "clmload_status =%d\n" , status );
170+ brcmf_dbg (INFO , "%s =%d\n" , statvar , status );
177171 err = - EIO ;
178172 }
179173
180174 kfree (chunk_buf );
181- done :
182- release_firmware (clm );
175+ return err ;
176+ }
177+
178+ static int brcmf_c_process_clm_blob (struct brcmf_if * ifp )
179+ {
180+ struct brcmf_pub * drvr = ifp -> drvr ;
181+ struct brcmf_bus * bus = drvr -> bus_if ;
182+ const struct firmware * fw = NULL ;
183+ s32 err ;
184+
185+ brcmf_dbg (TRACE , "Enter\n" );
186+
187+ err = brcmf_bus_get_blob (bus , & fw , BRCMF_BLOB_CLM );
188+ if (err || !fw ) {
189+ brcmf_info ("no clm_blob available (err=%d), device may have limited channels available\n" ,
190+ err );
191+ return 0 ;
192+ }
193+
194+ err = brcmf_c_download_blob (ifp , fw -> data , fw -> size ,
195+ "clmload" , "clmload_status" );
196+
197+ release_firmware (fw );
198+ return err ;
199+ }
200+
201+ static int brcmf_c_process_txcap_blob (struct brcmf_if * ifp )
202+ {
203+ struct brcmf_pub * drvr = ifp -> drvr ;
204+ struct brcmf_bus * bus = drvr -> bus_if ;
205+ const struct firmware * fw = NULL ;
206+ s32 err ;
207+
208+ brcmf_dbg (TRACE , "Enter\n" );
209+
210+ err = brcmf_bus_get_blob (bus , & fw , BRCMF_BLOB_TXCAP );
211+ if (err || !fw ) {
212+ brcmf_info ("no txcap_blob available (err=%d)\n" , err );
213+ return 0 ;
214+ }
215+
216+ brcmf_info ("TxCap blob found, loading\n" );
217+ err = brcmf_c_download_blob (ifp , fw -> data , fw -> size ,
218+ "txcapload" , "txcapload_status" );
219+
220+ release_firmware (fw );
183221 return err ;
184222}
185223
@@ -291,6 +329,13 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
291329 goto done ;
292330 }
293331
332+ /* Do TxCap downloading, if needed */
333+ err = brcmf_c_process_txcap_blob (ifp );
334+ if (err < 0 ) {
335+ bphy_err (drvr , "download TxCap blob file failed, %d\n" , err );
336+ goto done ;
337+ }
338+
294339 /* query for 'ver' to get version info from firmware */
295340 memset (buf , 0 , sizeof (buf ));
296341 err = brcmf_fil_iovar_data_get (ifp , "ver" , buf , sizeof (buf ));
0 commit comments