diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/mac80211/Makefile | 1 | ||||
-rw-r--r-- | net/mac80211/cfg.c | 340 | ||||
-rw-r--r-- | net/mac80211/ethtool.c | 244 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 2 | ||||
-rw-r--r-- | net/mac80211/iface.c | 2 | ||||
-rw-r--r-- | net/mac80211/sta_info.c | 134 | ||||
-rw-r--r-- | net/mac80211/sta_info.h | 2 | ||||
-rw-r--r-- | net/wireless/core.c | 3 | ||||
-rw-r--r-- | net/wireless/ethtool.c | 86 | ||||
-rw-r--r-- | net/wireless/ethtool.h | 6 | ||||
-rw-r--r-- | net/wireless/rdev-ops.h | 48 | ||||
-rw-r--r-- | net/wireless/trace.h | 49 |
12 files changed, 387 insertions, 530 deletions
diff --git a/net/mac80211/Makefile b/net/mac80211/Makefile index 4409bf506594..7273d2796dd1 100644 --- a/net/mac80211/Makefile +++ b/net/mac80211/Makefile | |||
@@ -17,6 +17,7 @@ mac80211-y := \ | |||
17 | aes_ccm.o \ | 17 | aes_ccm.o \ |
18 | aes_cmac.o \ | 18 | aes_cmac.o \ |
19 | cfg.o \ | 19 | cfg.o \ |
20 | ethtool.o \ | ||
20 | rx.o \ | 21 | rx.o \ |
21 | spectmgmt.o \ | 22 | spectmgmt.o \ |
22 | tx.o \ | 23 | tx.o \ |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index f8d065480ba9..b6d73c14e1ae 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -468,326 +468,6 @@ void sta_set_rate_info_rx(struct sta_info *sta, struct rate_info *rinfo) | |||
468 | rinfo->flags |= RATE_INFO_FLAGS_160_MHZ_WIDTH; | 468 | rinfo->flags |= RATE_INFO_FLAGS_160_MHZ_WIDTH; |
469 | } | 469 | } |
470 | 470 | ||
471 | static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) | ||
472 | { | ||
473 | struct ieee80211_sub_if_data *sdata = sta->sdata; | ||
474 | struct ieee80211_local *local = sdata->local; | ||
475 | struct rate_control_ref *ref = local->rate_ctrl; | ||
476 | struct timespec uptime; | ||
477 | u64 packets = 0; | ||
478 | u32 thr = 0; | ||
479 | int i, ac; | ||
480 | |||
481 | sinfo->generation = sdata->local->sta_generation; | ||
482 | |||
483 | sinfo->filled = STATION_INFO_INACTIVE_TIME | | ||
484 | STATION_INFO_RX_BYTES64 | | ||
485 | STATION_INFO_TX_BYTES64 | | ||
486 | STATION_INFO_RX_PACKETS | | ||
487 | STATION_INFO_TX_PACKETS | | ||
488 | STATION_INFO_TX_RETRIES | | ||
489 | STATION_INFO_TX_FAILED | | ||
490 | STATION_INFO_TX_BITRATE | | ||
491 | STATION_INFO_RX_BITRATE | | ||
492 | STATION_INFO_RX_DROP_MISC | | ||
493 | STATION_INFO_BSS_PARAM | | ||
494 | STATION_INFO_CONNECTED_TIME | | ||
495 | STATION_INFO_STA_FLAGS | | ||
496 | STATION_INFO_BEACON_LOSS_COUNT; | ||
497 | |||
498 | do_posix_clock_monotonic_gettime(&uptime); | ||
499 | sinfo->connected_time = uptime.tv_sec - sta->last_connected; | ||
500 | |||
501 | sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx); | ||
502 | sinfo->tx_bytes = 0; | ||
503 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { | ||
504 | sinfo->tx_bytes += sta->tx_bytes[ac]; | ||
505 | packets += sta->tx_packets[ac]; | ||
506 | } | ||
507 | sinfo->tx_packets = packets; | ||
508 | sinfo->rx_bytes = sta->rx_bytes; | ||
509 | sinfo->rx_packets = sta->rx_packets; | ||
510 | sinfo->tx_retries = sta->tx_retry_count; | ||
511 | sinfo->tx_failed = sta->tx_retry_failed; | ||
512 | sinfo->rx_dropped_misc = sta->rx_dropped; | ||
513 | sinfo->beacon_loss_count = sta->beacon_loss_count; | ||
514 | |||
515 | if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) || | ||
516 | (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) { | ||
517 | sinfo->filled |= STATION_INFO_SIGNAL | STATION_INFO_SIGNAL_AVG; | ||
518 | if (!local->ops->get_rssi || | ||
519 | drv_get_rssi(local, sdata, &sta->sta, &sinfo->signal)) | ||
520 | sinfo->signal = (s8)sta->last_signal; | ||
521 | sinfo->signal_avg = (s8) -ewma_read(&sta->avg_signal); | ||
522 | } | ||
523 | if (sta->chains) { | ||
524 | sinfo->filled |= STATION_INFO_CHAIN_SIGNAL | | ||
525 | STATION_INFO_CHAIN_SIGNAL_AVG; | ||
526 | |||
527 | sinfo->chains = sta->chains; | ||
528 | for (i = 0; i < ARRAY_SIZE(sinfo->chain_signal); i++) { | ||
529 | sinfo->chain_signal[i] = sta->chain_signal_last[i]; | ||
530 | sinfo->chain_signal_avg[i] = | ||
531 | (s8) -ewma_read(&sta->chain_signal_avg[i]); | ||
532 | } | ||
533 | } | ||
534 | |||
535 | sta_set_rate_info_tx(sta, &sta->last_tx_rate, &sinfo->txrate); | ||
536 | sta_set_rate_info_rx(sta, &sinfo->rxrate); | ||
537 | |||
538 | if (ieee80211_vif_is_mesh(&sdata->vif)) { | ||
539 | #ifdef CONFIG_MAC80211_MESH | ||
540 | sinfo->filled |= STATION_INFO_LLID | | ||
541 | STATION_INFO_PLID | | ||
542 | STATION_INFO_PLINK_STATE | | ||
543 | STATION_INFO_LOCAL_PM | | ||
544 | STATION_INFO_PEER_PM | | ||
545 | STATION_INFO_NONPEER_PM; | ||
546 | |||
547 | sinfo->llid = sta->llid; | ||
548 | sinfo->plid = sta->plid; | ||
549 | sinfo->plink_state = sta->plink_state; | ||
550 | if (test_sta_flag(sta, WLAN_STA_TOFFSET_KNOWN)) { | ||
551 | sinfo->filled |= STATION_INFO_T_OFFSET; | ||
552 | sinfo->t_offset = sta->t_offset; | ||
553 | } | ||
554 | sinfo->local_pm = sta->local_pm; | ||
555 | sinfo->peer_pm = sta->peer_pm; | ||
556 | sinfo->nonpeer_pm = sta->nonpeer_pm; | ||
557 | #endif | ||
558 | } | ||
559 | |||
560 | sinfo->bss_param.flags = 0; | ||
561 | if (sdata->vif.bss_conf.use_cts_prot) | ||
562 | sinfo->bss_param.flags |= BSS_PARAM_FLAGS_CTS_PROT; | ||
563 | if (sdata->vif.bss_conf.use_short_preamble) | ||
564 | sinfo->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_PREAMBLE; | ||
565 | if (sdata->vif.bss_conf.use_short_slot) | ||
566 | sinfo->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_SLOT_TIME; | ||
567 | sinfo->bss_param.dtim_period = sdata->local->hw.conf.ps_dtim_period; | ||
568 | sinfo->bss_param.beacon_interval = sdata->vif.bss_conf.beacon_int; | ||
569 | |||
570 | sinfo->sta_flags.set = 0; | ||
571 | sinfo->sta_flags.mask = BIT(NL80211_STA_FLAG_AUTHORIZED) | | ||
572 | BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) | | ||
573 | BIT(NL80211_STA_FLAG_WME) | | ||
574 | BIT(NL80211_STA_FLAG_MFP) | | ||
575 | BIT(NL80211_STA_FLAG_AUTHENTICATED) | | ||
576 | BIT(NL80211_STA_FLAG_ASSOCIATED) | | ||
577 | BIT(NL80211_STA_FLAG_TDLS_PEER); | ||
578 | if (test_sta_flag(sta, WLAN_STA_AUTHORIZED)) | ||
579 | sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_AUTHORIZED); | ||
580 | if (test_sta_flag(sta, WLAN_STA_SHORT_PREAMBLE)) | ||
581 | sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_SHORT_PREAMBLE); | ||
582 | if (test_sta_flag(sta, WLAN_STA_WME)) | ||
583 | sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_WME); | ||
584 | if (test_sta_flag(sta, WLAN_STA_MFP)) | ||
585 | sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_MFP); | ||
586 | if (test_sta_flag(sta, WLAN_STA_AUTH)) | ||
587 | sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_AUTHENTICATED); | ||
588 | if (test_sta_flag(sta, WLAN_STA_ASSOC)) | ||
589 | sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_ASSOCIATED); | ||
590 | if (test_sta_flag(sta, WLAN_STA_TDLS_PEER)) | ||
591 | sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_TDLS_PEER); | ||
592 | |||
593 | /* check if the driver has a SW RC implementation */ | ||
594 | if (ref && ref->ops->get_expected_throughput) | ||
595 | thr = ref->ops->get_expected_throughput(sta->rate_ctrl_priv); | ||
596 | else | ||
597 | thr = drv_get_expected_throughput(local, &sta->sta); | ||
598 | |||
599 | if (thr != 0) { | ||
600 | sinfo->filled |= STATION_INFO_EXPECTED_THROUGHPUT; | ||
601 | sinfo->expected_throughput = thr; | ||
602 | } | ||
603 | } | ||
604 | |||
605 | static const char ieee80211_gstrings_sta_stats[][ETH_GSTRING_LEN] = { | ||
606 | "rx_packets", "rx_bytes", | ||
607 | "rx_duplicates", "rx_fragments", "rx_dropped", | ||
608 | "tx_packets", "tx_bytes", "tx_fragments", | ||
609 | "tx_filtered", "tx_retry_failed", "tx_retries", | ||
610 | "beacon_loss", "sta_state", "txrate", "rxrate", "signal", | ||
611 | "channel", "noise", "ch_time", "ch_time_busy", | ||
612 | "ch_time_ext_busy", "ch_time_rx", "ch_time_tx" | ||
613 | }; | ||
614 | #define STA_STATS_LEN ARRAY_SIZE(ieee80211_gstrings_sta_stats) | ||
615 | |||
616 | static int ieee80211_get_et_sset_count(struct wiphy *wiphy, | ||
617 | struct net_device *dev, | ||
618 | int sset) | ||
619 | { | ||
620 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
621 | int rv = 0; | ||
622 | |||
623 | if (sset == ETH_SS_STATS) | ||
624 | rv += STA_STATS_LEN; | ||
625 | |||
626 | rv += drv_get_et_sset_count(sdata, sset); | ||
627 | |||
628 | if (rv == 0) | ||
629 | return -EOPNOTSUPP; | ||
630 | return rv; | ||
631 | } | ||
632 | |||
633 | static void ieee80211_get_et_stats(struct wiphy *wiphy, | ||
634 | struct net_device *dev, | ||
635 | struct ethtool_stats *stats, | ||
636 | u64 *data) | ||
637 | { | ||
638 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
639 | struct ieee80211_chanctx_conf *chanctx_conf; | ||
640 | struct ieee80211_channel *channel; | ||
641 | struct sta_info *sta; | ||
642 | struct ieee80211_local *local = sdata->local; | ||
643 | struct station_info sinfo; | ||
644 | struct survey_info survey; | ||
645 | int i, q; | ||
646 | #define STA_STATS_SURVEY_LEN 7 | ||
647 | |||
648 | memset(data, 0, sizeof(u64) * STA_STATS_LEN); | ||
649 | |||
650 | #define ADD_STA_STATS(sta) \ | ||
651 | do { \ | ||
652 | data[i++] += sta->rx_packets; \ | ||
653 | data[i++] += sta->rx_bytes; \ | ||
654 | data[i++] += sta->num_duplicates; \ | ||
655 | data[i++] += sta->rx_fragments; \ | ||
656 | data[i++] += sta->rx_dropped; \ | ||
657 | \ | ||
658 | data[i++] += sinfo.tx_packets; \ | ||
659 | data[i++] += sinfo.tx_bytes; \ | ||
660 | data[i++] += sta->tx_fragments; \ | ||
661 | data[i++] += sta->tx_filtered_count; \ | ||
662 | data[i++] += sta->tx_retry_failed; \ | ||
663 | data[i++] += sta->tx_retry_count; \ | ||
664 | data[i++] += sta->beacon_loss_count; \ | ||
665 | } while (0) | ||
666 | |||
667 | /* For Managed stations, find the single station based on BSSID | ||
668 | * and use that. For interface types, iterate through all available | ||
669 | * stations and add stats for any station that is assigned to this | ||
670 | * network device. | ||
671 | */ | ||
672 | |||
673 | mutex_lock(&local->sta_mtx); | ||
674 | |||
675 | if (sdata->vif.type == NL80211_IFTYPE_STATION) { | ||
676 | sta = sta_info_get_bss(sdata, sdata->u.mgd.bssid); | ||
677 | |||
678 | if (!(sta && !WARN_ON(sta->sdata->dev != dev))) | ||
679 | goto do_survey; | ||
680 | |||
681 | sinfo.filled = 0; | ||
682 | sta_set_sinfo(sta, &sinfo); | ||
683 | |||
684 | i = 0; | ||
685 | ADD_STA_STATS(sta); | ||
686 | |||
687 | data[i++] = sta->sta_state; | ||
688 | |||
689 | |||
690 | if (sinfo.filled & STATION_INFO_TX_BITRATE) | ||
691 | data[i] = 100000 * | ||
692 | cfg80211_calculate_bitrate(&sinfo.txrate); | ||
693 | i++; | ||
694 | if (sinfo.filled & STATION_INFO_RX_BITRATE) | ||
695 | data[i] = 100000 * | ||
696 | cfg80211_calculate_bitrate(&sinfo.rxrate); | ||
697 | i++; | ||
698 | |||
699 | if (sinfo.filled & STATION_INFO_SIGNAL_AVG) | ||
700 | data[i] = (u8)sinfo.signal_avg; | ||
701 | i++; | ||
702 | } else { | ||
703 | list_for_each_entry(sta, &local->sta_list, list) { | ||
704 | /* Make sure this station belongs to the proper dev */ | ||
705 | if (sta->sdata->dev != dev) | ||
706 | continue; | ||
707 | |||
708 | sinfo.filled = 0; | ||
709 | sta_set_sinfo(sta, &sinfo); | ||
710 | i = 0; | ||
711 | ADD_STA_STATS(sta); | ||
712 | } | ||
713 | } | ||
714 | |||
715 | do_survey: | ||
716 | i = STA_STATS_LEN - STA_STATS_SURVEY_LEN; | ||
717 | /* Get survey stats for current channel */ | ||
718 | survey.filled = 0; | ||
719 | |||
720 | rcu_read_lock(); | ||
721 | chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); | ||
722 | if (chanctx_conf) | ||
723 | channel = chanctx_conf->def.chan; | ||
724 | else | ||
725 | channel = NULL; | ||
726 | rcu_read_unlock(); | ||
727 | |||
728 | if (channel) { | ||
729 | q = 0; | ||
730 | do { | ||
731 | survey.filled = 0; | ||
732 | if (drv_get_survey(local, q, &survey) != 0) { | ||
733 | survey.filled = 0; | ||
734 | break; | ||
735 | } | ||
736 | q++; | ||
737 | } while (channel != survey.channel); | ||
738 | } | ||
739 | |||
740 | if (survey.filled) | ||
741 | data[i++] = survey.channel->center_freq; | ||
742 | else | ||
743 | data[i++] = 0; | ||
744 | if (survey.filled & SURVEY_INFO_NOISE_DBM) | ||
745 | data[i++] = (u8)survey.noise; | ||
746 | else | ||
747 | data[i++] = -1LL; | ||
748 | if (survey.filled & SURVEY_INFO_CHANNEL_TIME) | ||
749 | data[i++] = survey.channel_time; | ||
750 | else | ||
751 | data[i++] = -1LL; | ||
752 | if (survey.filled & SURVEY_INFO_CHANNEL_TIME_BUSY) | ||
753 | data[i++] = survey.channel_time_busy; | ||
754 | else | ||
755 | data[i++] = -1LL; | ||
756 | if (survey.filled & SURVEY_INFO_CHANNEL_TIME_EXT_BUSY) | ||
757 | data[i++] = survey.channel_time_ext_busy; | ||
758 | else | ||
759 | data[i++] = -1LL; | ||
760 | if (survey.filled & SURVEY_INFO_CHANNEL_TIME_RX) | ||
761 | data[i++] = survey.channel_time_rx; | ||
762 | else | ||
763 | data[i++] = -1LL; | ||
764 | if (survey.filled & SURVEY_INFO_CHANNEL_TIME_TX) | ||
765 | data[i++] = survey.channel_time_tx; | ||
766 | else | ||
767 | data[i++] = -1LL; | ||
768 | |||
769 | mutex_unlock(&local->sta_mtx); | ||
770 | |||
771 | if (WARN_ON(i != STA_STATS_LEN)) | ||
772 | return; | ||
773 | |||
774 | drv_get_et_stats(sdata, stats, &(data[STA_STATS_LEN])); | ||
775 | } | ||
776 | |||
777 | static void ieee80211_get_et_strings(struct wiphy *wiphy, | ||
778 | struct net_device *dev, | ||
779 | u32 sset, u8 *data) | ||
780 | { | ||
781 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
782 | int sz_sta_stats = 0; | ||
783 | |||
784 | if (sset == ETH_SS_STATS) { | ||
785 | sz_sta_stats = sizeof(ieee80211_gstrings_sta_stats); | ||
786 | memcpy(data, ieee80211_gstrings_sta_stats, sz_sta_stats); | ||
787 | } | ||
788 | drv_get_et_strings(sdata, sset, &(data[sz_sta_stats])); | ||
789 | } | ||
790 | |||
791 | static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev, | 471 | static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev, |
792 | int idx, u8 *mac, struct station_info *sinfo) | 472 | int idx, u8 *mac, struct station_info *sinfo) |
793 | { | 473 | { |
@@ -3597,21 +3277,6 @@ static int ieee80211_get_antenna(struct wiphy *wiphy, u32 *tx_ant, u32 *rx_ant) | |||
3597 | return drv_get_antenna(local, tx_ant, rx_ant); | 3277 | return drv_get_antenna(local, tx_ant, rx_ant); |
3598 | } | 3278 | } |
3599 | 3279 | ||
3600 | static int ieee80211_set_ringparam(struct wiphy *wiphy, u32 tx, u32 rx) | ||
3601 | { | ||
3602 | struct ieee80211_local *local = wiphy_priv(wiphy); | ||
3603 | |||
3604 | return drv_set_ringparam(local, tx, rx); | ||
3605 | } | ||
3606 | |||
3607 | static void ieee80211_get_ringparam(struct wiphy *wiphy, | ||
3608 | u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max) | ||
3609 | { | ||
3610 | struct ieee80211_local *local = wiphy_priv(wiphy); | ||
3611 | |||
3612 | drv_get_ringparam(local, tx, tx_max, rx, rx_max); | ||
3613 | } | ||
3614 | |||
3615 | static int ieee80211_set_rekey_data(struct wiphy *wiphy, | 3280 | static int ieee80211_set_rekey_data(struct wiphy *wiphy, |
3616 | struct net_device *dev, | 3281 | struct net_device *dev, |
3617 | struct cfg80211_gtk_rekey_data *data) | 3282 | struct cfg80211_gtk_rekey_data *data) |
@@ -3843,8 +3508,6 @@ const struct cfg80211_ops mac80211_config_ops = { | |||
3843 | .mgmt_frame_register = ieee80211_mgmt_frame_register, | 3508 | .mgmt_frame_register = ieee80211_mgmt_frame_register, |
3844 | .set_antenna = ieee80211_set_antenna, | 3509 | .set_antenna = ieee80211_set_antenna, |
3845 | .get_antenna = ieee80211_get_antenna, | 3510 | .get_antenna = ieee80211_get_antenna, |
3846 | .set_ringparam = ieee80211_set_ringparam, | ||
3847 | .get_ringparam = ieee80211_get_ringparam, | ||
3848 | .set_rekey_data = ieee80211_set_rekey_data, | 3511 | .set_rekey_data = ieee80211_set_rekey_data, |
3849 | .tdls_oper = ieee80211_tdls_oper, | 3512 | .tdls_oper = ieee80211_tdls_oper, |
3850 | .tdls_mgmt = ieee80211_tdls_mgmt, | 3513 | .tdls_mgmt = ieee80211_tdls_mgmt, |
@@ -3853,9 +3516,6 @@ const struct cfg80211_ops mac80211_config_ops = { | |||
3853 | #ifdef CONFIG_PM | 3516 | #ifdef CONFIG_PM |
3854 | .set_wakeup = ieee80211_set_wakeup, | 3517 | .set_wakeup = ieee80211_set_wakeup, |
3855 | #endif | 3518 | #endif |
3856 | .get_et_sset_count = ieee80211_get_et_sset_count, | ||
3857 | .get_et_stats = ieee80211_get_et_stats, | ||
3858 | .get_et_strings = ieee80211_get_et_strings, | ||
3859 | .get_channel = ieee80211_cfg_get_channel, | 3519 | .get_channel = ieee80211_cfg_get_channel, |
3860 | .start_radar_detection = ieee80211_start_radar_detection, | 3520 | .start_radar_detection = ieee80211_start_radar_detection, |
3861 | .channel_switch = ieee80211_channel_switch, | 3521 | .channel_switch = ieee80211_channel_switch, |
diff --git a/net/mac80211/ethtool.c b/net/mac80211/ethtool.c new file mode 100644 index 000000000000..ebfc8091557b --- /dev/null +++ b/net/mac80211/ethtool.c | |||
@@ -0,0 +1,244 @@ | |||
1 | /* | ||
2 | * mac80211 ethtool hooks for cfg80211 | ||
3 | * | ||
4 | * Copied from cfg.c - originally | ||
5 | * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net> | ||
6 | * Copyright 2014 Intel Corporation (Author: Johannes Berg) | ||
7 | * | ||
8 | * This file is GPLv2 as found in COPYING. | ||
9 | */ | ||
10 | #include <linux/types.h> | ||
11 | #include <net/cfg80211.h> | ||
12 | #include "ieee80211_i.h" | ||
13 | #include "sta_info.h" | ||
14 | #include "driver-ops.h" | ||
15 | |||
16 | static int ieee80211_set_ringparam(struct net_device *dev, | ||
17 | struct ethtool_ringparam *rp) | ||
18 | { | ||
19 | struct ieee80211_local *local = wiphy_priv(dev->ieee80211_ptr->wiphy); | ||
20 | |||
21 | if (rp->rx_mini_pending != 0 || rp->rx_jumbo_pending != 0) | ||
22 | return -EINVAL; | ||
23 | |||
24 | return drv_set_ringparam(local, rp->tx_pending, rp->rx_pending); | ||
25 | } | ||
26 | |||
27 | static void ieee80211_get_ringparam(struct net_device *dev, | ||
28 | struct ethtool_ringparam *rp) | ||
29 | { | ||
30 | struct ieee80211_local *local = wiphy_priv(dev->ieee80211_ptr->wiphy); | ||
31 | |||
32 | memset(rp, 0, sizeof(*rp)); | ||
33 | |||
34 | drv_get_ringparam(local, &rp->tx_pending, &rp->tx_max_pending, | ||
35 | &rp->rx_pending, &rp->rx_max_pending); | ||
36 | } | ||
37 | |||
38 | static const char ieee80211_gstrings_sta_stats[][ETH_GSTRING_LEN] = { | ||
39 | "rx_packets", "rx_bytes", | ||
40 | "rx_duplicates", "rx_fragments", "rx_dropped", | ||
41 | "tx_packets", "tx_bytes", "tx_fragments", | ||
42 | "tx_filtered", "tx_retry_failed", "tx_retries", | ||
43 | "beacon_loss", "sta_state", "txrate", "rxrate", "signal", | ||
44 | "channel", "noise", "ch_time", "ch_time_busy", | ||
45 | "ch_time_ext_busy", "ch_time_rx", "ch_time_tx" | ||
46 | }; | ||
47 | #define STA_STATS_LEN ARRAY_SIZE(ieee80211_gstrings_sta_stats) | ||
48 | |||
49 | static int ieee80211_get_sset_count(struct net_device *dev, int sset) | ||
50 | { | ||
51 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
52 | int rv = 0; | ||
53 | |||
54 | if (sset == ETH_SS_STATS) | ||
55 | rv += STA_STATS_LEN; | ||
56 | |||
57 | rv += drv_get_et_sset_count(sdata, sset); | ||
58 | |||
59 | if (rv == 0) | ||
60 | return -EOPNOTSUPP; | ||
61 | return rv; | ||
62 | } | ||
63 | |||
64 | static void ieee80211_get_stats(struct net_device *dev, | ||
65 | struct ethtool_stats *stats, | ||
66 | u64 *data) | ||
67 | { | ||
68 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
69 | struct ieee80211_chanctx_conf *chanctx_conf; | ||
70 | struct ieee80211_channel *channel; | ||
71 | struct sta_info *sta; | ||
72 | struct ieee80211_local *local = sdata->local; | ||
73 | struct station_info sinfo; | ||
74 | struct survey_info survey; | ||
75 | int i, q; | ||
76 | #define STA_STATS_SURVEY_LEN 7 | ||
77 | |||
78 | memset(data, 0, sizeof(u64) * STA_STATS_LEN); | ||
79 | |||
80 | #define ADD_STA_STATS(sta) \ | ||
81 | do { \ | ||
82 | data[i++] += sta->rx_packets; \ | ||
83 | data[i++] += sta->rx_bytes; \ | ||
84 | data[i++] += sta->num_duplicates; \ | ||
85 | data[i++] += sta->rx_fragments; \ | ||
86 | data[i++] += sta->rx_dropped; \ | ||
87 | \ | ||
88 | data[i++] += sinfo.tx_packets; \ | ||
89 | data[i++] += sinfo.tx_bytes; \ | ||
90 | data[i++] += sta->tx_fragments; \ | ||
91 | data[i++] += sta->tx_filtered_count; \ | ||
92 | data[i++] += sta->tx_retry_failed; \ | ||
93 | data[i++] += sta->tx_retry_count; \ | ||
94 | data[i++] += sta->beacon_loss_count; \ | ||
95 | } while (0) | ||
96 | |||
97 | /* For Managed stations, find the single station based on BSSID | ||
98 | * and use that. For interface types, iterate through all available | ||
99 | * stations and add stats for any station that is assigned to this | ||
100 | * network device. | ||
101 | */ | ||
102 | |||
103 | mutex_lock(&local->sta_mtx); | ||
104 | |||
105 | if (sdata->vif.type == NL80211_IFTYPE_STATION) { | ||
106 | sta = sta_info_get_bss(sdata, sdata->u.mgd.bssid); | ||
107 | |||
108 | if (!(sta && !WARN_ON(sta->sdata->dev != dev))) | ||
109 | goto do_survey; | ||
110 | |||
111 | sinfo.filled = 0; | ||
112 | sta_set_sinfo(sta, &sinfo); | ||
113 | |||
114 | i = 0; | ||
115 | ADD_STA_STATS(sta); | ||
116 | |||
117 | data[i++] = sta->sta_state; | ||
118 | |||
119 | |||
120 | if (sinfo.filled & STATION_INFO_TX_BITRATE) | ||
121 | data[i] = 100000 * | ||
122 | cfg80211_calculate_bitrate(&sinfo.txrate); | ||
123 | i++; | ||
124 | if (sinfo.filled & STATION_INFO_RX_BITRATE) | ||
125 | data[i] = 100000 * | ||
126 | cfg80211_calculate_bitrate(&sinfo.rxrate); | ||
127 | i++; | ||
128 | |||
129 | if (sinfo.filled & STATION_INFO_SIGNAL_AVG) | ||
130 | data[i] = (u8)sinfo.signal_avg; | ||
131 | i++; | ||
132 | } else { | ||
133 | list_for_each_entry(sta, &local->sta_list, list) { | ||
134 | /* Make sure this station belongs to the proper dev */ | ||
135 | if (sta->sdata->dev != dev) | ||
136 | continue; | ||
137 | |||
138 | sinfo.filled = 0; | ||
139 | sta_set_sinfo(sta, &sinfo); | ||
140 | i = 0; | ||
141 | ADD_STA_STATS(sta); | ||
142 | } | ||
143 | } | ||
144 | |||
145 | do_survey: | ||
146 | i = STA_STATS_LEN - STA_STATS_SURVEY_LEN; | ||
147 | /* Get survey stats for current channel */ | ||
148 | survey.filled = 0; | ||
149 | |||
150 | rcu_read_lock(); | ||
151 | chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); | ||
152 | if (chanctx_conf) | ||
153 | channel = chanctx_conf->def.chan; | ||
154 | else | ||
155 | channel = NULL; | ||
156 | rcu_read_unlock(); | ||
157 | |||
158 | if (channel) { | ||
159 | q = 0; | ||
160 | do { | ||
161 | survey.filled = 0; | ||
162 | if (drv_get_survey(local, q, &survey) != 0) { | ||
163 | survey.filled = 0; | ||
164 | break; | ||
165 | } | ||
166 | q++; | ||
167 | } while (channel != survey.channel); | ||
168 | } | ||
169 | |||
170 | if (survey.filled) | ||
171 | data[i++] = survey.channel->center_freq; | ||
172 | else | ||
173 | data[i++] = 0; | ||
174 | if (survey.filled & SURVEY_INFO_NOISE_DBM) | ||
175 | data[i++] = (u8)survey.noise; | ||
176 | else | ||
177 | data[i++] = -1LL; | ||
178 | if (survey.filled & SURVEY_INFO_CHANNEL_TIME) | ||
179 | data[i++] = survey.channel_time; | ||
180 | else | ||
181 | data[i++] = -1LL; | ||
182 | if (survey.filled & SURVEY_INFO_CHANNEL_TIME_BUSY) | ||
183 | data[i++] = survey.channel_time_busy; | ||
184 | else | ||
185 | data[i++] = -1LL; | ||
186 | if (survey.filled & SURVEY_INFO_CHANNEL_TIME_EXT_BUSY) | ||
187 | data[i++] = survey.channel_time_ext_busy; | ||
188 | else | ||
189 | data[i++] = -1LL; | ||
190 | if (survey.filled & SURVEY_INFO_CHANNEL_TIME_RX) | ||
191 | data[i++] = survey.channel_time_rx; | ||
192 | else | ||
193 | data[i++] = -1LL; | ||
194 | if (survey.filled & SURVEY_INFO_CHANNEL_TIME_TX) | ||
195 | data[i++] = survey.channel_time_tx; | ||
196 | else | ||
197 | data[i++] = -1LL; | ||
198 | |||
199 | mutex_unlock(&local->sta_mtx); | ||
200 | |||
201 | if (WARN_ON(i != STA_STATS_LEN)) | ||
202 | return; | ||
203 | |||
204 | drv_get_et_stats(sdata, stats, &(data[STA_STATS_LEN])); | ||
205 | } | ||
206 | |||
207 | static void ieee80211_get_strings(struct net_device *dev, u32 sset, u8 *data) | ||
208 | { | ||
209 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
210 | int sz_sta_stats = 0; | ||
211 | |||
212 | if (sset == ETH_SS_STATS) { | ||
213 | sz_sta_stats = sizeof(ieee80211_gstrings_sta_stats); | ||
214 | memcpy(data, ieee80211_gstrings_sta_stats, sz_sta_stats); | ||
215 | } | ||
216 | drv_get_et_strings(sdata, sset, &(data[sz_sta_stats])); | ||
217 | } | ||
218 | |||
219 | static int ieee80211_get_regs_len(struct net_device *dev) | ||
220 | { | ||
221 | return 0; | ||
222 | } | ||
223 | |||
224 | static void ieee80211_get_regs(struct net_device *dev, | ||
225 | struct ethtool_regs *regs, | ||
226 | void *data) | ||
227 | { | ||
228 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
229 | |||
230 | regs->version = wdev->wiphy->hw_version; | ||
231 | regs->len = 0; | ||
232 | } | ||
233 | |||
234 | const struct ethtool_ops ieee80211_ethtool_ops = { | ||
235 | .get_drvinfo = cfg80211_get_drvinfo, | ||
236 | .get_regs_len = ieee80211_get_regs_len, | ||
237 | .get_regs = ieee80211_get_regs, | ||
238 | .get_link = ethtool_op_get_link, | ||
239 | .get_ringparam = ieee80211_get_ringparam, | ||
240 | .set_ringparam = ieee80211_set_ringparam, | ||
241 | .get_strings = ieee80211_get_strings, | ||
242 | .get_ethtool_stats = ieee80211_get_stats, | ||
243 | .get_sset_count = ieee80211_get_sset_count, | ||
244 | }; | ||
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index ac9836e0aab3..4372d48b718f 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -1847,6 +1847,8 @@ int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev, | |||
1847 | const u8 *peer, enum nl80211_tdls_operation oper); | 1847 | const u8 *peer, enum nl80211_tdls_operation oper); |
1848 | 1848 | ||
1849 | 1849 | ||
1850 | extern const struct ethtool_ops ieee80211_ethtool_ops; | ||
1851 | |||
1850 | #ifdef CONFIG_MAC80211_NOINLINE | 1852 | #ifdef CONFIG_MAC80211_NOINLINE |
1851 | #define debug_noinline noinline | 1853 | #define debug_noinline noinline |
1852 | #else | 1854 | #else |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 388b863e821c..db5afc7faa22 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -1705,6 +1705,8 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, | |||
1705 | 1705 | ||
1706 | ndev->features |= local->hw.netdev_features; | 1706 | ndev->features |= local->hw.netdev_features; |
1707 | 1707 | ||
1708 | netdev_set_default_ethtool_ops(ndev, &ieee80211_ethtool_ops); | ||
1709 | |||
1708 | ret = register_netdevice(ndev); | 1710 | ret = register_netdevice(ndev); |
1709 | if (ret) { | 1711 | if (ret) { |
1710 | free_netdev(ndev); | 1712 | free_netdev(ndev); |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index ae7c16ad5f22..6fe48f64d0e4 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -1719,3 +1719,137 @@ u8 sta_info_tx_streams(struct sta_info *sta) | |||
1719 | return ((ht_cap->mcs.tx_params & IEEE80211_HT_MCS_TX_MAX_STREAMS_MASK) | 1719 | return ((ht_cap->mcs.tx_params & IEEE80211_HT_MCS_TX_MAX_STREAMS_MASK) |
1720 | >> IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT) + 1; | 1720 | >> IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT) + 1; |
1721 | } | 1721 | } |
1722 | |||
1723 | void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) | ||
1724 | { | ||
1725 | struct ieee80211_sub_if_data *sdata = sta->sdata; | ||
1726 | struct ieee80211_local *local = sdata->local; | ||
1727 | struct rate_control_ref *ref = local->rate_ctrl; | ||
1728 | struct timespec uptime; | ||
1729 | u64 packets = 0; | ||
1730 | u32 thr = 0; | ||
1731 | int i, ac; | ||
1732 | |||
1733 | sinfo->generation = sdata->local->sta_generation; | ||
1734 | |||
1735 | sinfo->filled = STATION_INFO_INACTIVE_TIME | | ||
1736 | STATION_INFO_RX_BYTES64 | | ||
1737 | STATION_INFO_TX_BYTES64 | | ||
1738 | STATION_INFO_RX_PACKETS | | ||
1739 | STATION_INFO_TX_PACKETS | | ||
1740 | STATION_INFO_TX_RETRIES | | ||
1741 | STATION_INFO_TX_FAILED | | ||
1742 | STATION_INFO_TX_BITRATE | | ||
1743 | STATION_INFO_RX_BITRATE | | ||
1744 | STATION_INFO_RX_DROP_MISC | | ||
1745 | STATION_INFO_BSS_PARAM | | ||
1746 | STATION_INFO_CONNECTED_TIME | | ||
1747 | STATION_INFO_STA_FLAGS | | ||
1748 | STATION_INFO_BEACON_LOSS_COUNT; | ||
1749 | |||
1750 | do_posix_clock_monotonic_gettime(&uptime); | ||
1751 | sinfo->connected_time = uptime.tv_sec - sta->last_connected; | ||
1752 | |||
1753 | sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx); | ||
1754 | sinfo->tx_bytes = 0; | ||
1755 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { | ||
1756 | sinfo->tx_bytes += sta->tx_bytes[ac]; | ||
1757 | packets += sta->tx_packets[ac]; | ||
1758 | } | ||
1759 | sinfo->tx_packets = packets; | ||
1760 | sinfo->rx_bytes = sta->rx_bytes; | ||
1761 | sinfo->rx_packets = sta->rx_packets; | ||
1762 | sinfo->tx_retries = sta->tx_retry_count; | ||
1763 | sinfo->tx_failed = sta->tx_retry_failed; | ||
1764 | sinfo->rx_dropped_misc = sta->rx_dropped; | ||
1765 | sinfo->beacon_loss_count = sta->beacon_loss_count; | ||
1766 | |||
1767 | if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) || | ||
1768 | (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) { | ||
1769 | sinfo->filled |= STATION_INFO_SIGNAL | STATION_INFO_SIGNAL_AVG; | ||
1770 | if (!local->ops->get_rssi || | ||
1771 | drv_get_rssi(local, sdata, &sta->sta, &sinfo->signal)) | ||
1772 | sinfo->signal = (s8)sta->last_signal; | ||
1773 | sinfo->signal_avg = (s8) -ewma_read(&sta->avg_signal); | ||
1774 | } | ||
1775 | if (sta->chains) { | ||
1776 | sinfo->filled |= STATION_INFO_CHAIN_SIGNAL | | ||
1777 | STATION_INFO_CHAIN_SIGNAL_AVG; | ||
1778 | |||
1779 | sinfo->chains = sta->chains; | ||
1780 | for (i = 0; i < ARRAY_SIZE(sinfo->chain_signal); i++) { | ||
1781 | sinfo->chain_signal[i] = sta->chain_signal_last[i]; | ||
1782 | sinfo->chain_signal_avg[i] = | ||
1783 | (s8) -ewma_read(&sta->chain_signal_avg[i]); | ||
1784 | } | ||
1785 | } | ||
1786 | |||
1787 | sta_set_rate_info_tx(sta, &sta->last_tx_rate, &sinfo->txrate); | ||
1788 | sta_set_rate_info_rx(sta, &sinfo->rxrate); | ||
1789 | |||
1790 | if (ieee80211_vif_is_mesh(&sdata->vif)) { | ||
1791 | #ifdef CONFIG_MAC80211_MESH | ||
1792 | sinfo->filled |= STATION_INFO_LLID | | ||
1793 | STATION_INFO_PLID | | ||
1794 | STATION_INFO_PLINK_STATE | | ||
1795 | STATION_INFO_LOCAL_PM | | ||
1796 | STATION_INFO_PEER_PM | | ||
1797 | STATION_INFO_NONPEER_PM; | ||
1798 | |||
1799 | sinfo->llid = sta->llid; | ||
1800 | sinfo->plid = sta->plid; | ||
1801 | sinfo->plink_state = sta->plink_state; | ||
1802 | if (test_sta_flag(sta, WLAN_STA_TOFFSET_KNOWN)) { | ||
1803 | sinfo->filled |= STATION_INFO_T_OFFSET; | ||
1804 | sinfo->t_offset = sta->t_offset; | ||
1805 | } | ||
1806 | sinfo->local_pm = sta->local_pm; | ||
1807 | sinfo->peer_pm = sta->peer_pm; | ||
1808 | sinfo->nonpeer_pm = sta->nonpeer_pm; | ||
1809 | #endif | ||
1810 | } | ||
1811 | |||
1812 | sinfo->bss_param.flags = 0; | ||
1813 | if (sdata->vif.bss_conf.use_cts_prot) | ||
1814 | sinfo->bss_param.flags |= BSS_PARAM_FLAGS_CTS_PROT; | ||
1815 | if (sdata->vif.bss_conf.use_short_preamble) | ||
1816 | sinfo->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_PREAMBLE; | ||
1817 | if (sdata->vif.bss_conf.use_short_slot) | ||
1818 | sinfo->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_SLOT_TIME; | ||
1819 | sinfo->bss_param.dtim_period = sdata->local->hw.conf.ps_dtim_period; | ||
1820 | sinfo->bss_param.beacon_interval = sdata->vif.bss_conf.beacon_int; | ||
1821 | |||
1822 | sinfo->sta_flags.set = 0; | ||
1823 | sinfo->sta_flags.mask = BIT(NL80211_STA_FLAG_AUTHORIZED) | | ||
1824 | BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) | | ||
1825 | BIT(NL80211_STA_FLAG_WME) | | ||
1826 | BIT(NL80211_STA_FLAG_MFP) | | ||
1827 | BIT(NL80211_STA_FLAG_AUTHENTICATED) | | ||
1828 | BIT(NL80211_STA_FLAG_ASSOCIATED) | | ||
1829 | BIT(NL80211_STA_FLAG_TDLS_PEER); | ||
1830 | if (test_sta_flag(sta, WLAN_STA_AUTHORIZED)) | ||
1831 | sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_AUTHORIZED); | ||
1832 | if (test_sta_flag(sta, WLAN_STA_SHORT_PREAMBLE)) | ||
1833 | sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_SHORT_PREAMBLE); | ||
1834 | if (test_sta_flag(sta, WLAN_STA_WME)) | ||
1835 | sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_WME); | ||
1836 | if (test_sta_flag(sta, WLAN_STA_MFP)) | ||
1837 | sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_MFP); | ||
1838 | if (test_sta_flag(sta, WLAN_STA_AUTH)) | ||
1839 | sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_AUTHENTICATED); | ||
1840 | if (test_sta_flag(sta, WLAN_STA_ASSOC)) | ||
1841 | sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_ASSOCIATED); | ||
1842 | if (test_sta_flag(sta, WLAN_STA_TDLS_PEER)) | ||
1843 | sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_TDLS_PEER); | ||
1844 | |||
1845 | /* check if the driver has a SW RC implementation */ | ||
1846 | if (ref && ref->ops->get_expected_throughput) | ||
1847 | thr = ref->ops->get_expected_throughput(sta->rate_ctrl_priv); | ||
1848 | else | ||
1849 | thr = drv_get_expected_throughput(local, &sta->sta); | ||
1850 | |||
1851 | if (thr != 0) { | ||
1852 | sinfo->filled |= STATION_INFO_EXPECTED_THROUGHPUT; | ||
1853 | sinfo->expected_throughput = thr; | ||
1854 | } | ||
1855 | } | ||
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index fa7ce6f8593b..2a04361b2162 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h | |||
@@ -627,6 +627,8 @@ void sta_set_rate_info_tx(struct sta_info *sta, | |||
627 | struct rate_info *rinfo); | 627 | struct rate_info *rinfo); |
628 | void sta_set_rate_info_rx(struct sta_info *sta, | 628 | void sta_set_rate_info_rx(struct sta_info *sta, |
629 | struct rate_info *rinfo); | 629 | struct rate_info *rinfo); |
630 | void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo); | ||
631 | |||
630 | void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata, | 632 | void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata, |
631 | unsigned long exp_time); | 633 | unsigned long exp_time); |
632 | u8 sta_info_tx_streams(struct sta_info *sta); | 634 | u8 sta_info_tx_streams(struct sta_info *sta); |
diff --git a/net/wireless/core.c b/net/wireless/core.c index a1c40654dd9b..afee5e0455ea 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
@@ -25,7 +25,6 @@ | |||
25 | #include "sysfs.h" | 25 | #include "sysfs.h" |
26 | #include "debugfs.h" | 26 | #include "debugfs.h" |
27 | #include "wext-compat.h" | 27 | #include "wext-compat.h" |
28 | #include "ethtool.h" | ||
29 | #include "rdev-ops.h" | 28 | #include "rdev-ops.h" |
30 | 29 | ||
31 | /* name for sysfs, %d is appended */ | 30 | /* name for sysfs, %d is appended */ |
@@ -927,8 +926,6 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb, | |||
927 | /* allow mac80211 to determine the timeout */ | 926 | /* allow mac80211 to determine the timeout */ |
928 | wdev->ps_timeout = -1; | 927 | wdev->ps_timeout = -1; |
929 | 928 | ||
930 | netdev_set_default_ethtool_ops(dev, &cfg80211_ethtool_ops); | ||
931 | |||
932 | if ((wdev->iftype == NL80211_IFTYPE_STATION || | 929 | if ((wdev->iftype == NL80211_IFTYPE_STATION || |
933 | wdev->iftype == NL80211_IFTYPE_P2P_CLIENT || | 930 | wdev->iftype == NL80211_IFTYPE_P2P_CLIENT || |
934 | wdev->iftype == NL80211_IFTYPE_ADHOC) && !wdev->use_4addr) | 931 | wdev->iftype == NL80211_IFTYPE_ADHOC) && !wdev->use_4addr) |
diff --git a/net/wireless/ethtool.c b/net/wireless/ethtool.c index d4860bfc020e..e9e91298c70d 100644 --- a/net/wireless/ethtool.c +++ b/net/wireless/ethtool.c | |||
@@ -1,11 +1,9 @@ | |||
1 | #include <linux/utsname.h> | 1 | #include <linux/utsname.h> |
2 | #include <net/cfg80211.h> | 2 | #include <net/cfg80211.h> |
3 | #include "core.h" | 3 | #include "core.h" |
4 | #include "ethtool.h" | ||
5 | #include "rdev-ops.h" | 4 | #include "rdev-ops.h" |
6 | 5 | ||
7 | static void cfg80211_get_drvinfo(struct net_device *dev, | 6 | void cfg80211_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) |
8 | struct ethtool_drvinfo *info) | ||
9 | { | 7 | { |
10 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 8 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
11 | 9 | ||
@@ -23,84 +21,4 @@ static void cfg80211_get_drvinfo(struct net_device *dev, | |||
23 | strlcpy(info->bus_info, dev_name(wiphy_dev(wdev->wiphy)), | 21 | strlcpy(info->bus_info, dev_name(wiphy_dev(wdev->wiphy)), |
24 | sizeof(info->bus_info)); | 22 | sizeof(info->bus_info)); |
25 | } | 23 | } |
26 | 24 | EXPORT_SYMBOL(cfg80211_get_drvinfo); | |
27 | static int cfg80211_get_regs_len(struct net_device *dev) | ||
28 | { | ||
29 | /* For now, return 0... */ | ||
30 | return 0; | ||
31 | } | ||
32 | |||
33 | static void cfg80211_get_regs(struct net_device *dev, struct ethtool_regs *regs, | ||
34 | void *data) | ||
35 | { | ||
36 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
37 | |||
38 | regs->version = wdev->wiphy->hw_version; | ||
39 | regs->len = 0; | ||
40 | } | ||
41 | |||
42 | static void cfg80211_get_ringparam(struct net_device *dev, | ||
43 | struct ethtool_ringparam *rp) | ||
44 | { | ||
45 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
46 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); | ||
47 | |||
48 | memset(rp, 0, sizeof(*rp)); | ||
49 | |||
50 | if (rdev->ops->get_ringparam) | ||
51 | rdev_get_ringparam(rdev, &rp->tx_pending, &rp->tx_max_pending, | ||
52 | &rp->rx_pending, &rp->rx_max_pending); | ||
53 | } | ||
54 | |||
55 | static int cfg80211_set_ringparam(struct net_device *dev, | ||
56 | struct ethtool_ringparam *rp) | ||
57 | { | ||
58 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
59 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); | ||
60 | |||
61 | if (rp->rx_mini_pending != 0 || rp->rx_jumbo_pending != 0) | ||
62 | return -EINVAL; | ||
63 | |||
64 | if (rdev->ops->set_ringparam) | ||
65 | return rdev_set_ringparam(rdev, rp->tx_pending, rp->rx_pending); | ||
66 | |||
67 | return -ENOTSUPP; | ||
68 | } | ||
69 | |||
70 | static int cfg80211_get_sset_count(struct net_device *dev, int sset) | ||
71 | { | ||
72 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
73 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); | ||
74 | if (rdev->ops->get_et_sset_count) | ||
75 | return rdev_get_et_sset_count(rdev, dev, sset); | ||
76 | return -EOPNOTSUPP; | ||
77 | } | ||
78 | |||
79 | static void cfg80211_get_stats(struct net_device *dev, | ||
80 | struct ethtool_stats *stats, u64 *data) | ||
81 | { | ||
82 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
83 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); | ||
84 | if (rdev->ops->get_et_stats) | ||
85 | rdev_get_et_stats(rdev, dev, stats, data); | ||
86 | } | ||
87 | |||
88 | static void cfg80211_get_strings(struct net_device *dev, u32 sset, u8 *data) | ||
89 | { | ||
90 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
91 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); | ||
92 | if (rdev->ops->get_et_strings) | ||
93 | rdev_get_et_strings(rdev, dev, sset, data); | ||
94 | } | ||
95 | |||
96 | const struct ethtool_ops cfg80211_ethtool_ops = { | ||
97 | .get_drvinfo = cfg80211_get_drvinfo, | ||
98 | .get_regs_len = cfg80211_get_regs_len, | ||
99 | .get_regs = cfg80211_get_regs, | ||
100 | .get_link = ethtool_op_get_link, | ||
101 | .get_ringparam = cfg80211_get_ringparam, | ||
102 | .set_ringparam = cfg80211_set_ringparam, | ||
103 | .get_strings = cfg80211_get_strings, | ||
104 | .get_ethtool_stats = cfg80211_get_stats, | ||
105 | .get_sset_count = cfg80211_get_sset_count, | ||
106 | }; | ||
diff --git a/net/wireless/ethtool.h b/net/wireless/ethtool.h deleted file mode 100644 index 695ecad20bd6..000000000000 --- a/net/wireless/ethtool.h +++ /dev/null | |||
@@ -1,6 +0,0 @@ | |||
1 | #ifndef __CFG80211_ETHTOOL__ | ||
2 | #define __CFG80211_ETHTOOL__ | ||
3 | |||
4 | extern const struct ethtool_ops cfg80211_ethtool_ops; | ||
5 | |||
6 | #endif /* __CFG80211_ETHTOOL__ */ | ||
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h index d95bbe348138..f552b0abbd70 100644 --- a/net/wireless/rdev-ops.h +++ b/net/wireless/rdev-ops.h | |||
@@ -714,25 +714,6 @@ static inline int rdev_get_antenna(struct cfg80211_registered_device *rdev, | |||
714 | return ret; | 714 | return ret; |
715 | } | 715 | } |
716 | 716 | ||
717 | static inline int rdev_set_ringparam(struct cfg80211_registered_device *rdev, | ||
718 | u32 tx, u32 rx) | ||
719 | { | ||
720 | int ret; | ||
721 | trace_rdev_set_ringparam(&rdev->wiphy, tx, rx); | ||
722 | ret = rdev->ops->set_ringparam(&rdev->wiphy, tx, rx); | ||
723 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
724 | return ret; | ||
725 | } | ||
726 | |||
727 | static inline void rdev_get_ringparam(struct cfg80211_registered_device *rdev, | ||
728 | u32 *tx, u32 *tx_max, u32 *rx, | ||
729 | u32 *rx_max) | ||
730 | { | ||
731 | trace_rdev_get_ringparam(&rdev->wiphy); | ||
732 | rdev->ops->get_ringparam(&rdev->wiphy, tx, tx_max, rx, rx_max); | ||
733 | trace_rdev_return_void_tx_rx(&rdev->wiphy, *tx, *tx_max, *rx, *rx_max); | ||
734 | } | ||
735 | |||
736 | static inline int | 717 | static inline int |
737 | rdev_sched_scan_start(struct cfg80211_registered_device *rdev, | 718 | rdev_sched_scan_start(struct cfg80211_registered_device *rdev, |
738 | struct net_device *dev, | 719 | struct net_device *dev, |
@@ -816,35 +797,6 @@ static inline int rdev_set_noack_map(struct cfg80211_registered_device *rdev, | |||
816 | } | 797 | } |
817 | 798 | ||
818 | static inline int | 799 | static inline int |
819 | rdev_get_et_sset_count(struct cfg80211_registered_device *rdev, | ||
820 | struct net_device *dev, int sset) | ||
821 | { | ||
822 | int ret; | ||
823 | trace_rdev_get_et_sset_count(&rdev->wiphy, dev, sset); | ||
824 | ret = rdev->ops->get_et_sset_count(&rdev->wiphy, dev, sset); | ||
825 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
826 | return ret; | ||
827 | } | ||
828 | |||
829 | static inline void rdev_get_et_stats(struct cfg80211_registered_device *rdev, | ||
830 | struct net_device *dev, | ||
831 | struct ethtool_stats *stats, u64 *data) | ||
832 | { | ||
833 | trace_rdev_get_et_stats(&rdev->wiphy, dev); | ||
834 | rdev->ops->get_et_stats(&rdev->wiphy, dev, stats, data); | ||
835 | trace_rdev_return_void(&rdev->wiphy); | ||
836 | } | ||
837 | |||
838 | static inline void rdev_get_et_strings(struct cfg80211_registered_device *rdev, | ||
839 | struct net_device *dev, u32 sset, | ||
840 | u8 *data) | ||
841 | { | ||
842 | trace_rdev_get_et_strings(&rdev->wiphy, dev, sset); | ||
843 | rdev->ops->get_et_strings(&rdev->wiphy, dev, sset, data); | ||
844 | trace_rdev_return_void(&rdev->wiphy); | ||
845 | } | ||
846 | |||
847 | static inline int | ||
848 | rdev_get_channel(struct cfg80211_registered_device *rdev, | 800 | rdev_get_channel(struct cfg80211_registered_device *rdev, |
849 | struct wireless_dev *wdev, | 801 | struct wireless_dev *wdev, |
850 | struct cfg80211_chan_def *chandef) | 802 | struct cfg80211_chan_def *chandef) |
diff --git a/net/wireless/trace.h b/net/wireless/trace.h index 560ed77084e9..174559aade57 100644 --- a/net/wireless/trace.h +++ b/net/wireless/trace.h | |||
@@ -298,11 +298,6 @@ DEFINE_EVENT(wiphy_only_evt, rdev_return_void, | |||
298 | TP_ARGS(wiphy) | 298 | TP_ARGS(wiphy) |
299 | ); | 299 | ); |
300 | 300 | ||
301 | DEFINE_EVENT(wiphy_only_evt, rdev_get_ringparam, | ||
302 | TP_PROTO(struct wiphy *wiphy), | ||
303 | TP_ARGS(wiphy) | ||
304 | ); | ||
305 | |||
306 | DEFINE_EVENT(wiphy_only_evt, rdev_get_antenna, | 301 | DEFINE_EVENT(wiphy_only_evt, rdev_get_antenna, |
307 | TP_PROTO(struct wiphy *wiphy), | 302 | TP_PROTO(struct wiphy *wiphy), |
308 | TP_ARGS(wiphy) | 303 | TP_ARGS(wiphy) |
@@ -580,11 +575,6 @@ DEFINE_EVENT(wiphy_netdev_evt, rdev_stop_ap, | |||
580 | TP_ARGS(wiphy, netdev) | 575 | TP_ARGS(wiphy, netdev) |
581 | ); | 576 | ); |
582 | 577 | ||
583 | DEFINE_EVENT(wiphy_netdev_evt, rdev_get_et_stats, | ||
584 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev), | ||
585 | TP_ARGS(wiphy, netdev) | ||
586 | ); | ||
587 | |||
588 | DEFINE_EVENT(wiphy_netdev_evt, rdev_sched_scan_stop, | 578 | DEFINE_EVENT(wiphy_netdev_evt, rdev_sched_scan_stop, |
589 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev), | 579 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev), |
590 | TP_ARGS(wiphy, netdev) | 580 | TP_ARGS(wiphy, netdev) |
@@ -1439,11 +1429,6 @@ DECLARE_EVENT_CLASS(tx_rx_evt, | |||
1439 | WIPHY_PR_ARG, __entry->tx, __entry->rx) | 1429 | WIPHY_PR_ARG, __entry->tx, __entry->rx) |
1440 | ); | 1430 | ); |
1441 | 1431 | ||
1442 | DEFINE_EVENT(tx_rx_evt, rdev_set_ringparam, | ||
1443 | TP_PROTO(struct wiphy *wiphy, u32 tx, u32 rx), | ||
1444 | TP_ARGS(wiphy, rx, tx) | ||
1445 | ); | ||
1446 | |||
1447 | DEFINE_EVENT(tx_rx_evt, rdev_set_antenna, | 1432 | DEFINE_EVENT(tx_rx_evt, rdev_set_antenna, |
1448 | TP_PROTO(struct wiphy *wiphy, u32 tx, u32 rx), | 1433 | TP_PROTO(struct wiphy *wiphy, u32 tx, u32 rx), |
1449 | TP_ARGS(wiphy, rx, tx) | 1434 | TP_ARGS(wiphy, rx, tx) |
@@ -1725,40 +1710,6 @@ TRACE_EVENT(rdev_set_noack_map, | |||
1725 | WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->noack_map) | 1710 | WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->noack_map) |
1726 | ); | 1711 | ); |
1727 | 1712 | ||
1728 | TRACE_EVENT(rdev_get_et_sset_count, | ||
1729 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, int sset), | ||
1730 | TP_ARGS(wiphy, netdev, sset), | ||
1731 | TP_STRUCT__entry( | ||
1732 | WIPHY_ENTRY | ||
1733 | NETDEV_ENTRY | ||
1734 | __field(int, sset) | ||
1735 | ), | ||
1736 | TP_fast_assign( | ||
1737 | WIPHY_ASSIGN; | ||
1738 | NETDEV_ASSIGN; | ||
1739 | __entry->sset = sset; | ||
1740 | ), | ||
1741 | TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", sset: %d", | ||
1742 | WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->sset) | ||
1743 | ); | ||
1744 | |||
1745 | TRACE_EVENT(rdev_get_et_strings, | ||
1746 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, u32 sset), | ||
1747 | TP_ARGS(wiphy, netdev, sset), | ||
1748 | TP_STRUCT__entry( | ||
1749 | WIPHY_ENTRY | ||
1750 | NETDEV_ENTRY | ||
1751 | __field(u32, sset) | ||
1752 | ), | ||
1753 | TP_fast_assign( | ||
1754 | WIPHY_ASSIGN; | ||
1755 | NETDEV_ASSIGN; | ||
1756 | __entry->sset = sset; | ||
1757 | ), | ||
1758 | TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", sset: %u", | ||
1759 | WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->sset) | ||
1760 | ); | ||
1761 | |||
1762 | DEFINE_EVENT(wiphy_wdev_evt, rdev_get_channel, | 1713 | DEFINE_EVENT(wiphy_wdev_evt, rdev_get_channel, |
1763 | TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev), | 1714 | TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev), |
1764 | TP_ARGS(wiphy, wdev) | 1715 | TP_ARGS(wiphy, wdev) |