aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
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
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')
-rw-r--r--drivers/net/wireless/b43/dma.c22
-rw-r--r--drivers/net/wireless/b43/main.c50
-rw-r--r--drivers/net/wireless/b43/phy.h2
-rw-r--r--drivers/net/wireless/b43/xmit.c144
-rw-r--r--drivers/net/wireless/b43/xmit.h200
5 files changed, 289 insertions, 129 deletions
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c
index cf92853a2180..3e73d2a523aa 100644
--- a/drivers/net/wireless/b43/dma.c
+++ b/drivers/net/wireless/b43/dma.c
@@ -807,7 +807,7 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
807 goto err_kfree_ring; 807 goto err_kfree_ring;
808 if (for_tx) { 808 if (for_tx) {
809 ring->txhdr_cache = kcalloc(nr_slots, 809 ring->txhdr_cache = kcalloc(nr_slots,
810 sizeof(struct b43_txhdr_fw4), 810 b43_txhdr_size(dev),
811 GFP_KERNEL); 811 GFP_KERNEL);
812 if (!ring->txhdr_cache) 812 if (!ring->txhdr_cache)
813 goto err_kfree_meta; 813 goto err_kfree_meta;
@@ -815,22 +815,21 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
815 /* test for ability to dma to txhdr_cache */ 815 /* test for ability to dma to txhdr_cache */
816 dma_test = dma_map_single(dev->dev->dev, 816 dma_test = dma_map_single(dev->dev->dev,
817 ring->txhdr_cache, 817 ring->txhdr_cache,
818 sizeof(struct b43_txhdr_fw4), 818 b43_txhdr_size(dev),
819 DMA_TO_DEVICE); 819 DMA_TO_DEVICE);
820 820
821 if (dma_mapping_error(dma_test)) { 821 if (dma_mapping_error(dma_test)) {
822 /* ugh realloc */ 822 /* ugh realloc */
823 kfree(ring->txhdr_cache); 823 kfree(ring->txhdr_cache);
824 ring->txhdr_cache = kcalloc(nr_slots, 824 ring->txhdr_cache = kcalloc(nr_slots,
825 sizeof(struct 825 b43_txhdr_size(dev),
826 b43_txhdr_fw4),
827 GFP_KERNEL | GFP_DMA); 826 GFP_KERNEL | GFP_DMA);
828 if (!ring->txhdr_cache) 827 if (!ring->txhdr_cache)
829 goto err_kfree_meta; 828 goto err_kfree_meta;
830 829
831 dma_test = dma_map_single(dev->dev->dev, 830 dma_test = dma_map_single(dev->dev->dev,
832 ring->txhdr_cache, 831 ring->txhdr_cache,
833 sizeof(struct b43_txhdr_fw4), 832 b43_txhdr_size(dev),
834 DMA_TO_DEVICE); 833 DMA_TO_DEVICE);
835 834
836 if (dma_mapping_error(dma_test)) 835 if (dma_mapping_error(dma_test))
@@ -838,7 +837,7 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
838 } 837 }
839 838
840 dma_unmap_single(dev->dev->dev, 839 dma_unmap_single(dev->dev->dev,
841 dma_test, sizeof(struct b43_txhdr_fw4), 840 dma_test, b43_txhdr_size(dev),
842 DMA_TO_DEVICE); 841 DMA_TO_DEVICE);
843 } 842 }
844 843
@@ -1122,6 +1121,7 @@ static int dma_tx_fragment(struct b43_dmaring *ring,
1122 struct b43_dmadesc_meta *meta_hdr; 1121 struct b43_dmadesc_meta *meta_hdr;
1123 struct sk_buff *bounce_skb; 1122 struct sk_buff *bounce_skb;
1124 u16 cookie; 1123 u16 cookie;
1124 size_t hdrsize = b43_txhdr_size(ring->dev);
1125 1125
1126#define SLOTS_PER_PACKET 2 1126#define SLOTS_PER_PACKET 2
1127 B43_WARN_ON(skb_shinfo(skb)->nr_frags); 1127 B43_WARN_ON(skb_shinfo(skb)->nr_frags);
@@ -1131,17 +1131,17 @@ static int dma_tx_fragment(struct b43_dmaring *ring,
1131 desc = ops->idx2desc(ring, slot, &meta_hdr); 1131 desc = ops->idx2desc(ring, slot, &meta_hdr);
1132 memset(meta_hdr, 0, sizeof(*meta_hdr)); 1132 memset(meta_hdr, 0, sizeof(*meta_hdr));
1133 1133
1134 header = &(ring->txhdr_cache[slot * sizeof(struct b43_txhdr_fw4)]); 1134 header = &(ring->txhdr_cache[slot * hdrsize]);
1135 cookie = generate_cookie(ring, slot); 1135 cookie = generate_cookie(ring, slot);
1136 b43_generate_txhdr(ring->dev, header, 1136 b43_generate_txhdr(ring->dev, header,
1137 skb->data, skb->len, ctl, cookie); 1137 skb->data, skb->len, ctl, cookie);
1138 1138
1139 meta_hdr->dmaaddr = map_descbuffer(ring, (unsigned char *)header, 1139 meta_hdr->dmaaddr = map_descbuffer(ring, (unsigned char *)header,
1140 sizeof(struct b43_txhdr_fw4), 1); 1140 hdrsize, 1);
1141 if (dma_mapping_error(meta_hdr->dmaaddr)) 1141 if (dma_mapping_error(meta_hdr->dmaaddr))
1142 return -EIO; 1142 return -EIO;
1143 ops->fill_descriptor(ring, desc, meta_hdr->dmaaddr, 1143 ops->fill_descriptor(ring, desc, meta_hdr->dmaaddr,
1144 sizeof(struct b43_txhdr_fw4), 1, 0, 0); 1144 hdrsize, 1, 0, 0);
1145 1145
1146 /* Get a slot for the payload. */ 1146 /* Get a slot for the payload. */
1147 slot = request_slot(ring); 1147 slot = request_slot(ring);
@@ -1189,7 +1189,7 @@ out_free_bounce:
1189 dev_kfree_skb_any(skb); 1189 dev_kfree_skb_any(skb);
1190out_unmap_hdr: 1190out_unmap_hdr:
1191 unmap_descbuffer(ring, meta_hdr->dmaaddr, 1191 unmap_descbuffer(ring, meta_hdr->dmaaddr,
1192 sizeof(struct b43_txhdr_fw4), 1); 1192 hdrsize, 1);
1193 return err; 1193 return err;
1194} 1194}
1195 1195
@@ -1298,7 +1298,7 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
1298 1); 1298 1);
1299 else 1299 else
1300 unmap_descbuffer(ring, meta->dmaaddr, 1300 unmap_descbuffer(ring, meta->dmaaddr,
1301 sizeof(struct b43_txhdr_fw4), 1); 1301 b43_txhdr_size(dev), 1);
1302 1302
1303 if (meta->is_last_fragment) { 1303 if (meta->is_last_fragment) {
1304 B43_WARN_ON(!meta->skb); 1304 B43_WARN_ON(!meta->skb);
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 481bc8238e7c..560d1421e679 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -1569,11 +1569,17 @@ static void b43_release_firmware(struct b43_wldev *dev)
1569 dev->fw.initvals_band = NULL; 1569 dev->fw.initvals_band = NULL;
1570} 1570}
1571 1571
1572static void b43_print_fw_helptext(struct b43_wl *wl) 1572static void b43_print_fw_helptext(struct b43_wl *wl, bool error)
1573{ 1573{
1574 b43err(wl, "You must go to " 1574 const char *text;
1575
1576 text = "You must go to "
1575 "http://linuxwireless.org/en/users/Drivers/b43#devicefirmware " 1577 "http://linuxwireless.org/en/users/Drivers/b43#devicefirmware "
1576 "and download the correct firmware (version 4).\n"); 1578 "and download the latest firmware (version 4).\n";
1579 if (error)
1580 b43err(wl, text);
1581 else
1582 b43warn(wl, text);
1577} 1583}
1578 1584
1579static int do_request_fw(struct b43_wldev *dev, 1585static int do_request_fw(struct b43_wldev *dev,
@@ -1725,7 +1731,7 @@ static int b43_request_firmware(struct b43_wldev *dev)
1725 return 0; 1731 return 0;
1726 1732
1727err_load: 1733err_load:
1728 b43_print_fw_helptext(dev->wl); 1734 b43_print_fw_helptext(dev->wl, 1);
1729 goto error; 1735 goto error;
1730 1736
1731err_no_ucode: 1737err_no_ucode:
@@ -1795,7 +1801,7 @@ static int b43_upload_microcode(struct b43_wldev *dev)
1795 i++; 1801 i++;
1796 if (i >= 50) { 1802 if (i >= 50) {
1797 b43err(dev->wl, "Microcode not responding\n"); 1803 b43err(dev->wl, "Microcode not responding\n");
1798 b43_print_fw_helptext(dev->wl); 1804 b43_print_fw_helptext(dev->wl, 1);
1799 err = -ENODEV; 1805 err = -ENODEV;
1800 goto out; 1806 goto out;
1801 } 1807 }
@@ -1813,7 +1819,7 @@ static int b43_upload_microcode(struct b43_wldev *dev)
1813 b43err(dev->wl, "YOUR FIRMWARE IS TOO OLD. Firmware from " 1819 b43err(dev->wl, "YOUR FIRMWARE IS TOO OLD. Firmware from "
1814 "binary drivers older than version 4.x is unsupported. " 1820 "binary drivers older than version 4.x is unsupported. "
1815 "You must upgrade your firmware files.\n"); 1821 "You must upgrade your firmware files.\n");
1816 b43_print_fw_helptext(dev->wl); 1822 b43_print_fw_helptext(dev->wl, 1);
1817 b43_write32(dev, B43_MMIO_MACCTL, 0); 1823 b43_write32(dev, B43_MMIO_MACCTL, 0);
1818 err = -EOPNOTSUPP; 1824 err = -EOPNOTSUPP;
1819 goto out; 1825 goto out;
@@ -1827,7 +1833,13 @@ static int b43_upload_microcode(struct b43_wldev *dev)
1827 dev->fw.rev = fwrev; 1833 dev->fw.rev = fwrev;
1828 dev->fw.patch = fwpatch; 1834 dev->fw.patch = fwpatch;
1829 1835
1830 out: 1836 if (b43_is_old_txhdr_format(dev)) {
1837 b43warn(dev->wl, "You are using an old firmware image. "
1838 "Support for old firmware will be removed in July 2008.\n");
1839 b43_print_fw_helptext(dev->wl, 0);
1840 }
1841
1842out:
1831 return err; 1843 return err;
1832} 1844}
1833 1845
@@ -1887,7 +1899,7 @@ static int b43_write_initvals(struct b43_wldev *dev,
1887 1899
1888err_format: 1900err_format:
1889 b43err(dev->wl, "Initial Values Firmware file-format error.\n"); 1901 b43err(dev->wl, "Initial Values Firmware file-format error.\n");
1890 b43_print_fw_helptext(dev->wl); 1902 b43_print_fw_helptext(dev->wl, 1);
1891 1903
1892 return -EPROTO; 1904 return -EPROTO;
1893} 1905}
@@ -2149,13 +2161,19 @@ static void b43_mgmtframe_txantenna(struct b43_wldev *dev, int antenna)
2149 2161
2150 switch (antenna) { 2162 switch (antenna) {
2151 case B43_ANTENNA0: 2163 case B43_ANTENNA0:
2152 ant |= B43_TX4_PHY_ANT0; 2164 ant |= B43_TXH_PHY_ANT0;
2153 break; 2165 break;
2154 case B43_ANTENNA1: 2166 case B43_ANTENNA1:
2155 ant |= B43_TX4_PHY_ANT1; 2167 ant |= B43_TXH_PHY_ANT1;
2168 break;
2169 case B43_ANTENNA2:
2170 ant |= B43_TXH_PHY_ANT2;
2171 break;
2172 case B43_ANTENNA3:
2173 ant |= B43_TXH_PHY_ANT3;
2156 break; 2174 break;
2157 case B43_ANTENNA_AUTO: 2175 case B43_ANTENNA_AUTO:
2158 ant |= B43_TX4_PHY_ANTLAST; 2176 ant |= B43_TXH_PHY_ANT01AUTO;
2159 break; 2177 break;
2160 default: 2178 default:
2161 B43_WARN_ON(1); 2179 B43_WARN_ON(1);
@@ -2165,15 +2183,15 @@ static void b43_mgmtframe_txantenna(struct b43_wldev *dev, int antenna)
2165 2183
2166 /* For Beacons */ 2184 /* For Beacons */
2167 tmp = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_BEACPHYCTL); 2185 tmp = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_BEACPHYCTL);
2168 tmp = (tmp & ~B43_TX4_PHY_ANT) | ant; 2186 tmp = (tmp & ~B43_TXH_PHY_ANT) | ant;
2169 b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_BEACPHYCTL, tmp); 2187 b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_BEACPHYCTL, tmp);
2170 /* For ACK/CTS */ 2188 /* For ACK/CTS */
2171 tmp = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_ACKCTSPHYCTL); 2189 tmp = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_ACKCTSPHYCTL);
2172 tmp = (tmp & ~B43_TX4_PHY_ANT) | ant; 2190 tmp = (tmp & ~B43_TXH_PHY_ANT) | ant;
2173 b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_ACKCTSPHYCTL, tmp); 2191 b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_ACKCTSPHYCTL, tmp);
2174 /* For Probe Resposes */ 2192 /* For Probe Resposes */
2175 tmp = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_PRPHYCTL); 2193 tmp = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_PRPHYCTL);
2176 tmp = (tmp & ~B43_TX4_PHY_ANT) | ant; 2194 tmp = (tmp & ~B43_TXH_PHY_ANT) | ant;
2177 b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_PRPHYCTL, tmp); 2195 b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_PRPHYCTL, tmp);
2178} 2196}
2179 2197
@@ -2738,6 +2756,10 @@ static int b43_antenna_from_ieee80211(struct b43_wldev *dev, u8 antenna)
2738 return B43_ANTENNA0; 2756 return B43_ANTENNA0;
2739 case 2: /* Antenna 1 */ 2757 case 2: /* Antenna 1 */
2740 return B43_ANTENNA1; 2758 return B43_ANTENNA1;
2759 case 3: /* Antenna 2 */
2760 return B43_ANTENNA2;
2761 case 4: /* Antenna 3 */
2762 return B43_ANTENNA3;
2741 default: 2763 default:
2742 return B43_ANTENNA_DEFAULT; 2764 return B43_ANTENNA_DEFAULT;
2743 } 2765 }
diff --git a/drivers/net/wireless/b43/phy.h b/drivers/net/wireless/b43/phy.h
index 31bd4d87b404..ab1e7f097022 100644
--- a/drivers/net/wireless/b43/phy.h
+++ b/drivers/net/wireless/b43/phy.h
@@ -180,6 +180,8 @@ enum {
180 B43_ANTENNA1, /* Antenna 0 */ 180 B43_ANTENNA1, /* Antenna 0 */
181 B43_ANTENNA_AUTO1, /* Automatic, starting with antenna 1 */ 181 B43_ANTENNA_AUTO1, /* Automatic, starting with antenna 1 */
182 B43_ANTENNA_AUTO0, /* Automatic, starting with antenna 0 */ 182 B43_ANTENNA_AUTO0, /* Automatic, starting with antenna 0 */
183 B43_ANTENNA2,
184 B43_ANTENNA3 = 8,
183 185
184 B43_ANTENNA_AUTO = B43_ANTENNA_AUTO0, 186 B43_ANTENNA_AUTO = B43_ANTENNA_AUTO0,
185 B43_ANTENNA_DEFAULT = B43_ANTENNA_AUTO, 187 B43_ANTENNA_DEFAULT = B43_ANTENNA_AUTO,
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,
diff --git a/drivers/net/wireless/b43/xmit.h b/drivers/net/wireless/b43/xmit.h
index 6dc079382f7f..ca2a2ab8654c 100644
--- a/drivers/net/wireless/b43/xmit.h
+++ b/drivers/net/wireless/b43/xmit.h
@@ -19,68 +19,160 @@ _b43_declare_plcp_hdr(6);
19#undef _b43_declare_plcp_hdr 19#undef _b43_declare_plcp_hdr
20 20
21/* TX header for v4 firmware */ 21/* TX header for v4 firmware */
22struct b43_txhdr_fw4 { 22struct b43_txhdr {
23 __le32 mac_ctl; /* MAC TX control */ 23 __le32 mac_ctl; /* MAC TX control */
24 __le16 mac_frame_ctl; /* Copy of the FrameControl field */ 24 __le16 mac_frame_ctl; /* Copy of the FrameControl field */
25 __le16 tx_fes_time_norm; /* TX FES Time Normal */ 25 __le16 tx_fes_time_norm; /* TX FES Time Normal */
26 __le16 phy_ctl; /* PHY TX control */ 26 __le16 phy_ctl; /* PHY TX control */
27 __le16 phy_ctl_0; /* Unused */ 27 __le16 phy_ctl1; /* PHY TX control word 1 */
28 __le16 phy_ctl_1; /* Unused */ 28 __le16 phy_ctl1_fb; /* PHY TX control word 1 for fallback rates */
29 __le16 phy_ctl_rts_0; /* Unused */ 29 __le16 phy_ctl1_rts; /* PHY TX control word 1 RTS */
30 __le16 phy_ctl_rts_1; /* Unused */ 30 __le16 phy_ctl1_rts_fb; /* PHY TX control word 1 RTS for fallback rates */
31 __u8 phy_rate; /* PHY rate */ 31 __u8 phy_rate; /* PHY rate */
32 __u8 phy_rate_rts; /* PHY rate for RTS/CTS */ 32 __u8 phy_rate_rts; /* PHY rate for RTS/CTS */
33 __u8 extra_ft; /* Extra Frame Types */ 33 __u8 extra_ft; /* Extra Frame Types */
34 __u8 chan_radio_code; /* Channel Radio Code */ 34 __u8 chan_radio_code; /* Channel Radio Code */
35 __u8 iv[16]; /* Encryption IV */ 35 __u8 iv[16]; /* Encryption IV */
36 __u8 tx_receiver[6]; /* TX Frame Receiver address */ 36 __u8 tx_receiver[6]; /* TX Frame Receiver address */
37 __le16 tx_fes_time_fb; /* TX FES Time Fallback */ 37 __le16 tx_fes_time_fb; /* TX FES Time Fallback */
38 struct b43_plcp_hdr6 rts_plcp_fb; /* RTS fallback PLCP */ 38 struct b43_plcp_hdr6 rts_plcp_fb; /* RTS fallback PLCP header */
39 __le16 rts_dur_fb; /* RTS fallback duration */ 39 __le16 rts_dur_fb; /* RTS fallback duration */
40 struct b43_plcp_hdr6 plcp_fb; /* Fallback PLCP */ 40 struct b43_plcp_hdr6 plcp_fb; /* Fallback PLCP header */
41 __le16 dur_fb; /* Fallback duration */ 41 __le16 dur_fb; /* Fallback duration */
42 __le16 mm_dur_time; /* Unused */ 42 __le16 mimo_modelen; /* MIMO mode length */
43 __le16 mm_dur_time_fb; /* Unused */ 43 __le16 mimo_ratelen_fb; /* MIMO fallback rate length */
44 __le32 time_stamp; /* Timestamp */ 44 __le32 timeout; /* Timeout */
45 PAD_BYTES(2); 45
46 __le16 cookie; /* TX frame cookie */ 46 union {
47 __le16 tx_status; /* TX status */ 47 /* The new r410 format. */
48 struct b43_plcp_hdr6 rts_plcp; /* RTS PLCP */ 48 struct {
49 __u8 rts_frame[16]; /* The RTS frame (if used) */ 49 __le16 mimo_antenna; /* MIMO antenna select */
50 PAD_BYTES(2); 50 __le16 preload_size; /* Preload size */
51 struct b43_plcp_hdr6 plcp; /* Main PLCP */ 51 PAD_BYTES(2);
52 __le16 cookie; /* TX frame cookie */
53 __le16 tx_status; /* TX status */
54 struct b43_plcp_hdr6 rts_plcp; /* RTS PLCP header */
55 __u8 rts_frame[16]; /* The RTS frame (if used) */
56 PAD_BYTES(2);
57 struct b43_plcp_hdr6 plcp; /* Main PLCP header */
58 } new_format __attribute__ ((__packed__));
59
60 /* The old r351 format. */
61 struct {
62 PAD_BYTES(2);
63 __le16 cookie; /* TX frame cookie */
64 __le16 tx_status; /* TX status */
65 struct b43_plcp_hdr6 rts_plcp; /* RTS PLCP header */
66 __u8 rts_frame[16]; /* The RTS frame (if used) */
67 PAD_BYTES(2);
68 struct b43_plcp_hdr6 plcp; /* Main PLCP header */
69 } old_format __attribute__ ((__packed__));
70
71 } __attribute__ ((__packed__));
52} __attribute__ ((__packed__)); 72} __attribute__ ((__packed__));
53 73
54/* MAC TX control */ 74/* MAC TX control */
55#define B43_TX4_MAC_KEYIDX 0x0FF00000 /* Security key index */ 75#define B43_TXH_MAC_USEFBR 0x10000000 /* Use fallback rate for this AMPDU */
56#define B43_TX4_MAC_KEYIDX_SHIFT 20 76#define B43_TXH_MAC_KEYIDX 0x0FF00000 /* Security key index */
57#define B43_TX4_MAC_KEYALG 0x00070000 /* Security key algorithm */ 77#define B43_TXH_MAC_KEYIDX_SHIFT 20
58#define B43_TX4_MAC_KEYALG_SHIFT 16 78#define B43_TXH_MAC_KEYALG 0x00070000 /* Security key algorithm */
59#define B43_TX4_MAC_LIFETIME 0x00001000 79#define B43_TXH_MAC_KEYALG_SHIFT 16
60#define B43_TX4_MAC_FRAMEBURST 0x00000800 80#define B43_TXH_MAC_AMIC 0x00008000 /* AMIC */
61#define B43_TX4_MAC_SENDCTS 0x00000400 81#define B43_TXH_MAC_RIFS 0x00004000 /* Use RIFS */
62#define B43_TX4_MAC_AMPDU 0x00000300 82#define B43_TXH_MAC_LIFETIME 0x00002000 /* Lifetime */
63#define B43_TX4_MAC_AMPDU_SHIFT 8 83#define B43_TXH_MAC_FRAMEBURST 0x00001000 /* Frameburst */
64#define B43_TX4_MAC_5GHZ 0x00000080 84#define B43_TXH_MAC_SENDCTS 0x00000800 /* Send CTS-to-self */
65#define B43_TX4_MAC_IGNPMQ 0x00000020 85#define B43_TXH_MAC_AMPDU 0x00000600 /* AMPDU status */
66#define B43_TX4_MAC_HWSEQ 0x00000010 /* Use Hardware Sequence Number */ 86#define B43_TXH_MAC_AMPDU_MPDU 0x00000000 /* Regular MPDU, not an AMPDU */
67#define B43_TX4_MAC_STMSDU 0x00000008 /* Start MSDU */ 87#define B43_TXH_MAC_AMPDU_FIRST 0x00000200 /* First MPDU or AMPDU */
68#define B43_TX4_MAC_SENDRTS 0x00000004 88#define B43_TXH_MAC_AMPDU_INTER 0x00000400 /* Intermediate MPDU or AMPDU */
69#define B43_TX4_MAC_LONGFRAME 0x00000002 89#define B43_TXH_MAC_AMPDU_LAST 0x00000600 /* Last (or only) MPDU of AMPDU */
70#define B43_TX4_MAC_ACK 0x00000001 90#define B43_TXH_MAC_40MHZ 0x00000100 /* Use 40 MHz bandwidth */
91#define B43_TXH_MAC_5GHZ 0x00000080 /* 5GHz band */
92#define B43_TXH_MAC_DFCS 0x00000040 /* DFCS */
93#define B43_TXH_MAC_IGNPMQ 0x00000020 /* Ignore PMQ */
94#define B43_TXH_MAC_HWSEQ 0x00000010 /* Use Hardware Sequence Number */
95#define B43_TXH_MAC_STMSDU 0x00000008 /* Start MSDU */
96#define B43_TXH_MAC_SENDRTS 0x00000004 /* Send RTS */
97#define B43_TXH_MAC_LONGFRAME 0x00000002 /* Long frame */
98#define B43_TXH_MAC_ACK 0x00000001 /* Immediate ACK */
71 99
72/* Extra Frame Types */ 100/* Extra Frame Types */
73#define B43_TX4_EFT_FBOFDM 0x0001 /* Data frame fallback rate type */ 101#define B43_TXH_EFT_FB 0x03 /* Data frame fallback encoding */
74#define B43_TX4_EFT_RTSOFDM 0x0004 /* RTS/CTS rate type */ 102#define B43_TXH_EFT_FB_CCK 0x00 /* CCK */
75#define B43_TX4_EFT_RTSFBOFDM 0x0010 /* RTS/CTS fallback rate type */ 103#define B43_TXH_EFT_FB_OFDM 0x01 /* OFDM */
104#define B43_TXH_EFT_FB_EWC 0x02 /* EWC */
105#define B43_TXH_EFT_FB_N 0x03 /* N */
106#define B43_TXH_EFT_RTS 0x0C /* RTS/CTS encoding */
107#define B43_TXH_EFT_RTS_CCK 0x00 /* CCK */
108#define B43_TXH_EFT_RTS_OFDM 0x04 /* OFDM */
109#define B43_TXH_EFT_RTS_EWC 0x08 /* EWC */
110#define B43_TXH_EFT_RTS_N 0x0C /* N */
111#define B43_TXH_EFT_RTSFB 0x30 /* RTS/CTS fallback encoding */
112#define B43_TXH_EFT_RTSFB_CCK 0x00 /* CCK */
113#define B43_TXH_EFT_RTSFB_OFDM 0x10 /* OFDM */
114#define B43_TXH_EFT_RTSFB_EWC 0x20 /* EWC */
115#define B43_TXH_EFT_RTSFB_N 0x30 /* N */
76 116
77/* PHY TX control word */ 117/* PHY TX control word */
78#define B43_TX4_PHY_OFDM 0x0001 /* Data frame rate type */ 118#define B43_TXH_PHY_ENC 0x0003 /* Data frame encoding */
79#define B43_TX4_PHY_SHORTPRMBL 0x0010 /* Use short preamble */ 119#define B43_TXH_PHY_ENC_CCK 0x0000 /* CCK */
80#define B43_TX4_PHY_ANT 0x03C0 /* Antenna selection */ 120#define B43_TXH_PHY_ENC_OFDM 0x0001 /* OFDM */
81#define B43_TX4_PHY_ANT0 0x0000 /* Use antenna 0 */ 121#define B43_TXH_PHY_ENC_EWC 0x0002 /* EWC */
82#define B43_TX4_PHY_ANT1 0x0100 /* Use antenna 1 */ 122#define B43_TXH_PHY_ENC_N 0x0003 /* N */
83#define B43_TX4_PHY_ANTLAST 0x0300 /* Use last used antenna */ 123#define B43_TXH_PHY_SHORTPRMBL 0x0010 /* Use short preamble */
124#define B43_TXH_PHY_ANT 0x03C0 /* Antenna selection */
125#define B43_TXH_PHY_ANT0 0x0000 /* Use antenna 0 */
126#define B43_TXH_PHY_ANT1 0x0040 /* Use antenna 1 */
127#define B43_TXH_PHY_ANT01AUTO 0x00C0 /* Use antenna 0/1 auto */
128#define B43_TXH_PHY_ANT2 0x0100 /* Use antenna 2 */
129#define B43_TXH_PHY_ANT3 0x0200 /* Use antenna 3 */
130#define B43_TXH_PHY_TXPWR 0xFC00 /* TX power */
131#define B43_TXH_PHY_TXPWR_SHIFT 10
132
133/* PHY TX control word 1 */
134#define B43_TXH_PHY1_BW 0x0007 /* Bandwidth */
135#define B43_TXH_PHY1_BW_10 0x0000 /* 10 MHz */
136#define B43_TXH_PHY1_BW_10U 0x0001 /* 10 MHz upper */
137#define B43_TXH_PHY1_BW_20 0x0002 /* 20 MHz */
138#define B43_TXH_PHY1_BW_20U 0x0003 /* 20 MHz upper */
139#define B43_TXH_PHY1_BW_40 0x0004 /* 40 MHz */
140#define B43_TXH_PHY1_BW_40DUP 0x0005 /* 50 MHz duplicate */
141#define B43_TXH_PHY1_MODE 0x0038 /* Mode */
142#define B43_TXH_PHY1_MODE_SISO 0x0000 /* SISO */
143#define B43_TXH_PHY1_MODE_CDD 0x0008 /* CDD */
144#define B43_TXH_PHY1_MODE_STBC 0x0010 /* STBC */
145#define B43_TXH_PHY1_MODE_SDM 0x0018 /* SDM */
146#define B43_TXH_PHY1_CRATE 0x0700 /* Coding rate */
147#define B43_TXH_PHY1_CRATE_1_2 0x0000 /* 1/2 */
148#define B43_TXH_PHY1_CRATE_2_3 0x0100 /* 2/3 */
149#define B43_TXH_PHY1_CRATE_3_4 0x0200 /* 3/4 */
150#define B43_TXH_PHY1_CRATE_4_5 0x0300 /* 4/5 */
151#define B43_TXH_PHY1_CRATE_5_6 0x0400 /* 5/6 */
152#define B43_TXH_PHY1_CRATE_7_8 0x0600 /* 7/8 */
153#define B43_TXH_PHY1_MODUL 0x3800 /* Modulation scheme */
154#define B43_TXH_PHY1_MODUL_BPSK 0x0000 /* BPSK */
155#define B43_TXH_PHY1_MODUL_QPSK 0x0800 /* QPSK */
156#define B43_TXH_PHY1_MODUL_QAM16 0x1000 /* QAM16 */
157#define B43_TXH_PHY1_MODUL_QAM64 0x1800 /* QAM64 */
158#define B43_TXH_PHY1_MODUL_QAM256 0x2000 /* QAM256 */
159
160
161/* r351 firmware compatibility stuff. */
162static inline
163bool b43_is_old_txhdr_format(struct b43_wldev *dev)
164{
165 return (dev->fw.rev <= 351);
166}
167
168static inline
169size_t b43_txhdr_size(struct b43_wldev *dev)
170{
171 if (b43_is_old_txhdr_format(dev))
172 return 100 + sizeof(struct b43_plcp_hdr6);
173 return 104 + sizeof(struct b43_plcp_hdr6);
174}
175
84 176
85void b43_generate_txhdr(struct b43_wldev *dev, 177void b43_generate_txhdr(struct b43_wldev *dev,
86 u8 * txhdr, 178 u8 * txhdr,