aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/b43/xmit.c
diff options
context:
space:
mode:
authorMichael Buesch <mb@bu3sch.de>2008-01-28 17:47:41 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 18:09:50 -0500
commiteb189d8bc9824bcb2187ffdab27d77ab469264c3 (patch)
tree612c6549f0d0261087b55b157dd5ca016386ddee /drivers/net/wireless/b43/xmit.c
parent243dcfcc1d4b33aa610f1bf3ec610dafdf4d7ff7 (diff)
b43: Add support for new firmware
This patch adds support for new firmware. Old firmware is still supported until July 2008. To get new firmware, go to ftp://ftp.linksys.com/opensourcecode/wrt150nv11/1.51.3/ and download the tarball. We don't have a smaller tarball, yet. That will be fixed later. You can extract firmware out of the "wl_ap.o" file contained in this tarball using latest fwcutter. You must pass the option --unsupported to fwcutter. Fwcutter-010 with official support for a new firmware image will be released soon. Signed-off-by: Michael Buesch <mb@bu3sch.de> Signed-off-by: John W. Linville <linville@tuxdriver.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/wireless/b43/xmit.c')
-rw-r--r--drivers/net/wireless/b43/xmit.c144
1 files changed, 94 insertions, 50 deletions
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c
index 5014213b7752..3fc53e8b4416 100644
--- a/drivers/net/wireless/b43/xmit.c
+++ b/drivers/net/wireless/b43/xmit.c
@@ -177,13 +177,15 @@ static u8 b43_calc_fallback_rate(u8 bitrate)
177 return 0; 177 return 0;
178} 178}
179 179
180static void generate_txhdr_fw4(struct b43_wldev *dev, 180/* Generate a TX data header. */
181 struct b43_txhdr_fw4 *txhdr, 181void b43_generate_txhdr(struct b43_wldev *dev,
182 const unsigned char *fragment_data, 182 u8 *_txhdr,
183 unsigned int fragment_len, 183 const unsigned char *fragment_data,
184 const struct ieee80211_tx_control *txctl, 184 unsigned int fragment_len,
185 u16 cookie) 185 const struct ieee80211_tx_control *txctl,
186 u16 cookie)
186{ 187{
188 struct b43_txhdr *txhdr = (struct b43_txhdr *)_txhdr;
187 const struct b43_phy *phy = &dev->phy; 189 const struct b43_phy *phy = &dev->phy;
188 const struct ieee80211_hdr *wlhdr = 190 const struct ieee80211_hdr *wlhdr =
189 (const struct ieee80211_hdr *)fragment_data; 191 (const struct ieee80211_hdr *)fragment_data;
@@ -241,23 +243,30 @@ static void generate_txhdr_fw4(struct b43_wldev *dev,
241 plcp_fragment_len += txctl->icv_len; 243 plcp_fragment_len += txctl->icv_len;
242 244
243 key_idx = b43_kidx_to_fw(dev, key_idx); 245 key_idx = b43_kidx_to_fw(dev, key_idx);
244 mac_ctl |= (key_idx << B43_TX4_MAC_KEYIDX_SHIFT) & 246 mac_ctl |= (key_idx << B43_TXH_MAC_KEYIDX_SHIFT) &
245 B43_TX4_MAC_KEYIDX; 247 B43_TXH_MAC_KEYIDX;
246 mac_ctl |= (key->algorithm << B43_TX4_MAC_KEYALG_SHIFT) & 248 mac_ctl |= (key->algorithm << B43_TXH_MAC_KEYALG_SHIFT) &
247 B43_TX4_MAC_KEYALG; 249 B43_TXH_MAC_KEYALG;
248 wlhdr_len = ieee80211_get_hdrlen(fctl); 250 wlhdr_len = ieee80211_get_hdrlen(fctl);
249 iv_len = min((size_t) txctl->iv_len, 251 iv_len = min((size_t) txctl->iv_len,
250 ARRAY_SIZE(txhdr->iv)); 252 ARRAY_SIZE(txhdr->iv));
251 memcpy(txhdr->iv, ((u8 *) wlhdr) + wlhdr_len, iv_len); 253 memcpy(txhdr->iv, ((u8 *) wlhdr) + wlhdr_len, iv_len);
252 } 254 }
253 b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)(&txhdr->plcp), 255 if (b43_is_old_txhdr_format(dev)) {
254 plcp_fragment_len, rate); 256 b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)(&txhdr->old_format.plcp),
257 plcp_fragment_len, rate);
258 } else {
259 b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)(&txhdr->new_format.plcp),
260 plcp_fragment_len, rate);
261 }
255 b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)(&txhdr->plcp_fb), 262 b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)(&txhdr->plcp_fb),
256 plcp_fragment_len, rate_fb); 263 plcp_fragment_len, rate_fb);
257 264
258 /* Extra Frame Types */ 265 /* Extra Frame Types */
259 if (rate_fb_ofdm) 266 if (rate_fb_ofdm)
260 extra_ft |= B43_TX4_EFT_FBOFDM; 267 extra_ft |= B43_TXH_EFT_FB_OFDM;
268 else
269 extra_ft |= B43_TXH_EFT_FB_CCK;
261 270
262 /* Set channel radio code. Note that the micrcode ORs 0x100 to 271 /* Set channel radio code. Note that the micrcode ORs 0x100 to
263 * this value before comparing it to the value in SHM, if this 272 * this value before comparing it to the value in SHM, if this
@@ -267,19 +276,27 @@ static void generate_txhdr_fw4(struct b43_wldev *dev,
267 276
268 /* PHY TX Control word */ 277 /* PHY TX Control word */
269 if (rate_ofdm) 278 if (rate_ofdm)
270 phy_ctl |= B43_TX4_PHY_OFDM; 279 phy_ctl |= B43_TXH_PHY_ENC_OFDM;
280 else
281 phy_ctl |= B43_TXH_PHY_ENC_CCK;
271 if (dev->short_preamble) 282 if (dev->short_preamble)
272 phy_ctl |= B43_TX4_PHY_SHORTPRMBL; 283 phy_ctl |= B43_TXH_PHY_SHORTPRMBL;
273 284
274 switch (b43_ieee80211_antenna_sanitize(dev, txctl->antenna_sel_tx)) { 285 switch (b43_ieee80211_antenna_sanitize(dev, txctl->antenna_sel_tx)) {
275 case 0: /* Default */ 286 case 0: /* Default */
276 phy_ctl |= B43_TX4_PHY_ANTLAST; 287 phy_ctl |= B43_TXH_PHY_ANT01AUTO;
277 break; 288 break;
278 case 1: /* Antenna 0 */ 289 case 1: /* Antenna 0 */
279 phy_ctl |= B43_TX4_PHY_ANT0; 290 phy_ctl |= B43_TXH_PHY_ANT0;
280 break; 291 break;
281 case 2: /* Antenna 1 */ 292 case 2: /* Antenna 1 */
282 phy_ctl |= B43_TX4_PHY_ANT1; 293 phy_ctl |= B43_TXH_PHY_ANT1;
294 break;
295 case 3: /* Antenna 2 */
296 phy_ctl |= B43_TXH_PHY_ANT2;
297 break;
298 case 4: /* Antenna 3 */
299 phy_ctl |= B43_TXH_PHY_ANT3;
283 break; 300 break;
284 default: 301 default:
285 B43_WARN_ON(1); 302 B43_WARN_ON(1);
@@ -287,16 +304,16 @@ static void generate_txhdr_fw4(struct b43_wldev *dev,
287 304
288 /* MAC control */ 305 /* MAC control */
289 if (!(txctl->flags & IEEE80211_TXCTL_NO_ACK)) 306 if (!(txctl->flags & IEEE80211_TXCTL_NO_ACK))
290 mac_ctl |= B43_TX4_MAC_ACK; 307 mac_ctl |= B43_TXH_MAC_ACK;
291 if (!(((fctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL) && 308 if (!(((fctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL) &&
292 ((fctl & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PSPOLL))) 309 ((fctl & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PSPOLL)))
293 mac_ctl |= B43_TX4_MAC_HWSEQ; 310 mac_ctl |= B43_TXH_MAC_HWSEQ;
294 if (txctl->flags & IEEE80211_TXCTL_FIRST_FRAGMENT) 311 if (txctl->flags & IEEE80211_TXCTL_FIRST_FRAGMENT)
295 mac_ctl |= B43_TX4_MAC_STMSDU; 312 mac_ctl |= B43_TXH_MAC_STMSDU;
296 if (phy->type == B43_PHYTYPE_A) 313 if (phy->type == B43_PHYTYPE_A)
297 mac_ctl |= B43_TX4_MAC_5GHZ; 314 mac_ctl |= B43_TXH_MAC_5GHZ;
298 if (txctl->flags & IEEE80211_TXCTL_LONG_RETRY_LIMIT) 315 if (txctl->flags & IEEE80211_TXCTL_LONG_RETRY_LIMIT)
299 mac_ctl |= B43_TX4_MAC_LONGFRAME; 316 mac_ctl |= B43_TXH_MAC_LONGFRAME;
300 317
301 /* Generate the RTS or CTS-to-self frame */ 318 /* Generate the RTS or CTS-to-self frame */
302 if ((txctl->flags & IEEE80211_TXCTL_USE_RTS_CTS) || 319 if ((txctl->flags & IEEE80211_TXCTL_USE_RTS_CTS) ||
@@ -305,6 +322,7 @@ static void generate_txhdr_fw4(struct b43_wldev *dev,
305 struct ieee80211_hdr *hdr; 322 struct ieee80211_hdr *hdr;
306 int rts_rate, rts_rate_fb; 323 int rts_rate, rts_rate_fb;
307 int rts_rate_ofdm, rts_rate_fb_ofdm; 324 int rts_rate_ofdm, rts_rate_fb_ofdm;
325 struct b43_plcp_hdr6 *plcp;
308 326
309 rts_rate = txctl->rts_cts_rate; 327 rts_rate = txctl->rts_cts_rate;
310 rts_rate_ofdm = b43_is_ofdm_rate(rts_rate); 328 rts_rate_ofdm = b43_is_ofdm_rate(rts_rate);
@@ -312,58 +330,84 @@ static void generate_txhdr_fw4(struct b43_wldev *dev,
312 rts_rate_fb_ofdm = b43_is_ofdm_rate(rts_rate_fb); 330 rts_rate_fb_ofdm = b43_is_ofdm_rate(rts_rate_fb);
313 331
314 if (txctl->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) { 332 if (txctl->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) {
333 struct ieee80211_cts *cts;
334
335 if (b43_is_old_txhdr_format(dev)) {
336 cts = (struct ieee80211_cts *)
337 (txhdr->old_format.rts_frame);
338 } else {
339 cts = (struct ieee80211_cts *)
340 (txhdr->new_format.rts_frame);
341 }
315 ieee80211_ctstoself_get(dev->wl->hw, txctl->vif, 342 ieee80211_ctstoself_get(dev->wl->hw, txctl->vif,
316 fragment_data, fragment_len, 343 fragment_data, fragment_len,
317 txctl, 344 txctl, cts);
318 (struct ieee80211_cts *)(txhdr-> 345 mac_ctl |= B43_TXH_MAC_SENDCTS;
319 rts_frame));
320 mac_ctl |= B43_TX4_MAC_SENDCTS;
321 len = sizeof(struct ieee80211_cts); 346 len = sizeof(struct ieee80211_cts);
322 } else { 347 } else {
348 struct ieee80211_rts *rts;
349
350 if (b43_is_old_txhdr_format(dev)) {
351 rts = (struct ieee80211_rts *)
352 (txhdr->old_format.rts_frame);
353 } else {
354 rts = (struct ieee80211_rts *)
355 (txhdr->new_format.rts_frame);
356 }
323 ieee80211_rts_get(dev->wl->hw, txctl->vif, 357 ieee80211_rts_get(dev->wl->hw, txctl->vif,
324 fragment_data, fragment_len, txctl, 358 fragment_data, fragment_len,
325 (struct ieee80211_rts *)(txhdr-> 359 txctl, rts);
326 rts_frame)); 360 mac_ctl |= B43_TXH_MAC_SENDRTS;
327 mac_ctl |= B43_TX4_MAC_SENDRTS;
328 len = sizeof(struct ieee80211_rts); 361 len = sizeof(struct ieee80211_rts);
329 } 362 }
330 len += FCS_LEN; 363 len += FCS_LEN;
331 b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)(&txhdr-> 364
332 rts_plcp), len, 365 /* Generate the PLCP headers for the RTS/CTS frame */
333 rts_rate); 366 if (b43_is_old_txhdr_format(dev))
334 b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)(&txhdr-> 367 plcp = &txhdr->old_format.rts_plcp;
335 rts_plcp_fb), 368 else
369 plcp = &txhdr->new_format.rts_plcp;
370 b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)plcp,
371 len, rts_rate);
372 plcp = &txhdr->rts_plcp_fb;
373 b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)plcp,
336 len, rts_rate_fb); 374 len, rts_rate_fb);
337 hdr = (struct ieee80211_hdr *)(&txhdr->rts_frame); 375
376 if (b43_is_old_txhdr_format(dev)) {
377 hdr = (struct ieee80211_hdr *)
378 (&txhdr->old_format.rts_frame);
379 } else {
380 hdr = (struct ieee80211_hdr *)
381 (&txhdr->new_format.rts_frame);
382 }
338 txhdr->rts_dur_fb = hdr->duration_id; 383 txhdr->rts_dur_fb = hdr->duration_id;
384
339 if (rts_rate_ofdm) { 385 if (rts_rate_ofdm) {
340 extra_ft |= B43_TX4_EFT_RTSOFDM; 386 extra_ft |= B43_TXH_EFT_RTS_OFDM;
341 txhdr->phy_rate_rts = 387 txhdr->phy_rate_rts =
342 b43_plcp_get_ratecode_ofdm(rts_rate); 388 b43_plcp_get_ratecode_ofdm(rts_rate);
343 } else 389 } else {
390 extra_ft |= B43_TXH_EFT_RTS_CCK;
344 txhdr->phy_rate_rts = 391 txhdr->phy_rate_rts =
345 b43_plcp_get_ratecode_cck(rts_rate); 392 b43_plcp_get_ratecode_cck(rts_rate);
393 }
346 if (rts_rate_fb_ofdm) 394 if (rts_rate_fb_ofdm)
347 extra_ft |= B43_TX4_EFT_RTSFBOFDM; 395 extra_ft |= B43_TXH_EFT_RTSFB_OFDM;
396 else
397 extra_ft |= B43_TXH_EFT_RTSFB_CCK;
348 } 398 }
349 399
350 /* Magic cookie */ 400 /* Magic cookie */
351 txhdr->cookie = cpu_to_le16(cookie); 401 if (b43_is_old_txhdr_format(dev))
402 txhdr->old_format.cookie = cpu_to_le16(cookie);
403 else
404 txhdr->new_format.cookie = cpu_to_le16(cookie);
352 405
353 /* Apply the bitfields */ 406 /* Apply the bitfields */
354 txhdr->mac_ctl = cpu_to_le32(mac_ctl); 407 txhdr->mac_ctl = cpu_to_le32(mac_ctl);
355 txhdr->phy_ctl = cpu_to_le16(phy_ctl); 408 txhdr->phy_ctl = cpu_to_le16(phy_ctl);
356 txhdr->extra_ft = extra_ft; 409 txhdr->extra_ft = extra_ft;
357}
358 410
359void b43_generate_txhdr(struct b43_wldev *dev,
360 u8 * txhdr,
361 const unsigned char *fragment_data,
362 unsigned int fragment_len,
363 const struct ieee80211_tx_control *txctl, u16 cookie)
364{
365 generate_txhdr_fw4(dev, (struct b43_txhdr_fw4 *)txhdr,
366 fragment_data, fragment_len, txctl, cookie);
367} 411}
368 412
369static s8 b43_rssi_postprocess(struct b43_wldev *dev, 413static s8 b43_rssi_postprocess(struct b43_wldev *dev,