diff options
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/wireless/ath9k/ath9k.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath9k/core.c | 129 | ||||
-rw-r--r-- | drivers/net/wireless/ath9k/core.h | 25 | ||||
-rw-r--r-- | drivers/net/wireless/ath9k/hw.c | 35 | ||||
-rw-r--r-- | drivers/net/wireless/ath9k/main.c | 18 | ||||
-rw-r--r-- | drivers/net/wireless/ath9k/recv.c | 13 |
6 files changed, 197 insertions, 25 deletions
diff --git a/drivers/net/wireless/ath9k/ath9k.h b/drivers/net/wireless/ath9k/ath9k.h index 0e897c276858..accace5f7efb 100644 --- a/drivers/net/wireless/ath9k/ath9k.h +++ b/drivers/net/wireless/ath9k/ath9k.h | |||
@@ -854,7 +854,7 @@ bool ath9k_hw_calibrate(struct ath_hal *ah, | |||
854 | u8 rxchainmask, | 854 | u8 rxchainmask, |
855 | bool longcal, | 855 | bool longcal, |
856 | bool *isCalDone); | 856 | bool *isCalDone); |
857 | int16_t ath9k_hw_getchan_noise(struct ath_hal *ah, | 857 | s16 ath9k_hw_getchan_noise(struct ath_hal *ah, |
858 | struct ath9k_channel *chan); | 858 | struct ath9k_channel *chan); |
859 | void ath9k_hw_write_associd(struct ath_hal *ah, const u8 *bssid, | 859 | void ath9k_hw_write_associd(struct ath_hal *ah, const u8 *bssid, |
860 | u16 assocId); | 860 | u16 assocId); |
diff --git a/drivers/net/wireless/ath9k/core.c b/drivers/net/wireless/ath9k/core.c index 5af7dfbd423d..c5033f6f42ac 100644 --- a/drivers/net/wireless/ath9k/core.c +++ b/drivers/net/wireless/ath9k/core.c | |||
@@ -490,6 +490,122 @@ void ath_update_chainmask(struct ath_softc *sc, int is_ht) | |||
490 | __func__, sc->sc_tx_chainmask, sc->sc_rx_chainmask); | 490 | __func__, sc->sc_tx_chainmask, sc->sc_rx_chainmask); |
491 | } | 491 | } |
492 | 492 | ||
493 | /*******/ | ||
494 | /* ANI */ | ||
495 | /*******/ | ||
496 | |||
497 | /* | ||
498 | * This routine performs the periodic noise floor calibration function | ||
499 | * that is used to adjust and optimize the chip performance. This | ||
500 | * takes environmental changes (location, temperature) into account. | ||
501 | * When the task is complete, it reschedules itself depending on the | ||
502 | * appropriate interval that was calculated. | ||
503 | */ | ||
504 | |||
505 | static void ath_ani_calibrate(unsigned long data) | ||
506 | { | ||
507 | struct ath_softc *sc; | ||
508 | struct ath_hal *ah; | ||
509 | bool longcal = false; | ||
510 | bool shortcal = false; | ||
511 | bool aniflag = false; | ||
512 | unsigned int timestamp = jiffies_to_msecs(jiffies); | ||
513 | u32 cal_interval; | ||
514 | |||
515 | sc = (struct ath_softc *)data; | ||
516 | ah = sc->sc_ah; | ||
517 | |||
518 | /* | ||
519 | * don't calibrate when we're scanning. | ||
520 | * we are most likely not on our home channel. | ||
521 | */ | ||
522 | if (sc->rx_filter & FIF_BCN_PRBRESP_PROMISC) | ||
523 | return; | ||
524 | |||
525 | /* Long calibration runs independently of short calibration. */ | ||
526 | if ((timestamp - sc->sc_ani.sc_longcal_timer) >= ATH_LONG_CALINTERVAL) { | ||
527 | longcal = true; | ||
528 | DPRINTF(sc, ATH_DBG_ANI, "%s: longcal @%lu\n", | ||
529 | __func__, jiffies); | ||
530 | sc->sc_ani.sc_longcal_timer = timestamp; | ||
531 | } | ||
532 | |||
533 | /* Short calibration applies only while sc_caldone is false */ | ||
534 | if (!sc->sc_ani.sc_caldone) { | ||
535 | if ((timestamp - sc->sc_ani.sc_shortcal_timer) >= | ||
536 | ATH_SHORT_CALINTERVAL) { | ||
537 | shortcal = true; | ||
538 | DPRINTF(sc, ATH_DBG_ANI, "%s: shortcal @%lu\n", | ||
539 | __func__, jiffies); | ||
540 | sc->sc_ani.sc_shortcal_timer = timestamp; | ||
541 | sc->sc_ani.sc_resetcal_timer = timestamp; | ||
542 | } | ||
543 | } else { | ||
544 | if ((timestamp - sc->sc_ani.sc_resetcal_timer) >= | ||
545 | ATH_RESTART_CALINTERVAL) { | ||
546 | ath9k_hw_reset_calvalid(ah, ah->ah_curchan, | ||
547 | &sc->sc_ani.sc_caldone); | ||
548 | if (sc->sc_ani.sc_caldone) | ||
549 | sc->sc_ani.sc_resetcal_timer = timestamp; | ||
550 | } | ||
551 | } | ||
552 | |||
553 | /* Verify whether we must check ANI */ | ||
554 | if ((timestamp - sc->sc_ani.sc_checkani_timer) >= | ||
555 | ATH_ANI_POLLINTERVAL) { | ||
556 | aniflag = true; | ||
557 | sc->sc_ani.sc_checkani_timer = timestamp; | ||
558 | } | ||
559 | |||
560 | /* Skip all processing if there's nothing to do. */ | ||
561 | if (longcal || shortcal || aniflag) { | ||
562 | /* Call ANI routine if necessary */ | ||
563 | if (aniflag) | ||
564 | ath9k_hw_ani_monitor(ah, &sc->sc_halstats, | ||
565 | ah->ah_curchan); | ||
566 | |||
567 | /* Perform calibration if necessary */ | ||
568 | if (longcal || shortcal) { | ||
569 | bool iscaldone = false; | ||
570 | |||
571 | if (ath9k_hw_calibrate(ah, ah->ah_curchan, | ||
572 | sc->sc_rx_chainmask, longcal, | ||
573 | &iscaldone)) { | ||
574 | if (longcal) | ||
575 | sc->sc_ani.sc_noise_floor = | ||
576 | ath9k_hw_getchan_noise(ah, | ||
577 | ah->ah_curchan); | ||
578 | |||
579 | DPRINTF(sc, ATH_DBG_ANI, | ||
580 | "%s: calibrate chan %u/%x nf: %d\n", | ||
581 | __func__, | ||
582 | ah->ah_curchan->channel, | ||
583 | ah->ah_curchan->channelFlags, | ||
584 | sc->sc_ani.sc_noise_floor); | ||
585 | } else { | ||
586 | DPRINTF(sc, ATH_DBG_ANY, | ||
587 | "%s: calibrate chan %u/%x failed\n", | ||
588 | __func__, | ||
589 | ah->ah_curchan->channel, | ||
590 | ah->ah_curchan->channelFlags); | ||
591 | } | ||
592 | sc->sc_ani.sc_caldone = iscaldone; | ||
593 | } | ||
594 | } | ||
595 | |||
596 | /* | ||
597 | * Set timer interval based on previous results. | ||
598 | * The interval must be the shortest necessary to satisfy ANI, | ||
599 | * short calibration and long calibration. | ||
600 | */ | ||
601 | |||
602 | cal_interval = ATH_ANI_POLLINTERVAL; | ||
603 | if (!sc->sc_ani.sc_caldone) | ||
604 | cal_interval = min(cal_interval, (u32)ATH_SHORT_CALINTERVAL); | ||
605 | |||
606 | mod_timer(&sc->sc_ani.timer, jiffies + msecs_to_jiffies(cal_interval)); | ||
607 | } | ||
608 | |||
493 | /******************/ | 609 | /******************/ |
494 | /* VAP management */ | 610 | /* VAP management */ |
495 | /******************/ | 611 | /******************/ |
@@ -676,12 +792,6 @@ int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan) | |||
676 | if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) | 792 | if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) |
677 | sc->sc_imask |= ATH9K_INT_CST; | 793 | sc->sc_imask |= ATH9K_INT_CST; |
678 | 794 | ||
679 | /* Note: We disable MIB interrupts for now as we don't yet | ||
680 | * handle processing ANI, otherwise you will get an interrupt | ||
681 | * storm after about 7 hours of usage making the system unusable | ||
682 | * with huge latency. Once we do have ANI processing included | ||
683 | * we can re-enable this interrupt. */ | ||
684 | #if 0 | ||
685 | /* | 795 | /* |
686 | * Enable MIB interrupts when there are hardware phy counters. | 796 | * Enable MIB interrupts when there are hardware phy counters. |
687 | * Note we only do this (at the moment) for station mode. | 797 | * Note we only do this (at the moment) for station mode. |
@@ -690,7 +800,6 @@ int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan) | |||
690 | ((sc->sc_ah->ah_opmode == ATH9K_M_STA) || | 800 | ((sc->sc_ah->ah_opmode == ATH9K_M_STA) || |
691 | (sc->sc_ah->ah_opmode == ATH9K_M_IBSS))) | 801 | (sc->sc_ah->ah_opmode == ATH9K_M_IBSS))) |
692 | sc->sc_imask |= ATH9K_INT_MIB; | 802 | sc->sc_imask |= ATH9K_INT_MIB; |
693 | #endif | ||
694 | /* | 803 | /* |
695 | * Some hardware processes the TIM IE and fires an | 804 | * Some hardware processes the TIM IE and fires an |
696 | * interrupt when the TIM bit is set. For hardware | 805 | * interrupt when the TIM bit is set. For hardware |
@@ -991,6 +1100,10 @@ int ath_init(u16 devid, struct ath_softc *sc) | |||
991 | } | 1100 | } |
992 | sc->sc_ah = ah; | 1101 | sc->sc_ah = ah; |
993 | 1102 | ||
1103 | /* Initializes the noise floor to a reasonable default value. | ||
1104 | * Later on this will be updated during ANI processing. */ | ||
1105 | sc->sc_ani.sc_noise_floor = ATH_DEFAULT_NOISE_FLOOR; | ||
1106 | |||
994 | /* Get the hardware key cache size. */ | 1107 | /* Get the hardware key cache size. */ |
995 | sc->sc_keymax = ah->ah_caps.keycache_size; | 1108 | sc->sc_keymax = ah->ah_caps.keycache_size; |
996 | if (sc->sc_keymax > ATH_KEYMAX) { | 1109 | if (sc->sc_keymax > ATH_KEYMAX) { |
@@ -1098,6 +1211,8 @@ int ath_init(u16 devid, struct ath_softc *sc) | |||
1098 | goto bad2; | 1211 | goto bad2; |
1099 | } | 1212 | } |
1100 | 1213 | ||
1214 | setup_timer(&sc->sc_ani.timer, ath_ani_calibrate, (unsigned long)sc); | ||
1215 | |||
1101 | sc->sc_rc = ath_rate_attach(ah); | 1216 | sc->sc_rc = ath_rate_attach(ah); |
1102 | if (sc->sc_rc == NULL) { | 1217 | if (sc->sc_rc == NULL) { |
1103 | error = -EIO; | 1218 | error = -EIO; |
diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h index 5b4f1c48a618..cb3e61e57c4d 100644 --- a/drivers/net/wireless/ath9k/core.h +++ b/drivers/net/wireless/ath9k/core.h | |||
@@ -800,6 +800,28 @@ void ath_slow_ant_div(struct ath_antdiv *antdiv, | |||
800 | struct ath_rx_status *rx_stats); | 800 | struct ath_rx_status *rx_stats); |
801 | void ath_setdefantenna(void *sc, u32 antenna); | 801 | void ath_setdefantenna(void *sc, u32 antenna); |
802 | 802 | ||
803 | /*******/ | ||
804 | /* ANI */ | ||
805 | /*******/ | ||
806 | |||
807 | /* ANI values for STA only. | ||
808 | FIXME: Add appropriate values for AP later */ | ||
809 | |||
810 | #define ATH_ANI_POLLINTERVAL 100 /* 100 milliseconds between ANI poll */ | ||
811 | #define ATH_SHORT_CALINTERVAL 1000 /* 1 second between calibrations */ | ||
812 | #define ATH_LONG_CALINTERVAL 30000 /* 30 seconds between calibrations */ | ||
813 | #define ATH_RESTART_CALINTERVAL 1200000 /* 20 minutes between calibrations */ | ||
814 | |||
815 | struct ath_ani { | ||
816 | bool sc_caldone; | ||
817 | int16_t sc_noise_floor; | ||
818 | unsigned int sc_longcal_timer; | ||
819 | unsigned int sc_shortcal_timer; | ||
820 | unsigned int sc_resetcal_timer; | ||
821 | unsigned int sc_checkani_timer; | ||
822 | struct timer_list timer; | ||
823 | }; | ||
824 | |||
803 | /********************/ | 825 | /********************/ |
804 | /* LED Control */ | 826 | /* LED Control */ |
805 | /********************/ | 827 | /********************/ |
@@ -1028,6 +1050,9 @@ struct ath_softc { | |||
1028 | 1050 | ||
1029 | /* Rfkill */ | 1051 | /* Rfkill */ |
1030 | struct ath_rfkill rf_kill; | 1052 | struct ath_rfkill rf_kill; |
1053 | |||
1054 | /* ANI */ | ||
1055 | struct ath_ani sc_ani; | ||
1031 | }; | 1056 | }; |
1032 | 1057 | ||
1033 | int ath_init(u16 devid, struct ath_softc *sc); | 1058 | int ath_init(u16 devid, struct ath_softc *sc); |
diff --git a/drivers/net/wireless/ath9k/hw.c b/drivers/net/wireless/ath9k/hw.c index 272c75816609..62e44a0ef996 100644 --- a/drivers/net/wireless/ath9k/hw.c +++ b/drivers/net/wireless/ath9k/hw.c | |||
@@ -329,7 +329,7 @@ static void ath9k_hw_set_defaults(struct ath_hal *ah) | |||
329 | ah->ah_config.ofdm_trig_high = 500; | 329 | ah->ah_config.ofdm_trig_high = 500; |
330 | ah->ah_config.cck_trig_high = 200; | 330 | ah->ah_config.cck_trig_high = 200; |
331 | ah->ah_config.cck_trig_low = 100; | 331 | ah->ah_config.cck_trig_low = 100; |
332 | ah->ah_config.enable_ani = 0; | 332 | ah->ah_config.enable_ani = 1; |
333 | ah->ah_config.noise_immunity_level = 4; | 333 | ah->ah_config.noise_immunity_level = 4; |
334 | ah->ah_config.ofdm_weaksignal_det = 1; | 334 | ah->ah_config.ofdm_weaksignal_det = 1; |
335 | ah->ah_config.cck_weaksignal_thr = 0; | 335 | ah->ah_config.cck_weaksignal_thr = 0; |
@@ -8405,23 +8405,48 @@ u32 ath9k_hw_mhz2ieee(struct ath_hal *ah, u32 freq, u32 flags) | |||
8405 | } | 8405 | } |
8406 | } | 8406 | } |
8407 | 8407 | ||
8408 | int16_t | 8408 | /* We can tune this as we go by monitoring really low values */ |
8409 | #define ATH9K_NF_TOO_LOW -60 | ||
8410 | |||
8411 | /* AR5416 may return very high value (like -31 dBm), in those cases the nf | ||
8412 | * is incorrect and we should use the static NF value. Later we can try to | ||
8413 | * find out why they are reporting these values */ | ||
8414 | static bool ath9k_hw_nf_in_range(struct ath_hal *ah, s16 nf) | ||
8415 | { | ||
8416 | if (nf > ATH9K_NF_TOO_LOW) { | ||
8417 | DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL, | ||
8418 | "%s: noise floor value detected (%d) is " | ||
8419 | "lower than what we think is a " | ||
8420 | "reasonable value (%d)\n", | ||
8421 | __func__, nf, ATH9K_NF_TOO_LOW); | ||
8422 | return false; | ||
8423 | } | ||
8424 | return true; | ||
8425 | } | ||
8426 | |||
8427 | s16 | ||
8409 | ath9k_hw_getchan_noise(struct ath_hal *ah, struct ath9k_channel *chan) | 8428 | ath9k_hw_getchan_noise(struct ath_hal *ah, struct ath9k_channel *chan) |
8410 | { | 8429 | { |
8411 | struct ath9k_channel *ichan; | 8430 | struct ath9k_channel *ichan; |
8431 | s16 nf; | ||
8412 | 8432 | ||
8413 | ichan = ath9k_regd_check_channel(ah, chan); | 8433 | ichan = ath9k_regd_check_channel(ah, chan); |
8414 | if (ichan == NULL) { | 8434 | if (ichan == NULL) { |
8415 | DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL, | 8435 | DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL, |
8416 | "%s: invalid channel %u/0x%x; no mapping\n", | 8436 | "%s: invalid channel %u/0x%x; no mapping\n", |
8417 | __func__, chan->channel, chan->channelFlags); | 8437 | __func__, chan->channel, chan->channelFlags); |
8418 | return 0; | 8438 | return ATH_DEFAULT_NOISE_FLOOR; |
8419 | } | 8439 | } |
8420 | if (ichan->rawNoiseFloor == 0) { | 8440 | if (ichan->rawNoiseFloor == 0) { |
8421 | enum wireless_mode mode = ath9k_hw_chan2wmode(ah, chan); | 8441 | enum wireless_mode mode = ath9k_hw_chan2wmode(ah, chan); |
8422 | return NOISE_FLOOR[mode]; | 8442 | nf = NOISE_FLOOR[mode]; |
8423 | } else | 8443 | } else |
8424 | return ichan->rawNoiseFloor; | 8444 | nf = ichan->rawNoiseFloor; |
8445 | |||
8446 | if (!ath9k_hw_nf_in_range(ah, nf)) | ||
8447 | nf = ATH_DEFAULT_NOISE_FLOOR; | ||
8448 | |||
8449 | return nf; | ||
8425 | } | 8450 | } |
8426 | 8451 | ||
8427 | bool ath9k_hw_set_tsfadjust(struct ath_hal *ah, u32 setting) | 8452 | bool ath9k_hw_set_tsfadjust(struct ath_hal *ah, u32 setting) |
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index 2caba4403167..74726990d59e 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c | |||
@@ -274,10 +274,12 @@ static void ath9k_rx_prepare(struct ath_softc *sc, | |||
274 | rx_status->mactime = status->tsf; | 274 | rx_status->mactime = status->tsf; |
275 | rx_status->band = curchan->band; | 275 | rx_status->band = curchan->band; |
276 | rx_status->freq = curchan->center_freq; | 276 | rx_status->freq = curchan->center_freq; |
277 | rx_status->noise = ATH_DEFAULT_NOISE_FLOOR; | 277 | rx_status->noise = sc->sc_ani.sc_noise_floor; |
278 | rx_status->signal = rx_status->noise + status->rssi; | 278 | rx_status->signal = rx_status->noise + status->rssi; |
279 | rx_status->rate_idx = ath_rate2idx(sc, (status->rateKbps / 100)); | 279 | rx_status->rate_idx = ath_rate2idx(sc, (status->rateKbps / 100)); |
280 | rx_status->antenna = status->antenna; | 280 | rx_status->antenna = status->antenna; |
281 | |||
282 | /* XXX Fix me, 64 cannot be the max rssi value, rigure it out */ | ||
281 | rx_status->qual = status->rssi * 100 / 64; | 283 | rx_status->qual = status->rssi * 100 / 64; |
282 | 284 | ||
283 | if (status->flags & ATH_RX_MIC_ERROR) | 285 | if (status->flags & ATH_RX_MIC_ERROR) |
@@ -427,6 +429,11 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc, | |||
427 | ath_rate_newstate(sc, avp); | 429 | ath_rate_newstate(sc, avp); |
428 | /* Update ratectrl about the new state */ | 430 | /* Update ratectrl about the new state */ |
429 | ath_rc_node_update(hw, avp->rc_node); | 431 | ath_rc_node_update(hw, avp->rc_node); |
432 | |||
433 | /* Start ANI */ | ||
434 | mod_timer(&sc->sc_ani.timer, | ||
435 | jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL)); | ||
436 | |||
430 | } else { | 437 | } else { |
431 | DPRINTF(sc, ATH_DBG_CONFIG, | 438 | DPRINTF(sc, ATH_DBG_CONFIG, |
432 | "%s: Bss Info DISSOC\n", __func__); | 439 | "%s: Bss Info DISSOC\n", __func__); |
@@ -1173,6 +1180,13 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, | |||
1173 | return error; | 1180 | return error; |
1174 | } | 1181 | } |
1175 | 1182 | ||
1183 | if (conf->type == NL80211_IFTYPE_AP) { | ||
1184 | /* TODO: is this a suitable place to start ANI for AP mode? */ | ||
1185 | /* Start ANI */ | ||
1186 | mod_timer(&sc->sc_ani.timer, | ||
1187 | jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL)); | ||
1188 | } | ||
1189 | |||
1176 | return 0; | 1190 | return 0; |
1177 | } | 1191 | } |
1178 | 1192 | ||
@@ -1195,6 +1209,8 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, | |||
1195 | #ifdef CONFIG_SLOW_ANT_DIV | 1209 | #ifdef CONFIG_SLOW_ANT_DIV |
1196 | ath_slow_ant_div_stop(&sc->sc_antdiv); | 1210 | ath_slow_ant_div_stop(&sc->sc_antdiv); |
1197 | #endif | 1211 | #endif |
1212 | /* Stop ANI */ | ||
1213 | del_timer_sync(&sc->sc_ani.timer); | ||
1198 | 1214 | ||
1199 | /* Update ratectrl */ | 1215 | /* Update ratectrl */ |
1200 | ath_rate_newstate(sc, avp); | 1216 | ath_rate_newstate(sc, avp); |
diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index f4be5d11c9d5..4983402af559 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c | |||
@@ -999,20 +999,11 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) | |||
999 | rx_status.flags |= ATH_RX_SHORT_GI; | 999 | rx_status.flags |= ATH_RX_SHORT_GI; |
1000 | } | 1000 | } |
1001 | 1001 | ||
1002 | /* sc->sc_noise_floor is only available when the station | 1002 | /* sc_noise_floor is only available when the station |
1003 | attaches to an AP, so we use a default value | 1003 | attaches to an AP, so we use a default value |
1004 | if we are not yet attached. */ | 1004 | if we are not yet attached. */ |
1005 | |||
1006 | /* XXX we should use either sc->sc_noise_floor or | ||
1007 | * ath_hal_getChanNoise(ah, &sc->sc_curchan) | ||
1008 | * to calculate the noise floor. | ||
1009 | * However, the value returned by ath_hal_getChanNoise | ||
1010 | * seems to be incorrect (-31dBm on the last test), | ||
1011 | * so we will use a hard-coded value until we | ||
1012 | * figure out what is going on. | ||
1013 | */ | ||
1014 | rx_status.abs_rssi = | 1005 | rx_status.abs_rssi = |
1015 | ds->ds_rxstat.rs_rssi + ATH_DEFAULT_NOISE_FLOOR; | 1006 | ds->ds_rxstat.rs_rssi + sc->sc_ani.sc_noise_floor; |
1016 | 1007 | ||
1017 | pci_dma_sync_single_for_cpu(sc->pdev, | 1008 | pci_dma_sync_single_for_cpu(sc->pdev, |
1018 | bf->bf_buf_addr, | 1009 | bf->bf_buf_addr, |