aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00/rt61pci.c
diff options
context:
space:
mode:
authorIvo van Doorn <ivdoorn@gmail.com>2008-02-03 09:49:59 -0500
committerJohn W. Linville <linville@tuxdriver.com>2008-02-29 15:19:28 -0500
commit6bb40dd13b458beb55f5c60dba1cb28e814bd640 (patch)
tree9b2aaa0de4a4d72a7afc3550b08572083b111c57 /drivers/net/wireless/rt2x00/rt61pci.c
parent9404ef34e4747228717d6e22ce3827ed366ccf41 (diff)
rt2x00: Add per-interface structure
Rework the interface handling. Delete the interface structure and replace it with a per-interface structure. This changes the way rt2x00 handles the active interface drastically. Copy ieee80211_bss_conf to the this rt2x00_intf structure during the bss_info_changed() callback function. This will allow us to reference it later, and removes the requirement for the device flag SHORT_PREAMBLE flag which is interface specific. Drivers receive the option to give the maximum number of virtual interfaces the device can handle. Virtual interface support: rt2400pci: 1 sta or 1 ap, * monitor interfaces rt2500pci: 1 sta or 1 ap, * monitor interfaces rt2500usb: 1 sta or 1 ap, * monitor interfaces rt61pci: 1 sta or 4 ap, * monitor interfaces rt73usb: 1 sta or 4 ap, * monitor interfaces At the moment none of the drivers support AP and STA interfaces simultaneously, this is a hardware limitation so future support will be very unlikely. Each interface structure receives its dedicated beacon entry, with this we can easily work with beaconing while multiple master mode interfaces are currently active. The configuration handlers for the MAC, BSSID and type are often called together since they all belong to the interface configuration. Merge the 3 configuration calls and cleanup the API between rt2x00lib and the drivers. While we are cleaning up the interface configuration anyway, we might as well clean up the configuration handler as well. Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt61pci.c')
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c169
1 files changed, 95 insertions, 74 deletions
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index b5ab771bbac2..b432cc21d248 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -271,63 +271,60 @@ static int rt61pci_rfkill_poll(struct rt2x00_dev *rt2x00dev)
271/* 271/*
272 * Configuration handlers. 272 * Configuration handlers.
273 */ 273 */
274static void rt61pci_config_mac_addr(struct rt2x00_dev *rt2x00dev, __le32 *mac) 274static void rt61pci_config_intf(struct rt2x00_dev *rt2x00dev,
275 struct rt2x00_intf *intf,
276 struct rt2x00intf_conf *conf,
277 const unsigned int flags)
275{ 278{
276 u32 tmp; 279 unsigned int beacon_base;
277 280 u32 reg;
278 tmp = le32_to_cpu(mac[1]);
279 rt2x00_set_field32(&tmp, MAC_CSR3_UNICAST_TO_ME_MASK, 0xff);
280 mac[1] = cpu_to_le32(tmp);
281
282 rt2x00pci_register_multiwrite(rt2x00dev, MAC_CSR2, mac,
283 (2 * sizeof(__le32)));
284}
285 281
286static void rt61pci_config_bssid(struct rt2x00_dev *rt2x00dev, __le32 *bssid) 282 if (flags & CONFIG_UPDATE_TYPE) {
287{ 283 /*
288 u32 tmp; 284 * Clear current synchronisation setup.
285 * For the Beacon base registers we only need to clear
286 * the first byte since that byte contains the VALID and OWNER
287 * bits which (when set to 0) will invalidate the entire beacon.
288 */
289 beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx);
290 rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, 0);
291 rt2x00pci_register_write(rt2x00dev, beacon_base, 0);
289 292
290 tmp = le32_to_cpu(bssid[1]); 293 /*
291 rt2x00_set_field32(&tmp, MAC_CSR5_BSS_ID_MASK, 3); 294 * Enable synchronisation.
292 bssid[1] = cpu_to_le32(tmp); 295 */
296 rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, &reg);
297 rt2x00_set_field32(&reg, TXRX_CSR9_TSF_TICKING, 1);
298 rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE,
299 (conf->sync == TSF_SYNC_BEACON));
300 rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 0);
301 rt2x00_set_field32(&reg, TXRX_CSR9_TSF_SYNC, conf->sync);
302 rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg);
303 }
293 304
294 rt2x00pci_register_multiwrite(rt2x00dev, MAC_CSR4, bssid, 305 if (flags & CONFIG_UPDATE_MAC) {
295 (2 * sizeof(__le32))); 306 reg = le32_to_cpu(conf->mac[1]);
296} 307 rt2x00_set_field32(&reg, MAC_CSR3_UNICAST_TO_ME_MASK, 0xff);
308 conf->mac[1] = cpu_to_le32(reg);
297 309
298static void rt61pci_config_type(struct rt2x00_dev *rt2x00dev, const int type, 310 rt2x00pci_register_multiwrite(rt2x00dev, MAC_CSR2,
299 const int tsf_sync) 311 conf->mac, sizeof(conf->mac));
300{ 312 }
301 u32 reg;
302 313
303 /* 314 if (flags & CONFIG_UPDATE_BSSID) {
304 * Clear current synchronisation setup. 315 reg = le32_to_cpu(conf->bssid[1]);
305 * For the Beacon base registers we only need to clear 316 rt2x00_set_field32(&reg, MAC_CSR5_BSS_ID_MASK, 3);
306 * the first byte since that byte contains the VALID and OWNER 317 conf->bssid[1] = cpu_to_le32(reg);
307 * bits which (when set to 0) will invalidate the entire beacon.
308 */
309 rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, 0);
310 rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE0, 0);
311 rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE1, 0);
312 rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE2, 0);
313 rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE3, 0);
314 318
315 /* 319 rt2x00pci_register_multiwrite(rt2x00dev, MAC_CSR4,
316 * Enable synchronisation. 320 conf->bssid, sizeof(conf->bssid));
317 */ 321 }
318 rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, &reg);
319 rt2x00_set_field32(&reg, TXRX_CSR9_TSF_TICKING, 1);
320 rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE,
321 (tsf_sync == TSF_SYNC_BEACON));
322 rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 0);
323 rt2x00_set_field32(&reg, TXRX_CSR9_TSF_SYNC, tsf_sync);
324 rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg);
325} 322}
326 323
327static void rt61pci_config_preamble(struct rt2x00_dev *rt2x00dev, 324static int rt61pci_config_preamble(struct rt2x00_dev *rt2x00dev,
328 const int short_preamble, 325 const int short_preamble,
329 const int ack_timeout, 326 const int ack_timeout,
330 const int ack_consume_time) 327 const int ack_consume_time)
331{ 328{
332 u32 reg; 329 u32 reg;
333 330
@@ -339,6 +336,8 @@ static void rt61pci_config_preamble(struct rt2x00_dev *rt2x00dev,
339 rt2x00_set_field32(&reg, TXRX_CSR4_AUTORESPOND_PREAMBLE, 336 rt2x00_set_field32(&reg, TXRX_CSR4_AUTORESPOND_PREAMBLE,
340 !!short_preamble); 337 !!short_preamble);
341 rt2x00pci_register_write(rt2x00dev, TXRX_CSR4, reg); 338 rt2x00pci_register_write(rt2x00dev, TXRX_CSR4, reg);
339
340 return 0;
342} 341}
343 342
344static void rt61pci_config_phymode(struct rt2x00_dev *rt2x00dev, 343static void rt61pci_config_phymode(struct rt2x00_dev *rt2x00dev,
@@ -667,8 +666,8 @@ static void rt61pci_config_duration(struct rt2x00_dev *rt2x00dev,
667} 666}
668 667
669static void rt61pci_config(struct rt2x00_dev *rt2x00dev, 668static void rt61pci_config(struct rt2x00_dev *rt2x00dev,
670 const unsigned int flags, 669 struct rt2x00lib_conf *libconf,
671 struct rt2x00lib_conf *libconf) 670 const unsigned int flags)
672{ 671{
673 if (flags & CONFIG_UPDATE_PHYMODE) 672 if (flags & CONFIG_UPDATE_PHYMODE)
674 rt61pci_config_phymode(rt2x00dev, libconf->basic_rates); 673 rt61pci_config_phymode(rt2x00dev, libconf->basic_rates);
@@ -816,6 +815,13 @@ static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev)
816 } 815 }
817 816
818 /* 817 /*
818 * If we are not associated, we should go straight to the
819 * dynamic CCA tuning.
820 */
821 if (!rt2x00dev->intf_associated)
822 goto dynamic_cca_tune;
823
824 /*
819 * Special big-R17 for very short distance 825 * Special big-R17 for very short distance
820 */ 826 */
821 if (rssi >= -35) { 827 if (rssi >= -35) {
@@ -866,6 +872,8 @@ static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev)
866 return; 872 return;
867 } 873 }
868 874
875dynamic_cca_tune:
876
869 /* 877 /*
870 * r17 does not yet exceed upper limit, continue and base 878 * r17 does not yet exceed upper limit, continue and base
871 * the r17 tuning on the false CCA count. 879 * the r17 tuning on the false CCA count.
@@ -1215,6 +1223,17 @@ static int rt61pci_init_registers(struct rt2x00_dev *rt2x00dev)
1215 rt2x00pci_register_write(rt2x00dev, AC_TXOP_CSR1, reg); 1223 rt2x00pci_register_write(rt2x00dev, AC_TXOP_CSR1, reg);
1216 1224
1217 /* 1225 /*
1226 * Clear all beacons
1227 * For the Beacon base registers we only need to clear
1228 * the first byte since that byte contains the VALID and OWNER
1229 * bits which (when set to 0) will invalidate the entire beacon.
1230 */
1231 rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE0, 0);
1232 rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE1, 0);
1233 rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE2, 0);
1234 rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE3, 0);
1235
1236 /*
1218 * We must clear the error counters. 1237 * We must clear the error counters.
1219 * These registers are cleared on read, 1238 * These registers are cleared on read,
1220 * so we may pass a useless variable to store the value. 1239 * so we may pass a useless variable to store the value.
@@ -2378,25 +2397,20 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
2378 struct ieee80211_tx_control *control) 2397 struct ieee80211_tx_control *control)
2379{ 2398{
2380 struct rt2x00_dev *rt2x00dev = hw->priv; 2399 struct rt2x00_dev *rt2x00dev = hw->priv;
2400 struct rt2x00_intf *intf = vif_to_intf(control->vif);
2381 struct skb_frame_desc *skbdesc; 2401 struct skb_frame_desc *skbdesc;
2382 struct data_queue *queue; 2402 unsigned int beacon_base;
2383 struct queue_entry *entry;
2384 2403
2385 /* 2404 if (unlikely(!intf->beacon))
2386 * Just in case the ieee80211 doesn't set this, 2405 return -ENOBUFS;
2387 * but we need this queue set for the descriptor
2388 * initialization.
2389 */
2390 control->queue = IEEE80211_TX_QUEUE_BEACON;
2391 queue = rt2x00queue_get_queue(rt2x00dev, control->queue);
2392 entry = rt2x00queue_get_entry(queue, Q_INDEX);
2393 2406
2394 /* 2407 /*
2395 * We need to append the descriptor in front of the 2408 * We need to append the descriptor in front of the
2396 * beacon frame. 2409 * beacon frame.
2397 */ 2410 */
2398 if (skb_headroom(skb) < queue->desc_size) { 2411 if (skb_headroom(skb) < intf->beacon->queue->desc_size) {
2399 if (pskb_expand_head(skb, queue->desc_size, 0, GFP_ATOMIC)) { 2412 if (pskb_expand_head(skb, intf->beacon->queue->desc_size,
2413 0, GFP_ATOMIC)) {
2400 dev_kfree_skb(skb); 2414 dev_kfree_skb(skb);
2401 return -ENOMEM; 2415 return -ENOMEM;
2402 } 2416 }
@@ -2405,29 +2419,36 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
2405 /* 2419 /*
2406 * Add the descriptor in front of the skb. 2420 * Add the descriptor in front of the skb.
2407 */ 2421 */
2408 skb_push(skb, queue->desc_size); 2422 skb_push(skb, intf->beacon->queue->desc_size);
2409 memset(skb->data, 0, queue->desc_size); 2423 memset(skb->data, 0, intf->beacon->queue->desc_size);
2410 2424
2411 /* 2425 /*
2412 * Fill in skb descriptor 2426 * Fill in skb descriptor
2413 */ 2427 */
2414 skbdesc = get_skb_frame_desc(skb); 2428 skbdesc = get_skb_frame_desc(skb);
2415 memset(skbdesc, 0, sizeof(*skbdesc)); 2429 memset(skbdesc, 0, sizeof(*skbdesc));
2416 skbdesc->data = skb->data + queue->desc_size; 2430 skbdesc->data = skb->data + intf->beacon->queue->desc_size;
2417 skbdesc->data_len = queue->data_size; 2431 skbdesc->data_len = skb->len - intf->beacon->queue->desc_size;
2418 skbdesc->desc = skb->data; 2432 skbdesc->desc = skb->data;
2419 skbdesc->desc_len = queue->desc_size; 2433 skbdesc->desc_len = intf->beacon->queue->desc_size;
2420 skbdesc->entry = entry; 2434 skbdesc->entry = intf->beacon;
2421 2435
2436 /*
2437 * Just in case the ieee80211 doesn't set this,
2438 * but we need this queue set for the descriptor
2439 * initialization.
2440 */
2441 control->queue = IEEE80211_TX_QUEUE_BEACON;
2422 rt2x00lib_write_tx_desc(rt2x00dev, skb, control); 2442 rt2x00lib_write_tx_desc(rt2x00dev, skb, control);
2423 2443
2424 /* 2444 /*
2425 * Write entire beacon with descriptor to register, 2445 * Write entire beacon with descriptor to register,
2426 * and kick the beacon generator. 2446 * and kick the beacon generator.
2427 */ 2447 */
2428 rt2x00pci_register_multiwrite(rt2x00dev, HW_BEACON_BASE0, 2448 beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx);
2449 rt2x00pci_register_multiwrite(rt2x00dev, beacon_base,
2429 skb->data, skb->len); 2450 skb->data, skb->len);
2430 rt61pci_kick_tx_queue(rt2x00dev, IEEE80211_TX_QUEUE_BEACON); 2451 rt61pci_kick_tx_queue(rt2x00dev, control->queue);
2431 2452
2432 return 0; 2453 return 0;
2433} 2454}
@@ -2469,9 +2490,7 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = {
2469 .write_tx_data = rt2x00pci_write_tx_data, 2490 .write_tx_data = rt2x00pci_write_tx_data,
2470 .kick_tx_queue = rt61pci_kick_tx_queue, 2491 .kick_tx_queue = rt61pci_kick_tx_queue,
2471 .fill_rxdone = rt61pci_fill_rxdone, 2492 .fill_rxdone = rt61pci_fill_rxdone,
2472 .config_mac_addr = rt61pci_config_mac_addr, 2493 .config_intf = rt61pci_config_intf,
2473 .config_bssid = rt61pci_config_bssid,
2474 .config_type = rt61pci_config_type,
2475 .config_preamble = rt61pci_config_preamble, 2494 .config_preamble = rt61pci_config_preamble,
2476 .config = rt61pci_config, 2495 .config = rt61pci_config,
2477}; 2496};
@@ -2491,7 +2510,7 @@ static const struct data_queue_desc rt61pci_queue_tx = {
2491}; 2510};
2492 2511
2493static const struct data_queue_desc rt61pci_queue_bcn = { 2512static const struct data_queue_desc rt61pci_queue_bcn = {
2494 .entry_num = BEACON_ENTRIES, 2513 .entry_num = 4 * BEACON_ENTRIES,
2495 .data_size = MGMT_FRAME_SIZE, 2514 .data_size = MGMT_FRAME_SIZE,
2496 .desc_size = TXINFO_SIZE, 2515 .desc_size = TXINFO_SIZE,
2497 .priv_size = sizeof(struct queue_entry_priv_pci_tx), 2516 .priv_size = sizeof(struct queue_entry_priv_pci_tx),
@@ -2499,6 +2518,8 @@ static const struct data_queue_desc rt61pci_queue_bcn = {
2499 2518
2500static const struct rt2x00_ops rt61pci_ops = { 2519static const struct rt2x00_ops rt61pci_ops = {
2501 .name = KBUILD_MODNAME, 2520 .name = KBUILD_MODNAME,
2521 .max_sta_intf = 1,
2522 .max_ap_intf = 4,
2502 .eeprom_size = EEPROM_SIZE, 2523 .eeprom_size = EEPROM_SIZE,
2503 .rf_size = RF_SIZE, 2524 .rf_size = RF_SIZE,
2504 .rx = &rt61pci_queue_rx, 2525 .rx = &rt61pci_queue_rx,