mirror of https://gitee.com/openkylin/linux.git
iwlwifi: mvm: remove TCP wakeup support
This feature was actually removed from firmware, but without ever telling the driver. Since nobody is actually using it, just remove it entirely without bothering with a capability check. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
This commit is contained in:
parent
357969c6b5
commit
debdc23b17
|
@ -429,231 +429,6 @@ static int iwl_mvm_send_patterns(struct iwl_mvm *mvm,
|
|||
return err;
|
||||
}
|
||||
|
||||
enum iwl_mvm_tcp_packet_type {
|
||||
MVM_TCP_TX_SYN,
|
||||
MVM_TCP_RX_SYNACK,
|
||||
MVM_TCP_TX_DATA,
|
||||
MVM_TCP_RX_ACK,
|
||||
MVM_TCP_RX_WAKE,
|
||||
MVM_TCP_TX_FIN,
|
||||
};
|
||||
|
||||
static __le16 pseudo_hdr_check(int len, __be32 saddr, __be32 daddr)
|
||||
{
|
||||
__sum16 check = tcp_v4_check(len, saddr, daddr, 0);
|
||||
return cpu_to_le16(be16_to_cpu((__force __be16)check));
|
||||
}
|
||||
|
||||
static void iwl_mvm_build_tcp_packet(struct ieee80211_vif *vif,
|
||||
struct cfg80211_wowlan_tcp *tcp,
|
||||
void *_pkt, u8 *mask,
|
||||
__le16 *pseudo_hdr_csum,
|
||||
enum iwl_mvm_tcp_packet_type ptype)
|
||||
{
|
||||
struct {
|
||||
struct ethhdr eth;
|
||||
struct iphdr ip;
|
||||
struct tcphdr tcp;
|
||||
u8 data[];
|
||||
} __packed *pkt = _pkt;
|
||||
u16 ip_tot_len = sizeof(struct iphdr) + sizeof(struct tcphdr);
|
||||
int i;
|
||||
|
||||
pkt->eth.h_proto = cpu_to_be16(ETH_P_IP),
|
||||
pkt->ip.version = 4;
|
||||
pkt->ip.ihl = 5;
|
||||
pkt->ip.protocol = IPPROTO_TCP;
|
||||
|
||||
switch (ptype) {
|
||||
case MVM_TCP_TX_SYN:
|
||||
case MVM_TCP_TX_DATA:
|
||||
case MVM_TCP_TX_FIN:
|
||||
memcpy(pkt->eth.h_dest, tcp->dst_mac, ETH_ALEN);
|
||||
memcpy(pkt->eth.h_source, vif->addr, ETH_ALEN);
|
||||
pkt->ip.ttl = 128;
|
||||
pkt->ip.saddr = tcp->src;
|
||||
pkt->ip.daddr = tcp->dst;
|
||||
pkt->tcp.source = cpu_to_be16(tcp->src_port);
|
||||
pkt->tcp.dest = cpu_to_be16(tcp->dst_port);
|
||||
/* overwritten for TX SYN later */
|
||||
pkt->tcp.doff = sizeof(struct tcphdr) / 4;
|
||||
pkt->tcp.window = cpu_to_be16(65000);
|
||||
break;
|
||||
case MVM_TCP_RX_SYNACK:
|
||||
case MVM_TCP_RX_ACK:
|
||||
case MVM_TCP_RX_WAKE:
|
||||
memcpy(pkt->eth.h_dest, vif->addr, ETH_ALEN);
|
||||
memcpy(pkt->eth.h_source, tcp->dst_mac, ETH_ALEN);
|
||||
pkt->ip.saddr = tcp->dst;
|
||||
pkt->ip.daddr = tcp->src;
|
||||
pkt->tcp.source = cpu_to_be16(tcp->dst_port);
|
||||
pkt->tcp.dest = cpu_to_be16(tcp->src_port);
|
||||
break;
|
||||
default:
|
||||
WARN_ON(1);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (ptype) {
|
||||
case MVM_TCP_TX_SYN:
|
||||
/* firmware assumes 8 option bytes - 8 NOPs for now */
|
||||
memset(pkt->data, 0x01, 8);
|
||||
ip_tot_len += 8;
|
||||
pkt->tcp.doff = (sizeof(struct tcphdr) + 8) / 4;
|
||||
pkt->tcp.syn = 1;
|
||||
break;
|
||||
case MVM_TCP_TX_DATA:
|
||||
ip_tot_len += tcp->payload_len;
|
||||
memcpy(pkt->data, tcp->payload, tcp->payload_len);
|
||||
pkt->tcp.psh = 1;
|
||||
pkt->tcp.ack = 1;
|
||||
break;
|
||||
case MVM_TCP_TX_FIN:
|
||||
pkt->tcp.fin = 1;
|
||||
pkt->tcp.ack = 1;
|
||||
break;
|
||||
case MVM_TCP_RX_SYNACK:
|
||||
pkt->tcp.syn = 1;
|
||||
pkt->tcp.ack = 1;
|
||||
break;
|
||||
case MVM_TCP_RX_ACK:
|
||||
pkt->tcp.ack = 1;
|
||||
break;
|
||||
case MVM_TCP_RX_WAKE:
|
||||
ip_tot_len += tcp->wake_len;
|
||||
pkt->tcp.psh = 1;
|
||||
pkt->tcp.ack = 1;
|
||||
memcpy(pkt->data, tcp->wake_data, tcp->wake_len);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (ptype) {
|
||||
case MVM_TCP_TX_SYN:
|
||||
case MVM_TCP_TX_DATA:
|
||||
case MVM_TCP_TX_FIN:
|
||||
pkt->ip.tot_len = cpu_to_be16(ip_tot_len);
|
||||
pkt->ip.check = ip_fast_csum(&pkt->ip, pkt->ip.ihl);
|
||||
break;
|
||||
case MVM_TCP_RX_WAKE:
|
||||
for (i = 0; i < DIV_ROUND_UP(tcp->wake_len, 8); i++) {
|
||||
u8 tmp = tcp->wake_mask[i];
|
||||
mask[i + 6] |= tmp << 6;
|
||||
if (i + 1 < DIV_ROUND_UP(tcp->wake_len, 8))
|
||||
mask[i + 7] = tmp >> 2;
|
||||
}
|
||||
/* fall through for ethernet/IP/TCP headers mask */
|
||||
case MVM_TCP_RX_SYNACK:
|
||||
case MVM_TCP_RX_ACK:
|
||||
mask[0] = 0xff; /* match ethernet */
|
||||
/*
|
||||
* match ethernet, ip.version, ip.ihl
|
||||
* the ip.ihl half byte is really masked out by firmware
|
||||
*/
|
||||
mask[1] = 0x7f;
|
||||
mask[2] = 0x80; /* match ip.protocol */
|
||||
mask[3] = 0xfc; /* match ip.saddr, ip.daddr */
|
||||
mask[4] = 0x3f; /* match ip.daddr, tcp.source, tcp.dest */
|
||||
mask[5] = 0x80; /* match tcp flags */
|
||||
/* leave rest (0 or set for MVM_TCP_RX_WAKE) */
|
||||
break;
|
||||
};
|
||||
|
||||
*pseudo_hdr_csum = pseudo_hdr_check(ip_tot_len - sizeof(struct iphdr),
|
||||
pkt->ip.saddr, pkt->ip.daddr);
|
||||
}
|
||||
|
||||
static int iwl_mvm_send_remote_wake_cfg(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif,
|
||||
struct cfg80211_wowlan_tcp *tcp)
|
||||
{
|
||||
struct iwl_wowlan_remote_wake_config *cfg;
|
||||
struct iwl_host_cmd cmd = {
|
||||
.id = REMOTE_WAKE_CONFIG_CMD,
|
||||
.len = { sizeof(*cfg), },
|
||||
.dataflags = { IWL_HCMD_DFL_NOCOPY, },
|
||||
};
|
||||
int ret;
|
||||
|
||||
if (!tcp)
|
||||
return 0;
|
||||
|
||||
cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
|
||||
if (!cfg)
|
||||
return -ENOMEM;
|
||||
cmd.data[0] = cfg;
|
||||
|
||||
cfg->max_syn_retries = 10;
|
||||
cfg->max_data_retries = 10;
|
||||
cfg->tcp_syn_ack_timeout = 1; /* seconds */
|
||||
cfg->tcp_ack_timeout = 1; /* seconds */
|
||||
|
||||
/* SYN (TX) */
|
||||
iwl_mvm_build_tcp_packet(
|
||||
vif, tcp, cfg->syn_tx.data, NULL,
|
||||
&cfg->syn_tx.info.tcp_pseudo_header_checksum,
|
||||
MVM_TCP_TX_SYN);
|
||||
cfg->syn_tx.info.tcp_payload_length = 0;
|
||||
|
||||
/* SYN/ACK (RX) */
|
||||
iwl_mvm_build_tcp_packet(
|
||||
vif, tcp, cfg->synack_rx.data, cfg->synack_rx.rx_mask,
|
||||
&cfg->synack_rx.info.tcp_pseudo_header_checksum,
|
||||
MVM_TCP_RX_SYNACK);
|
||||
cfg->synack_rx.info.tcp_payload_length = 0;
|
||||
|
||||
/* KEEPALIVE/ACK (TX) */
|
||||
iwl_mvm_build_tcp_packet(
|
||||
vif, tcp, cfg->keepalive_tx.data, NULL,
|
||||
&cfg->keepalive_tx.info.tcp_pseudo_header_checksum,
|
||||
MVM_TCP_TX_DATA);
|
||||
cfg->keepalive_tx.info.tcp_payload_length =
|
||||
cpu_to_le16(tcp->payload_len);
|
||||
cfg->sequence_number_offset = tcp->payload_seq.offset;
|
||||
/* length must be 0..4, the field is little endian */
|
||||
cfg->sequence_number_length = tcp->payload_seq.len;
|
||||
cfg->initial_sequence_number = cpu_to_le32(tcp->payload_seq.start);
|
||||
cfg->keepalive_interval = cpu_to_le16(tcp->data_interval);
|
||||
if (tcp->payload_tok.len) {
|
||||
cfg->token_offset = tcp->payload_tok.offset;
|
||||
cfg->token_length = tcp->payload_tok.len;
|
||||
cfg->num_tokens =
|
||||
cpu_to_le16(tcp->tokens_size % tcp->payload_tok.len);
|
||||
memcpy(cfg->tokens, tcp->payload_tok.token_stream,
|
||||
tcp->tokens_size);
|
||||
} else {
|
||||
/* set tokens to max value to almost never run out */
|
||||
cfg->num_tokens = cpu_to_le16(65535);
|
||||
}
|
||||
|
||||
/* ACK (RX) */
|
||||
iwl_mvm_build_tcp_packet(
|
||||
vif, tcp, cfg->keepalive_ack_rx.data,
|
||||
cfg->keepalive_ack_rx.rx_mask,
|
||||
&cfg->keepalive_ack_rx.info.tcp_pseudo_header_checksum,
|
||||
MVM_TCP_RX_ACK);
|
||||
cfg->keepalive_ack_rx.info.tcp_payload_length = 0;
|
||||
|
||||
/* WAKEUP (RX) */
|
||||
iwl_mvm_build_tcp_packet(
|
||||
vif, tcp, cfg->wake_rx.data, cfg->wake_rx.rx_mask,
|
||||
&cfg->wake_rx.info.tcp_pseudo_header_checksum,
|
||||
MVM_TCP_RX_WAKE);
|
||||
cfg->wake_rx.info.tcp_payload_length =
|
||||
cpu_to_le16(tcp->wake_len);
|
||||
|
||||
/* FIN */
|
||||
iwl_mvm_build_tcp_packet(
|
||||
vif, tcp, cfg->fin_tx.data, NULL,
|
||||
&cfg->fin_tx.info.tcp_pseudo_header_checksum,
|
||||
MVM_TCP_TX_FIN);
|
||||
cfg->fin_tx.info.tcp_payload_length = 0;
|
||||
|
||||
ret = iwl_mvm_send_cmd(mvm, &cmd);
|
||||
kfree(cfg);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int iwl_mvm_d3_reprogram(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *ap_sta)
|
||||
{
|
||||
|
@ -1082,12 +857,7 @@ iwl_mvm_wowlan_config(struct iwl_mvm *mvm,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = iwl_mvm_send_proto_offload(mvm, vif, false, true, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = iwl_mvm_send_remote_wake_cfg(mvm, vif, wowlan->tcp);
|
||||
return ret;
|
||||
return iwl_mvm_send_proto_offload(mvm, vif, false, true, 0);
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
|
@ -114,29 +114,6 @@ static const struct ieee80211_iface_combination iwl_mvm_iface_combinations[] = {
|
|||
},
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static const struct nl80211_wowlan_tcp_data_token_feature
|
||||
iwl_mvm_wowlan_tcp_token_feature = {
|
||||
.min_len = 0,
|
||||
.max_len = 255,
|
||||
.bufsize = IWL_WOWLAN_REMOTE_WAKE_MAX_TOKENS,
|
||||
};
|
||||
|
||||
static const struct wiphy_wowlan_tcp_support iwl_mvm_wowlan_tcp_support = {
|
||||
.tok = &iwl_mvm_wowlan_tcp_token_feature,
|
||||
.data_payload_max = IWL_WOWLAN_TCP_MAX_PACKET_LEN -
|
||||
sizeof(struct ethhdr) -
|
||||
sizeof(struct iphdr) -
|
||||
sizeof(struct tcphdr),
|
||||
.data_interval_max = 65535, /* __le16 in API */
|
||||
.wake_payload_max = IWL_WOWLAN_REMOTE_WAKE_MAX_PACKET_LEN -
|
||||
sizeof(struct ethhdr) -
|
||||
sizeof(struct iphdr) -
|
||||
sizeof(struct tcphdr),
|
||||
.seq = true,
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_BCAST_FILTERING
|
||||
/*
|
||||
* Use the reserved field to indicate magic values.
|
||||
|
@ -702,7 +679,6 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
|
|||
mvm->wowlan.pattern_min_len = IWL_WOWLAN_MIN_PATTERN_LEN;
|
||||
mvm->wowlan.pattern_max_len = IWL_WOWLAN_MAX_PATTERN_LEN;
|
||||
mvm->wowlan.max_nd_match_sets = IWL_SCAN_MAX_PROFILES;
|
||||
mvm->wowlan.tcp = &iwl_mvm_wowlan_tcp_support;
|
||||
hw->wiphy->wowlan = &mvm->wowlan;
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue