Hello Shayne Chen, Commit a0facfc80ec1 ("wifi: mt76: connac: rework connac helpers") from Jan 2, 2025 (linux-next), leads to the following Smatch static checker warning: drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c:588 mt76_connac2_mac_write_txwi() error: we previously assumed 'vif' could be null (see line 510) drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c 492 void mt76_connac2_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi, 493 struct sk_buff *skb, struct mt76_wcid *wcid, 494 struct ieee80211_key_conf *key, int pid, 495 enum mt76_txq_id qid, u32 changed) 496 { 497 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 498 u8 phy_idx = (info->hw_queue & MT_TX_HW_QUEUE_PHY) >> 2; 499 struct ieee80211_vif *vif = info->control.vif; 500 struct mt76_phy *mphy = &dev->phy; 501 u8 p_fmt, q_idx, omac_idx = 0, wmm_idx = 0, band_idx = 0; 502 u32 val, sz_txd = mt76_is_mmio(dev) ? MT_TXD_SIZE : MT_SDIO_TXD_SIZE; 503 bool is_8023 = info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP; 504 bool beacon = !!(changed & (BSS_CHANGED_BEACON | 505 BSS_CHANGED_BEACON_ENABLED)); 506 bool inband_disc = !!(changed & (BSS_CHANGED_UNSOL_BCAST_PROBE_RESP | 507 BSS_CHANGED_FILS_DISCOVERY)); 508 bool amsdu_en = wcid->amsdu; 509 510 if (vif) { ^^^ This code assumes the "vif" can be NULL. 511 struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv; 512 513 omac_idx = mvif->omac_idx; 514 wmm_idx = mvif->wmm_idx; 515 band_idx = mvif->band_idx; 516 } 517 518 if (phy_idx && dev->phys[MT_BAND1]) 519 mphy = dev->phys[MT_BAND1]; 520 521 if (inband_disc) { 522 p_fmt = MT_TX_TYPE_FW; 523 q_idx = MT_LMAC_ALTX0; 524 } else if (beacon) { 525 p_fmt = MT_TX_TYPE_FW; 526 q_idx = MT_LMAC_BCN0; 527 } else if (qid >= MT_TXQ_PSD) { 528 p_fmt = mt76_is_mmio(dev) ? MT_TX_TYPE_CT : MT_TX_TYPE_SF; 529 q_idx = MT_LMAC_ALTX0; 530 } else { 531 p_fmt = mt76_is_mmio(dev) ? MT_TX_TYPE_CT : MT_TX_TYPE_SF; 532 q_idx = wmm_idx * MT76_CONNAC_MAX_WMM_SETS + 533 mt76_connac_lmac_mapping(skb_get_queue_mapping(skb)); 534 535 /* mt7915 WA only counts WED path */ 536 if (is_mt7915(dev) && mtk_wed_device_active(&dev->mmio.wed)) 537 wcid->stats.tx_packets++; 538 } 539 540 val = FIELD_PREP(MT_TXD0_TX_BYTES, skb->len + sz_txd) | 541 FIELD_PREP(MT_TXD0_PKT_FMT, p_fmt) | 542 FIELD_PREP(MT_TXD0_Q_IDX, q_idx); 543 txwi[0] = cpu_to_le32(val); 544 545 val = MT_TXD1_LONG_FORMAT | 546 FIELD_PREP(MT_TXD1_WLAN_IDX, wcid->idx) | 547 FIELD_PREP(MT_TXD1_OWN_MAC, omac_idx); 548 if (!is_mt7921(dev)) 549 val |= MT_TXD1_VTA; 550 if (phy_idx || band_idx) 551 val |= MT_TXD1_TGID; 552 553 txwi[1] = cpu_to_le32(val); 554 txwi[2] = 0; 555 556 val = FIELD_PREP(MT_TXD3_REM_TX_COUNT, 15); 557 if (!is_mt7921(dev)) 558 val |= MT_TXD3_SW_POWER_MGMT; 559 if (key) 560 val |= MT_TXD3_PROTECT_FRAME; 561 if (info->flags & IEEE80211_TX_CTL_NO_ACK) 562 val |= MT_TXD3_NO_ACK; 563 564 txwi[3] = cpu_to_le32(val); 565 txwi[4] = 0; 566 567 val = FIELD_PREP(MT_TXD5_PID, pid); 568 if (pid >= MT_PACKET_ID_FIRST) { 569 val |= MT_TXD5_TX_STATUS_HOST; 570 amsdu_en = 0; 571 } 572 573 txwi[5] = cpu_to_le32(val); 574 txwi[6] = 0; 575 txwi[7] = amsdu_en ? cpu_to_le32(MT_TXD7_HW_AMSDU) : 0; 576 577 if (is_8023) 578 mt76_connac2_mac_write_txwi_8023(txwi, skb, wcid); 579 else 580 mt76_connac2_mac_write_txwi_80211(dev, txwi, skb, key); 581 582 if (txwi[2] & cpu_to_le32(MT_TXD2_FIX_RATE)) { 583 /* Fixed rata is available just for 802.11 txd */ 584 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 585 bool multicast = ieee80211_is_data(hdr->frame_control) && 586 is_multicast_ether_addr(hdr->addr1); 587 u16 rate = mt76_connac2_mac_tx_rate_val(mphy, &vif->bss_conf, beacon, ^^^^^^^^^^^^^^ This code dereferences vif without checking. Technically the mt76_connac2_mac_tx_rate_val() has a NULL check but it doesn't work because the address of &vif->bss_conf can't be NULL since it's in the middle of the struct. 588 multicast); 589 u32 val = MT_TXD6_FIXED_BW; 590 591 /* hardware won't add HTC for mgmt/ctrl frame */ 592 txwi[2] |= cpu_to_le32(MT_TXD2_HTC_VLD); 593 594 val |= FIELD_PREP(MT_TXD6_TX_RATE, rate); 595 txwi[6] |= cpu_to_le32(val); 596 txwi[3] |= cpu_to_le32(MT_TXD3_BA_DISABLE); 597 598 if (!is_mt7921(dev)) { 599 u8 spe_idx = mt76_connac_spe_idx(mphy->antenna_mask); 600 601 if (!spe_idx) 602 spe_idx = 24 + phy_idx; 603 txwi[7] |= cpu_to_le32(FIELD_PREP(MT_TXD7_SPE_IDX, spe_idx)); 604 } 605 606 txwi[7] &= ~cpu_to_le32(MT_TXD7_HW_AMSDU); 607 } 608 } regards, dan carpenter