/* This is called if for some node with MAC address addr, we only get frames * over one of the slave interfaces. This would indicate an open network ring * (i.e. a link has failed somewhere). */ void hsr_nl_ringerror(struct hsr_priv *hsr, unsigned char addr[ETH_ALEN], struct hsr_port *port) { struct sk_buff *skb; void *msg_head; struct hsr_port *master; int res; skb = genlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC); if (!skb) goto fail; msg_head = genlmsg_put(skb, 0, 0, &hsr_genl_family, 0, HSR_C_RING_ERROR); if (!msg_head) goto nla_put_failure; res = nla_put(skb, HSR_A_NODE_ADDR, ETH_ALEN, addr); if (res < 0) goto nla_put_failure; res = nla_put_u32(skb, HSR_A_IFINDEX, port->dev->ifindex); if (res < 0) goto nla_put_failure; genlmsg_end(skb, msg_head); genlmsg_multicast(&hsr_genl_family, skb, 0, 0, GFP_ATOMIC); return; nla_put_failure: kfree_skb(skb); fail: rcu_read_lock(); master = hsr_port_get_hsr(hsr, HSR_PT_MASTER); netdev_warn(master->dev, "Could not send HSR ring error message\n"); rcu_read_unlock(); }
/* * Hard reset the card. This used to pause for the same period that a * 8390 reset command required, but that shouldn't be necessary. */ static void mcf8390_reset_8390(struct net_device *dev) { unsigned long reset_start_time = jiffies; u32 addr = dev->base_addr; struct ei_device *ei_local = netdev_priv(dev); netif_dbg(ei_local, hw, dev, "resetting the 8390 t=%ld...\n", jiffies); ei_outb(ei_inb(addr + NE_RESET), addr + NE_RESET); ei_status.txing = 0; ei_status.dmaing = 0; /* This check _should_not_ be necessary, omit eventually. */ while ((ei_inb(addr + NE_EN0_ISR) & ENISR_RESET) == 0) { if (time_after(jiffies, reset_start_time + 2 * HZ / 100)) { netdev_warn(dev, "%s: did not complete\n", __func__); break; } } ei_outb(ENISR_RESET, addr + NE_EN0_ISR); }
u8 HTGetHighestMCSRate(struct rtllib_device *ieee, u8 *pMCSRateSet, u8 *pMCSFilter) { u8 i, j; u8 bitMap; u8 mcsRate = 0; u8 availableMcsRate[16]; if (pMCSRateSet == NULL || pMCSFilter == NULL) { netdev_warn(ieee->dev, "%s(): pMCSRateSet and pMCSFilter are null\n", __func__); return false; } for (i = 0; i < 16; i++) availableMcsRate[i] = pMCSRateSet[i] & pMCSFilter[i]; for (i = 0; i < 16; i++) { if (availableMcsRate[i] != 0) break; } if (i == 16) return false; for (i = 0; i < 16; i++) { if (availableMcsRate[i] != 0) { bitMap = availableMcsRate[i]; for (j = 0; j < 8; j++) { if ((bitMap%2) != 0) { if (HTMcsToDataRate(ieee, (8*i+j)) > HTMcsToDataRate(ieee, mcsRate)) mcsRate = (8*i+j); } bitMap >>= 1; } } }
static void hip04_config_port(struct net_device *ndev, u32 speed, u32 duplex) { struct hip04_priv *priv = netdev_priv(ndev); u32 val; priv->speed = speed; priv->duplex = duplex; switch (priv->phy_mode) { case PHY_INTERFACE_MODE_SGMII: if (speed == SPEED_1000) val = SGMII_SPEED_1000; else if (speed == SPEED_100) val = SGMII_SPEED_100; else val = SGMII_SPEED_10; break; case PHY_INTERFACE_MODE_MII: if (speed == SPEED_100) val = MII_SPEED_100; else val = MII_SPEED_10; break; default: netdev_warn(ndev, "not supported mode\n"); val = MII_SPEED_10; break; } writel_relaxed(val, priv->base + GE_PORT_MODE); val = duplex ? GE_DUPLEX_FULL : GE_DUPLEX_HALF; writel_relaxed(val, priv->base + GE_DUPLEX_TYPE); val = GE_MODE_CHANGE_EN; writel_relaxed(val, priv->base + GE_MODE_CHANGE_REG); }
/* Grab the 8390 specific header. Similar to the block_input routine, but * we don't need to be concerned with ring wrap as the header will be at * the start of a page, so we optimize accordingly. */ static void zorro8390_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { int nic_base = dev->base_addr; int cnt; short *ptrs; /* This *shouldn't* happen. * If it does, it's the last thing you'll see */ if (ei_status.dmaing) { netdev_warn(dev, "%s: DMAing conflict [DMAstat:%d][irqlock:%d]\n", __func__, ei_status.dmaing, ei_status.irqlock); return; } ei_status.dmaing |= 0x01; z_writeb(E8390_NODMA + E8390_PAGE0 + E8390_START, nic_base + NE_CMD); z_writeb(ENISR_RDC, nic_base + NE_EN0_ISR); z_writeb(sizeof(struct e8390_pkt_hdr), nic_base + NE_EN0_RCNTLO); z_writeb(0, nic_base + NE_EN0_RCNTHI); z_writeb(0, nic_base + NE_EN0_RSARLO); /* On page boundary */ z_writeb(ring_page, nic_base + NE_EN0_RSARHI); z_writeb(E8390_RREAD+E8390_START, nic_base + NE_CMD); ptrs = (short *)hdr; for (cnt = 0; cnt < sizeof(struct e8390_pkt_hdr) >> 1; cnt++) *ptrs++ = z_readw(NE_BASE + NE_DATAPORT); z_writeb(ENISR_RDC, nic_base + NE_EN0_ISR); /* Ack intr */ hdr->count = WORDSWAP(hdr->count); ei_status.dmaing &= ~0x01; }
static struct adapter *rtw_usb_if1_init(struct dvobj_priv *dvobj, struct usb_interface *pusb_intf, const struct usb_device_id *pdid) { struct adapter *padapter = NULL; struct net_device *pnetdev = NULL; struct net_device *pmondev; int status = _FAIL; padapter = vzalloc(sizeof(*padapter)); if (!padapter) goto exit; padapter->dvobj = dvobj; dvobj->if1 = padapter; padapter->bDriverStopped = true; mutex_init(&padapter->hw_init_mutex); pnetdev = rtw_init_netdev(padapter); if (!pnetdev) goto free_adapter; SET_NETDEV_DEV(pnetdev, dvobj_to_dev(dvobj)); padapter = rtw_netdev_priv(pnetdev); if (padapter->registrypriv.monitor_enable) { pmondev = rtl88eu_mon_init(); if (!pmondev) netdev_warn(pnetdev, "Failed to initialize monitor interface"); padapter->pmondev = pmondev; } padapter->HalData = kzalloc(sizeof(struct hal_data_8188e), GFP_KERNEL); if (!padapter->HalData) DBG_88E("cant not alloc memory for HAL DATA\n"); /* step read_chip_version */ rtw_hal_read_chip_version(padapter); /* step usb endpoint mapping */ rtw_hal_chip_configure(padapter); /* step read efuse/eeprom data and get mac_addr */ rtw_hal_read_chip_info(padapter); /* step 5. */ if (rtw_init_drv_sw(padapter) == _FAIL) { RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("Initialize driver software resource Failed!\n")); goto free_hal_data; } #ifdef CONFIG_PM if (padapter->pwrctrlpriv.bSupportRemoteWakeup) { dvobj->pusbdev->do_remote_wakeup = 1; pusb_intf->needs_remote_wakeup = 1; device_init_wakeup(&pusb_intf->dev, 1); pr_debug("\n padapter->pwrctrlpriv.bSupportRemoteWakeup~~~~~~\n"); pr_debug("\n padapter->pwrctrlpriv.bSupportRemoteWakeup~~~[%d]~~~\n", device_may_wakeup(&pusb_intf->dev)); } #endif /* 2012-07-11 Move here to prevent the 8723AS-VAU BT auto * suspend influence */ if (usb_autopm_get_interface(pusb_intf) < 0) pr_debug("can't get autopm:\n"); /* alloc dev name after read efuse. */ rtw_init_netdev_name(pnetdev, padapter->registrypriv.ifname); rtw_macaddr_cfg(padapter->eeprompriv.mac_addr); memcpy(pnetdev->dev_addr, padapter->eeprompriv.mac_addr, ETH_ALEN); pr_debug("MAC Address from pnetdev->dev_addr = %pM\n", pnetdev->dev_addr); /* step 6. Tell the network stack we exist */ if (register_netdev(pnetdev) != 0) { RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("register_netdev() failed\n")); goto free_hal_data; } pr_debug("bDriverStopped:%d, bSurpriseRemoved:%d, bup:%d, hw_init_completed:%d\n" , padapter->bDriverStopped , padapter->bSurpriseRemoved , padapter->bup , padapter->hw_init_completed ); status = _SUCCESS; free_hal_data: if (status != _SUCCESS) kfree(padapter->HalData); free_adapter: if (status != _SUCCESS) { if (pnetdev) rtw_free_netdev(pnetdev); else vfree(padapter); padapter = NULL; } exit: return padapter; }
static int vlan_dev_init(struct net_device *dev) { struct net_device *real_dev = vlan_dev_priv(dev)->real_dev; netif_carrier_off(dev); /* IFF_BROADCAST|IFF_MULTICAST; ??? */ dev->flags = real_dev->flags & ~(IFF_UP | IFF_PROMISC | IFF_ALLMULTI | IFF_MASTER | IFF_SLAVE); dev->state = (real_dev->state & ((1<<__LINK_STATE_NOCARRIER) | (1<<__LINK_STATE_DORMANT))) | (1<<__LINK_STATE_PRESENT); dev->hw_features = NETIF_F_HW_CSUM | NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_GSO_SOFTWARE | NETIF_F_HIGHDMA | NETIF_F_SCTP_CRC | NETIF_F_ALL_FCOE; dev->features |= dev->hw_features | NETIF_F_LLTX; dev->gso_max_size = real_dev->gso_max_size; dev->gso_max_segs = real_dev->gso_max_segs; if (dev->features & NETIF_F_VLAN_FEATURES) netdev_warn(real_dev, "VLAN features are set incorrectly. Q-in-Q configurations may not work correctly.\n"); dev->vlan_features = real_dev->vlan_features & ~NETIF_F_ALL_FCOE; /* ipv6 shared card related stuff */ dev->dev_id = real_dev->dev_id; if (is_zero_ether_addr(dev->dev_addr)) { ether_addr_copy(dev->dev_addr, real_dev->dev_addr); dev->addr_assign_type = NET_ADDR_STOLEN; } if (is_zero_ether_addr(dev->broadcast)) memcpy(dev->broadcast, real_dev->broadcast, dev->addr_len); #if IS_ENABLED(CONFIG_FCOE) dev->fcoe_ddp_xid = real_dev->fcoe_ddp_xid; #endif dev->needed_headroom = real_dev->needed_headroom; if (vlan_hw_offload_capable(real_dev->features, vlan_dev_priv(dev)->vlan_proto)) { dev->header_ops = &vlan_passthru_header_ops; dev->hard_header_len = real_dev->hard_header_len; } else { dev->header_ops = &vlan_header_ops; dev->hard_header_len = real_dev->hard_header_len + VLAN_HLEN; } dev->netdev_ops = &vlan_netdev_ops; SET_NETDEV_DEVTYPE(dev, &vlan_type); vlan_dev_set_lockdep_class(dev, vlan_dev_get_lock_subclass(dev)); vlan_dev_priv(dev)->vlan_pcpu_stats = netdev_alloc_pcpu_stats(struct vlan_pcpu_stats); if (!vlan_dev_priv(dev)->vlan_pcpu_stats) return -ENOMEM; return 0; }
static int prism2_connect(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_connect_params *sme) { struct wlandevice *wlandev = dev->ml_priv; struct ieee80211_channel *channel = sme->channel; struct p80211msg_lnxreq_autojoin msg_join; u32 did; int length = sme->ssid_len; int chan = -1; int is_wep = (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40) || (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104); int result; int err = 0; /* Set the channel */ if (channel) { chan = ieee80211_frequency_to_channel(channel->center_freq); result = prism2_domibset_uint32(wlandev, DIDMIB_DOT11PHY_DSSSTABLE_CURRENTCHANNEL, chan); if (result) goto exit; } /* Set the authorization */ if ((sme->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) || ((sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC) && !is_wep)) msg_join.authtype.data = P80211ENUM_authalg_opensystem; else if ((sme->auth_type == NL80211_AUTHTYPE_SHARED_KEY) || ((sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC) && is_wep)) msg_join.authtype.data = P80211ENUM_authalg_sharedkey; else netdev_warn(dev, "Unhandled authorisation type for connect (%d)\n", sme->auth_type); /* Set the encryption - we only support wep */ if (is_wep) { if (sme->key) { if (sme->key_idx >= NUM_WEPKEYS) { err = -EINVAL; goto exit; } result = prism2_domibset_uint32(wlandev, DIDMIB_DOT11SMT_PRIVACYTABLE_WEPDEFAULTKEYID, sme->key_idx); if (result) goto exit; /* send key to driver */ did = didmib_dot11smt_wepdefaultkeystable_key( sme->key_idx + 1); result = prism2_domibset_pstr32(wlandev, did, sme->key_len, (u8 *)sme->key); if (result) goto exit; } /* Assume we should set privacy invoked and exclude unencrypted * We could possible use sme->privacy here, but the assumption * seems reasonable anyways */ result = prism2_domibset_uint32(wlandev, DIDMIB_DOT11SMT_PRIVACYTABLE_PRIVACYINVOKED, P80211ENUM_truth_true); if (result) goto exit; result = prism2_domibset_uint32(wlandev, DIDMIB_DOT11SMT_PRIVACYTABLE_EXCLUDEUNENCRYPTED, P80211ENUM_truth_true); if (result) goto exit; } else { /* Assume we should unset privacy invoked * and exclude unencrypted */ result = prism2_domibset_uint32(wlandev, DIDMIB_DOT11SMT_PRIVACYTABLE_PRIVACYINVOKED, P80211ENUM_truth_false); if (result) goto exit; result = prism2_domibset_uint32(wlandev, DIDMIB_DOT11SMT_PRIVACYTABLE_EXCLUDEUNENCRYPTED, P80211ENUM_truth_false); if (result) goto exit; } /* Now do the actual join. Note there is no way that I can * see to request a specific bssid */ msg_join.msgcode = DIDMSG_LNXREQ_AUTOJOIN; memcpy(msg_join.ssid.data.data, sme->ssid, length); msg_join.ssid.data.len = length; result = p80211req_dorequest(wlandev, (u8 *)&msg_join); exit: if (result) err = -EFAULT; return err; }
/*---------------------------------------------------------------- * prism2mgmt_scan * * Initiate a scan for BSSs. * * This function corresponds to MLME-scan.request and part of * MLME-scan.confirm. As far as I can tell in the standard, there * are no restrictions on when a scan.request may be issued. We have * to handle in whatever state the driver/MAC happen to be. * * Arguments: * wlandev wlan device structure * msgp ptr to msg buffer * * Returns: * 0 success and done * <0 success, but we're waiting for something to finish. * >0 an error occurred while handling the message. * Side effects: * * Call context: * process thread (usually) * interrupt *---------------------------------------------------------------- */ int prism2mgmt_scan(struct wlandevice *wlandev, void *msgp) { int result = 0; struct hfa384x *hw = wlandev->priv; struct p80211msg_dot11req_scan *msg = msgp; u16 roamingmode, word; int i, timeout; int istmpenable = 0; struct hfa384x_host_scan_request_data scanreq; /* gatekeeper check */ if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major, hw->ident_sta_fw.minor, hw->ident_sta_fw.variant) < HFA384x_FIRMWARE_VERSION(1, 3, 2)) { netdev_err(wlandev->netdev, "HostScan not supported with current firmware (<1.3.2).\n"); result = 1; msg->resultcode.data = P80211ENUM_resultcode_not_supported; goto exit; } memset(&scanreq, 0, sizeof(scanreq)); /* save current roaming mode */ result = hfa384x_drvr_getconfig16(hw, HFA384x_RID_CNFROAMINGMODE, &roamingmode); if (result) { netdev_err(wlandev->netdev, "getconfig(ROAMMODE) failed. result=%d\n", result); msg->resultcode.data = P80211ENUM_resultcode_implementation_failure; goto exit; } /* drop into mode 3 for the scan */ result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFROAMINGMODE, HFA384x_ROAMMODE_HOSTSCAN_HOSTROAM); if (result) { netdev_err(wlandev->netdev, "setconfig(ROAMINGMODE) failed. result=%d\n", result); msg->resultcode.data = P80211ENUM_resultcode_implementation_failure; goto exit; } /* active or passive? */ if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major, hw->ident_sta_fw.minor, hw->ident_sta_fw.variant) > HFA384x_FIRMWARE_VERSION(1, 5, 0)) { if (msg->scantype.data != P80211ENUM_scantype_active) word = msg->maxchanneltime.data; else word = 0; result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFPASSIVESCANCTRL, word); if (result) { netdev_warn(wlandev->netdev, "Passive scan not supported with current firmware. (<1.5.1)\n"); } } /* set up the txrate to be 2MBPS. Should be fastest basicrate... */ word = HFA384x_RATEBIT_2; scanreq.tx_rate = cpu_to_le16(word); /* set up the channel list */ word = 0; for (i = 0; i < msg->channellist.data.len; i++) { u8 channel = msg->channellist.data.data[i]; if (channel > 14) continue; /* channel 1 is BIT 0 ... channel 14 is BIT 13 */ word |= (1 << (channel - 1)); } scanreq.channel_list = cpu_to_le16(word); /* set up the ssid, if present. */ scanreq.ssid.len = cpu_to_le16(msg->ssid.data.len); memcpy(scanreq.ssid.data, msg->ssid.data.data, msg->ssid.data.len); /* Enable the MAC port if it's not already enabled */ result = hfa384x_drvr_getconfig16(hw, HFA384x_RID_PORTSTATUS, &word); if (result) { netdev_err(wlandev->netdev, "getconfig(PORTSTATUS) failed. result=%d\n", result); msg->resultcode.data = P80211ENUM_resultcode_implementation_failure; goto exit; } if (word == HFA384x_PORTSTATUS_DISABLED) { __le16 wordbuf[17]; result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFROAMINGMODE, HFA384x_ROAMMODE_HOSTSCAN_HOSTROAM); if (result) { netdev_err(wlandev->netdev, "setconfig(ROAMINGMODE) failed. result=%d\n", result); msg->resultcode.data = P80211ENUM_resultcode_implementation_failure; goto exit; } /* Construct a bogus SSID and assign it to OwnSSID and * DesiredSSID */ wordbuf[0] = cpu_to_le16(WLAN_SSID_MAXLEN); get_random_bytes(&wordbuf[1], WLAN_SSID_MAXLEN); result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFOWNSSID, wordbuf, HFA384x_RID_CNFOWNSSID_LEN); if (result) { netdev_err(wlandev->netdev, "Failed to set OwnSSID.\n"); msg->resultcode.data = P80211ENUM_resultcode_implementation_failure; goto exit; } result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFDESIREDSSID, wordbuf, HFA384x_RID_CNFDESIREDSSID_LEN); if (result) { netdev_err(wlandev->netdev, "Failed to set DesiredSSID.\n"); msg->resultcode.data = P80211ENUM_resultcode_implementation_failure; goto exit; } /* bsstype */ result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFPORTTYPE, HFA384x_PORTTYPE_IBSS); if (result) { netdev_err(wlandev->netdev, "Failed to set CNFPORTTYPE.\n"); msg->resultcode.data = P80211ENUM_resultcode_implementation_failure; goto exit; } /* ibss options */ result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CREATEIBSS, HFA384x_CREATEIBSS_JOINCREATEIBSS); if (result) { netdev_err(wlandev->netdev, "Failed to set CREATEIBSS.\n"); msg->resultcode.data = P80211ENUM_resultcode_implementation_failure; goto exit; } result = hfa384x_drvr_enable(hw, 0); if (result) { netdev_err(wlandev->netdev, "drvr_enable(0) failed. result=%d\n", result); msg->resultcode.data = P80211ENUM_resultcode_implementation_failure; goto exit; } istmpenable = 1; } /* Figure out our timeout first Kus, then HZ */ timeout = msg->channellist.data.len * msg->maxchanneltime.data; timeout = (timeout * HZ) / 1000; /* Issue the scan request */ hw->scanflag = 0; result = hfa384x_drvr_setconfig(hw, HFA384x_RID_HOSTSCAN, &scanreq, sizeof(scanreq)); if (result) { netdev_err(wlandev->netdev, "setconfig(SCANREQUEST) failed. result=%d\n", result); msg->resultcode.data = P80211ENUM_resultcode_implementation_failure; goto exit; } /* sleep until info frame arrives */ wait_event_interruptible_timeout(hw->cmdq, hw->scanflag, timeout); msg->numbss.status = P80211ENUM_msgitem_status_data_ok; if (hw->scanflag == -1) hw->scanflag = 0; msg->numbss.data = hw->scanflag; hw->scanflag = 0; /* Disable port if we temporarily enabled it. */ if (istmpenable) { result = hfa384x_drvr_disable(hw, 0); if (result) { netdev_err(wlandev->netdev, "drvr_disable(0) failed. result=%d\n", result); msg->resultcode.data = P80211ENUM_resultcode_implementation_failure; goto exit; } } /* restore original roaming mode */ result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFROAMINGMODE, roamingmode); if (result) { netdev_err(wlandev->netdev, "setconfig(ROAMMODE) failed. result=%d\n", result); msg->resultcode.data = P80211ENUM_resultcode_implementation_failure; goto exit; } result = 0; msg->resultcode.data = P80211ENUM_resultcode_success; exit: msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; return result; }
/* Stop the Ethernet port activity */ static void mvneta_port_down(struct mvneta_port *pp) { u32 val; int count; /* Stop Rx port activity. Check port Rx activity. */ val = mvreg_read(pp, MVNETA_RXQ_CMD) & MVNETA_RXQ_ENABLE_MASK; /* Issue stop command for active channels only */ if (val != 0) mvreg_write(pp, MVNETA_RXQ_CMD, val << MVNETA_RXQ_DISABLE_SHIFT); /* Wait for all Rx activity to terminate. */ count = 0; do { if (count++ >= MVNETA_RX_DISABLE_TIMEOUT_MSEC) { netdev_warn(pp->dev, "TIMEOUT for RX stopped ! rx_queue_cmd: 0x08%x\n", val); break; } mdelay(1); val = mvreg_read(pp, MVNETA_RXQ_CMD); } while (val & 0xff); /* Stop Tx port activity. Check port Tx activity. Issue stop * command for active channels only */ val = (mvreg_read(pp, MVNETA_TXQ_CMD)) & MVNETA_TXQ_ENABLE_MASK; if (val != 0) mvreg_write(pp, MVNETA_TXQ_CMD, (val << MVNETA_TXQ_DISABLE_SHIFT)); /* Wait for all Tx activity to terminate. */ count = 0; do { if (count++ >= MVNETA_TX_DISABLE_TIMEOUT_MSEC) { netdev_warn(pp->dev, "TIMEOUT for TX stopped status=0x%08x\n", val); break; } mdelay(1); /* Check TX Command reg that all Txqs are stopped */ val = mvreg_read(pp, MVNETA_TXQ_CMD); } while (val & 0xff); /* Double check to verify that TX FIFO is empty */ count = 0; do { if (count++ >= MVNETA_TX_FIFO_EMPTY_TIMEOUT) { netdev_warn(pp->dev, "TX FIFO empty timeout status=0x08%x\n", val); break; } mdelay(1); val = mvreg_read(pp, MVNETA_PORT_STATUS); } while (!(val & MVNETA_TX_FIFO_EMPTY) && (val & MVNETA_TX_IN_PRGRS)); udelay(200); }
static netdev_tx_t qcaspi_netdev_xmit(struct sk_buff *skb, struct net_device *dev) { u32 frame_len; u8 *ptmp; struct qcaspi *qca = netdev_priv(dev); u16 new_tail; struct sk_buff *tskb; u8 pad_len = 0; if (skb->len < QCAFRM_ETHMINLEN) pad_len = QCAFRM_ETHMINLEN - skb->len; if (qca->txr.skb[qca->txr.tail]) { netdev_warn(qca->net_dev, "queue was unexpectedly full!\n"); netif_stop_queue(qca->net_dev); qca->stats.ring_full++; return NETDEV_TX_BUSY; } if ((skb_headroom(skb) < QCAFRM_HEADER_LEN) || (skb_tailroom(skb) < QCAFRM_FOOTER_LEN + pad_len)) { tskb = skb_copy_expand(skb, QCAFRM_HEADER_LEN, QCAFRM_FOOTER_LEN + pad_len, GFP_ATOMIC); if (!tskb) { netdev_dbg(qca->net_dev, "could not allocate tx_buff\n"); qca->stats.out_of_mem++; return NETDEV_TX_BUSY; } dev_kfree_skb(skb); skb = tskb; } frame_len = skb->len + pad_len; ptmp = skb_push(skb, QCAFRM_HEADER_LEN); qcafrm_create_header(ptmp, frame_len); if (pad_len) { ptmp = skb_put(skb, pad_len); memset(ptmp, 0, pad_len); } ptmp = skb_put(skb, QCAFRM_FOOTER_LEN); qcafrm_create_footer(ptmp); netdev_dbg(qca->net_dev, "Tx-ing packet: Size: 0x%08x\n", skb->len); qca->txr.size += skb->len + QCASPI_HW_PKT_LEN; new_tail = qca->txr.tail + 1; if (new_tail >= qca->txr.count) new_tail = 0; qca->txr.skb[qca->txr.tail] = skb; qca->txr.tail = new_tail; if (!qcaspi_tx_ring_has_space(&qca->txr)) { netif_stop_queue(qca->net_dev); qca->stats.ring_full++; } dev->trans_start = jiffies; if (qca->spi_thread && qca->spi_thread->state != TASK_RUNNING) wake_up_process(qca->spi_thread); return NETDEV_TX_OK; }
static void media_check(unsigned long arg) { struct net_device *dev = (struct net_device *)(arg); struct el3_private *lp = netdev_priv(dev); unsigned int ioaddr = dev->base_addr; u16 media, errs; unsigned long flags; if (!netif_device_present(dev)) goto reschedule; /* Check for pending interrupt with expired latency timer: with this, we can limp along even if the interrupt is blocked */ if ((inw(ioaddr + EL3_STATUS) & IntLatch) && (inb(ioaddr + EL3_TIMER) == 0xff)) { if (!lp->fast_poll) netdev_warn(dev, "interrupt(s) dropped!\n"); local_irq_save(flags); el3_interrupt(dev->irq, dev); local_irq_restore(flags); lp->fast_poll = HZ; } if (lp->fast_poll) { lp->fast_poll--; lp->media.expires = jiffies + HZ/100; add_timer(&lp->media); return; } /* lp->lock guards the EL3 window. Window should always be 1 except when the lock is held */ spin_lock_irqsave(&lp->lock, flags); EL3WINDOW(4); media = inw(ioaddr+WN4_MEDIA) & 0xc810; /* Ignore collisions unless we've had no irq's recently */ if (time_before(jiffies, lp->last_irq + HZ)) { media &= ~0x0010; } else { /* Try harder to detect carrier errors */ EL3WINDOW(6); outw(StatsDisable, ioaddr + EL3_CMD); errs = inb(ioaddr + 0); outw(StatsEnable, ioaddr + EL3_CMD); dev->stats.tx_carrier_errors += errs; if (errs || (lp->media_status & 0x0010)) media |= 0x0010; } if (media != lp->media_status) { if ((media & lp->media_status & 0x8000) && ((lp->media_status ^ media) & 0x0800)) netdev_info(dev, "%s link beat\n", (lp->media_status & 0x0800 ? "lost" : "found")); else if ((media & lp->media_status & 0x4000) && ((lp->media_status ^ media) & 0x0010)) netdev_info(dev, "coax cable %s\n", (lp->media_status & 0x0010 ? "ok" : "problem")); if (dev->if_port == 0) { if (media & 0x8000) { if (media & 0x0800) netdev_info(dev, "flipped to 10baseT\n"); else tc589_set_xcvr(dev, 2); } else if (media & 0x4000) { if (media & 0x0010) tc589_set_xcvr(dev, 1); else netdev_info(dev, "flipped to 10base2\n"); } } lp->media_status = media; } EL3WINDOW(1); spin_unlock_irqrestore(&lp->lock, flags); reschedule: lp->media.expires = jiffies + HZ; add_timer(&lp->media); }
static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt) { struct can_priv *priv = netdev_priv(dev); const struct can_bittiming_const *btc = priv->bittiming_const; long rate, best_rate = 0; long best_error = 1000000000, error = 0; int best_tseg = 0, best_brp = 0, brp = 0; int tsegall, tseg = 0, tseg1 = 0, tseg2 = 0; int spt_error = 1000, spt = 0, sampl_pt; u64 v64; if (!priv->bittiming_const) return -ENOTSUPP; if (bt->sample_point) { sampl_pt = bt->sample_point; } else { if (bt->bitrate > 800000) sampl_pt = 750; else if (bt->bitrate > 500000) sampl_pt = 800; else sampl_pt = 875; } for (tseg = (btc->tseg1_max + btc->tseg2_max) * 2 + 1; tseg >= (btc->tseg1_min + btc->tseg2_min) * 2; tseg--) { tsegall = 1 + tseg / 2; brp = priv->clock.freq / (tsegall * bt->bitrate) + tseg % 2; brp = (brp / btc->brp_inc) * btc->brp_inc; if ((brp < btc->brp_min) || (brp > btc->brp_max)) continue; rate = priv->clock.freq / (brp * tsegall); error = bt->bitrate - rate; if (error < 0) error = -error; if (error > best_error) continue; best_error = error; if (error == 0) { spt = can_update_spt(btc, sampl_pt, tseg / 2, &tseg1, &tseg2); error = sampl_pt - spt; if (error < 0) error = -error; if (error > spt_error) continue; spt_error = error; } best_tseg = tseg / 2; best_brp = brp; best_rate = rate; if (error == 0) break; } if (best_error) { error = (best_error * 1000) / bt->bitrate; if (error > CAN_CALC_MAX_ERROR) { netdev_err(dev, "bitrate error %ld.%ld%% too high\n", error / 10, error % 10); return -EDOM; } else { netdev_warn(dev, "bitrate error %ld.%ld%%\n", error / 10, error % 10); } } bt->sample_point = can_update_spt(btc, sampl_pt, best_tseg, &tseg1, &tseg2); v64 = (u64)best_brp * 1000000000UL; do_div(v64, priv->clock.freq); bt->tq = (u32)v64; bt->prop_seg = tseg1 / 2; bt->phase_seg1 = tseg1 - bt->prop_seg; bt->phase_seg2 = tseg2; if (!bt->sjw || !btc->sjw_max) bt->sjw = 1; else { if (bt->sjw > btc->sjw_max) bt->sjw = btc->sjw_max; if (tseg2 < bt->sjw) bt->sjw = tseg2; } bt->brp = best_brp; bt->bitrate = priv->clock.freq / (bt->brp * (tseg1 + tseg2 + 1)); return 0; }
/** * eth_change_mtu - set new MTU size * @dev: network device * @new_mtu: new Maximum Transfer Unit * * Allow changing MTU size. Needs to be overridden for devices * supporting jumbo frames. */ int eth_change_mtu(struct net_device *dev, int new_mtu) { netdev_warn(dev, "%s is deprecated\n", __func__); dev->mtu = new_mtu; return 0; }
static netdev_tx_t ems_usb_start_xmit(struct sk_buff *skb, struct net_device *netdev) { struct ems_usb *dev = netdev_priv(netdev); struct ems_tx_urb_context *context = NULL; struct net_device_stats *stats = &netdev->stats; struct can_frame *cf = (struct can_frame *)skb->data; struct ems_cpc_msg *msg; struct urb *urb; u8 *buf; int i, err; size_t size = CPC_HEADER_SIZE + CPC_MSG_HEADER_LEN + sizeof(struct cpc_can_msg); if (can_dropped_invalid_skb(netdev, skb)) return NETDEV_TX_OK; /* create a URB, and a buffer for it, and copy the data to the URB */ urb = usb_alloc_urb(0, GFP_ATOMIC); if (!urb) { netdev_err(netdev, "No memory left for URBs\n"); goto nomem; } buf = usb_alloc_coherent(dev->udev, size, GFP_ATOMIC, &urb->transfer_dma); if (!buf) { netdev_err(netdev, "No memory left for USB buffer\n"); usb_free_urb(urb); goto nomem; } msg = (struct ems_cpc_msg *)&buf[CPC_HEADER_SIZE]; msg->msg.can_msg.id = cf->can_id & CAN_ERR_MASK; msg->msg.can_msg.length = cf->can_dlc; if (cf->can_id & CAN_RTR_FLAG) { msg->type = cf->can_id & CAN_EFF_FLAG ? CPC_CMD_TYPE_EXT_RTR_FRAME : CPC_CMD_TYPE_RTR_FRAME; msg->length = CPC_CAN_MSG_MIN_SIZE; } else { msg->type = cf->can_id & CAN_EFF_FLAG ? CPC_CMD_TYPE_EXT_CAN_FRAME : CPC_CMD_TYPE_CAN_FRAME; for (i = 0; i < cf->can_dlc; i++) msg->msg.can_msg.msg[i] = cf->data[i]; msg->length = CPC_CAN_MSG_MIN_SIZE + cf->can_dlc; } /* Respect byte order */ msg->msg.can_msg.id = cpu_to_le32(msg->msg.can_msg.id); for (i = 0; i < MAX_TX_URBS; i++) { if (dev->tx_contexts[i].echo_index == MAX_TX_URBS) { context = &dev->tx_contexts[i]; break; } } /* * May never happen! When this happens we'd more URBs in flight as * allowed (MAX_TX_URBS). */ if (!context) { usb_free_coherent(dev->udev, size, buf, urb->transfer_dma); usb_free_urb(urb); netdev_warn(netdev, "couldn't find free context\n"); return NETDEV_TX_BUSY; } context->dev = dev; context->echo_index = i; context->dlc = cf->can_dlc; usb_fill_bulk_urb(urb, dev->udev, usb_sndbulkpipe(dev->udev, 2), buf, size, ems_usb_write_bulk_callback, context); urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; usb_anchor_urb(urb, &dev->tx_submitted); can_put_echo_skb(skb, netdev, context->echo_index); atomic_inc(&dev->active_tx_urbs); err = usb_submit_urb(urb, GFP_ATOMIC); if (unlikely(err)) { can_free_echo_skb(netdev, context->echo_index); usb_unanchor_urb(urb); usb_free_coherent(dev->udev, size, buf, urb->transfer_dma); dev_kfree_skb(skb); atomic_dec(&dev->active_tx_urbs); if (err == -ENODEV) { netif_device_detach(netdev); } else { netdev_warn(netdev, "failed tx_urb %d\n", err); stats->tx_dropped++; } } else { netdev->trans_start = jiffies; /* Slow down tx path */ if (atomic_read(&dev->active_tx_urbs) >= MAX_TX_URBS || dev->free_slots < 5) { netif_stop_queue(netdev); } } /* * Release our reference to this URB, the USB core will eventually free * it entirely. */ usb_free_urb(urb); return NETDEV_TX_OK; nomem: dev_kfree_skb(skb); stats->tx_dropped++; return NETDEV_TX_OK; }
static int bond_changelink(struct net_device *bond_dev, struct nlattr *tb[], struct nlattr *data[]) { struct bonding *bond = netdev_priv(bond_dev); struct bond_opt_value newval; int miimon = 0; int err; if (!data) return 0; if (data[IFLA_BOND_MODE]) { int mode = nla_get_u8(data[IFLA_BOND_MODE]); bond_opt_initval(&newval, mode); err = __bond_opt_set(bond, BOND_OPT_MODE, &newval); if (err) return err; } if (data[IFLA_BOND_ACTIVE_SLAVE]) { int ifindex = nla_get_u32(data[IFLA_BOND_ACTIVE_SLAVE]); struct net_device *slave_dev; char *active_slave = ""; if (ifindex != 0) { slave_dev = __dev_get_by_index(dev_net(bond_dev), ifindex); if (!slave_dev) return -ENODEV; active_slave = slave_dev->name; } bond_opt_initstr(&newval, active_slave); err = __bond_opt_set(bond, BOND_OPT_ACTIVE_SLAVE, &newval); if (err) return err; } if (data[IFLA_BOND_MIIMON]) { miimon = nla_get_u32(data[IFLA_BOND_MIIMON]); bond_opt_initval(&newval, miimon); err = __bond_opt_set(bond, BOND_OPT_MIIMON, &newval); if (err) return err; } if (data[IFLA_BOND_UPDELAY]) { int updelay = nla_get_u32(data[IFLA_BOND_UPDELAY]); bond_opt_initval(&newval, updelay); err = __bond_opt_set(bond, BOND_OPT_UPDELAY, &newval); if (err) return err; } if (data[IFLA_BOND_DOWNDELAY]) { int downdelay = nla_get_u32(data[IFLA_BOND_DOWNDELAY]); bond_opt_initval(&newval, downdelay); err = __bond_opt_set(bond, BOND_OPT_DOWNDELAY, &newval); if (err) return err; } if (data[IFLA_BOND_USE_CARRIER]) { int use_carrier = nla_get_u8(data[IFLA_BOND_USE_CARRIER]); bond_opt_initval(&newval, use_carrier); err = __bond_opt_set(bond, BOND_OPT_USE_CARRIER, &newval); if (err) return err; } if (data[IFLA_BOND_ARP_INTERVAL]) { int arp_interval = nla_get_u32(data[IFLA_BOND_ARP_INTERVAL]); if (arp_interval && miimon) { netdev_err(bond->dev, "ARP monitoring cannot be used with MII monitoring\n"); return -EINVAL; } bond_opt_initval(&newval, arp_interval); err = __bond_opt_set(bond, BOND_OPT_ARP_INTERVAL, &newval); if (err) return err; } if (data[IFLA_BOND_ARP_IP_TARGET]) { struct nlattr *attr; int i = 0, rem; bond_option_arp_ip_targets_clear(bond); nla_for_each_nested(attr, data[IFLA_BOND_ARP_IP_TARGET], rem) { __be32 target; if (nla_len(attr) < sizeof(target)) return -EINVAL; target = nla_get_be32(attr); bond_opt_initval(&newval, (__force u64)target); err = __bond_opt_set(bond, BOND_OPT_ARP_TARGETS, &newval); if (err) break; i++; } if (i == 0 && bond->params.arp_interval) netdev_warn(bond->dev, "Removing last arp target with arp_interval on\n"); if (err) return err; }
static void bfin_mac_adjust_link(struct net_device *dev) { struct bfin_mac_local *lp = netdev_priv(dev); struct phy_device *phydev = lp->phydev; unsigned long flags; int new_state = 0; spin_lock_irqsave(&lp->lock, flags); if (phydev->link) { if (phydev->duplex != lp->old_duplex) { u32 opmode = bfin_read_EMAC_OPMODE(); new_state = 1; if (phydev->duplex) opmode |= FDMODE; else opmode &= ~(FDMODE); bfin_write_EMAC_OPMODE(opmode); lp->old_duplex = phydev->duplex; } if (phydev->speed != lp->old_speed) { if (phydev->interface == PHY_INTERFACE_MODE_RMII) { u32 opmode = bfin_read_EMAC_OPMODE(); switch (phydev->speed) { case 10: opmode |= RMII_10; break; case 100: opmode &= ~RMII_10; break; default: netdev_warn(dev, "Ack! Speed (%d) is not 10/100!\n", phydev->speed); break; } bfin_write_EMAC_OPMODE(opmode); } new_state = 1; lp->old_speed = phydev->speed; } if (!lp->old_link) { new_state = 1; lp->old_link = 1; } } else if (lp->old_link) { new_state = 1; lp->old_link = 0; lp->old_speed = 0; lp->old_duplex = -1; } if (new_state) { u32 opmode = bfin_read_EMAC_OPMODE(); phy_print_status(phydev); pr_debug("EMAC_OPMODE = 0x%08x\n", opmode); } spin_unlock_irqrestore(&lp->lock, flags); }
static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt) { struct can_priv *priv = netdev_priv(dev); const struct can_bittiming_const *btc = priv->bittiming_const; long rate, best_rate = 0; long best_error = 1000000000, error = 0; int best_tseg = 0, best_brp = 0, brp = 0; int tsegall, tseg = 0, tseg1 = 0, tseg2 = 0; int spt_error = 1000, spt = 0, sampl_pt; u64 v64; if (!priv->bittiming_const) return -ENOTSUPP; /* Use CIA recommended sample points */ if (bt->sample_point) { sampl_pt = bt->sample_point; } else { if (bt->bitrate > 800000) sampl_pt = 750; else if (bt->bitrate > 500000) sampl_pt = 800; else sampl_pt = 875; } /* tseg even = round down, odd = round up */ for (tseg = (btc->tseg1_max + btc->tseg2_max) * 2 + 1; tseg >= (btc->tseg1_min + btc->tseg2_min) * 2; tseg--) { tsegall = 1 + tseg / 2; /* Compute all possible tseg choices (tseg=tseg1+tseg2) */ brp = priv->clock.freq / (tsegall * bt->bitrate) + tseg % 2; /* chose brp step which is possible in system */ brp = (brp / btc->brp_inc) * btc->brp_inc; if ((brp < btc->brp_min) || (brp > btc->brp_max)) continue; rate = priv->clock.freq / (brp * tsegall); error = bt->bitrate - rate; /* tseg brp biterror */ if (error < 0) error = -error; if (error > best_error) continue; best_error = error; if (error == 0) { spt = can_update_spt(btc, sampl_pt, tseg / 2, &tseg1, &tseg2); error = sampl_pt - spt; if (error < 0) error = -error; if (error > spt_error) continue; spt_error = error; } best_tseg = tseg / 2; best_brp = brp; best_rate = rate; if (error == 0) break; } if (best_error) { /* Error in one-tenth of a percent */ error = (best_error * 1000) / bt->bitrate; if (error > CAN_CALC_MAX_ERROR) { netdev_err(dev, "bitrate error %ld.%ld%% too high\n", error / 10, error % 10); return -EDOM; } else { netdev_warn(dev, "bitrate error %ld.%ld%%\n", error / 10, error % 10); } } /* real sample point */ bt->sample_point = can_update_spt(btc, sampl_pt, best_tseg, &tseg1, &tseg2); v64 = (u64)best_brp * 1000000000UL; do_div(v64, priv->clock.freq); bt->tq = (u32)v64; bt->prop_seg = tseg1 / 2; bt->phase_seg1 = tseg1 - bt->prop_seg; bt->phase_seg2 = tseg2; /* check for sjw user settings */ if (!bt->sjw || !btc->sjw_max) bt->sjw = 1; else { /* bt->sjw is at least 1 -> sanitize upper bound to sjw_max */ if (bt->sjw > btc->sjw_max) bt->sjw = btc->sjw_max; /* bt->sjw must not be higher than tseg2 */ if (tseg2 < bt->sjw) bt->sjw = tseg2; } bt->brp = best_brp; /* real bit-rate */ bt->bitrate = priv->clock.freq / (bt->brp * (tseg1 + tseg2 + 1)); return 0; }
static int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev) { struct rtllib_device *ieee = (struct rtllib_device *) netdev_priv_rsl(dev); struct rtllib_txb *txb = NULL; struct rtllib_hdr_3addrqos *frag_hdr; int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size; unsigned long flags; struct net_device_stats *stats = &ieee->stats; int ether_type = 0, encrypt; int bytes, fc, qos_ctl = 0, hdr_len; struct sk_buff *skb_frag; struct rtllib_hdr_3addrqos header = { /* Ensure zero initialized */ .duration_id = 0, .seq_ctl = 0, .qos_ctl = 0 }; int qos_actived = ieee->current_network.qos_data.active; u8 dest[ETH_ALEN]; u8 src[ETH_ALEN]; struct lib80211_crypt_data *crypt = NULL; struct cb_desc *tcb_desc; u8 bIsMulticast = false; u8 IsAmsdu = false; bool bdhcp = false; spin_lock_irqsave(&ieee->lock, flags); /* If there is no driver handler to take the TXB, don't bother * creating it... */ if ((!ieee->hard_start_xmit && !(ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)) || ((!ieee->softmac_data_hard_start_xmit && (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)))) { netdev_warn(ieee->dev, "No xmit handler.\n"); goto success; } if (likely(ieee->raw_tx == 0)) { if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) { netdev_warn(ieee->dev, "skb too small (%d).\n", skb->len); goto success; } /* Save source and destination addresses */ ether_addr_copy(dest, skb->data); ether_addr_copy(src, skb->data + ETH_ALEN); memset(skb->cb, 0, sizeof(skb->cb)); ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto); if (ieee->iw_mode == IW_MODE_MONITOR) { txb = rtllib_alloc_txb(1, skb->len, GFP_ATOMIC); if (unlikely(!txb)) { netdev_warn(ieee->dev, "Could not allocate TXB\n"); goto failed; } txb->encrypted = 0; txb->payload_size = cpu_to_le16(skb->len); skb_put_data(txb->fragments[0], skb->data, skb->len); goto success; } if (skb->len > 282) { if (ether_type == ETH_P_IP) { const struct iphdr *ip = (struct iphdr *) ((u8 *)skb->data+14); if (ip->protocol == IPPROTO_UDP) { struct udphdr *udp; udp = (struct udphdr *)((u8 *)ip + (ip->ihl << 2)); if (((((u8 *)udp)[1] == 68) && (((u8 *)udp)[3] == 67)) || ((((u8 *)udp)[1] == 67) && (((u8 *)udp)[3] == 68))) { bdhcp = true; ieee->LPSDelayCnt = 200; } } } else if (ether_type == ETH_P_ARP) { netdev_info(ieee->dev, "=================>DHCP Protocol start tx ARP pkt!!\n"); bdhcp = true; ieee->LPSDelayCnt = ieee->current_network.tim.tim_count; } } skb->priority = rtllib_classify(skb, IsAmsdu); crypt = ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx]; encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) && ieee->host_encrypt && crypt && crypt->ops; if (!encrypt && ieee->ieee802_1x && ieee->drop_unencrypted && ether_type != ETH_P_PAE) { stats->tx_dropped++; goto success; } if (crypt && !encrypt && ether_type == ETH_P_PAE) { struct eapol *eap = (struct eapol *)(skb->data + sizeof(struct ethhdr) - SNAP_SIZE - sizeof(u16)); netdev_dbg(ieee->dev, "TX: IEEE 802.11 EAPOL frame: %s\n", eap_get_type(eap->type)); } /* Advance the SKB to the start of the payload */ skb_pull(skb, sizeof(struct ethhdr)); /* Determine total amount of storage required for TXB packets */ bytes = skb->len + SNAP_SIZE + sizeof(u16); if (encrypt) fc = RTLLIB_FTYPE_DATA | RTLLIB_FCTL_WEP; else fc = RTLLIB_FTYPE_DATA; if (qos_actived) fc |= RTLLIB_STYPE_QOS_DATA; else fc |= RTLLIB_STYPE_DATA; if (ieee->iw_mode == IW_MODE_INFRA) { fc |= RTLLIB_FCTL_TODS; /* To DS: Addr1 = BSSID, Addr2 = SA, * Addr3 = DA */ ether_addr_copy(header.addr1, ieee->current_network.bssid); ether_addr_copy(header.addr2, src); if (IsAmsdu) ether_addr_copy(header.addr3, ieee->current_network.bssid); else ether_addr_copy(header.addr3, dest); } else if (ieee->iw_mode == IW_MODE_ADHOC) { /* not From/To DS: Addr1 = DA, Addr2 = SA, * Addr3 = BSSID */ ether_addr_copy(header.addr1, dest); ether_addr_copy(header.addr2, src); ether_addr_copy(header.addr3, ieee->current_network.bssid); } bIsMulticast = is_multicast_ether_addr(header.addr1); header.frame_ctl = cpu_to_le16(fc); /* Determine fragmentation size based on destination (multicast * and broadcast are not fragmented) */ if (bIsMulticast) { frag_size = MAX_FRAG_THRESHOLD; qos_ctl |= QOS_CTL_NOTCONTAIN_ACK; } else { frag_size = ieee->fts; qos_ctl = 0; } if (qos_actived) { hdr_len = RTLLIB_3ADDR_LEN + 2; /* in case we are a client verify acm is not set for this ac */ while (unlikely(ieee->wmm_acm & (0x01 << skb->priority))) { netdev_info(ieee->dev, "skb->priority = %x\n", skb->priority); if (wme_downgrade_ac(skb)) break; netdev_info(ieee->dev, "converted skb->priority = %x\n", skb->priority); } qos_ctl |= skb->priority; header.qos_ctl = cpu_to_le16(qos_ctl & RTLLIB_QOS_TID); } else { hdr_len = RTLLIB_3ADDR_LEN; } /* Determine amount of payload per fragment. Regardless of if * this stack is providing the full 802.11 header, one will * eventually be affixed to this fragment -- so we must account * for it when determining the amount of payload space. */ bytes_per_frag = frag_size - hdr_len; if (ieee->config & (CFG_RTLLIB_COMPUTE_FCS | CFG_RTLLIB_RESERVE_FCS)) bytes_per_frag -= RTLLIB_FCS_LEN; /* Each fragment may need to have room for encrypting * pre/postfix */ if (encrypt) { bytes_per_frag -= crypt->ops->extra_mpdu_prefix_len + crypt->ops->extra_mpdu_postfix_len + crypt->ops->extra_msdu_prefix_len + crypt->ops->extra_msdu_postfix_len; } /* Number of fragments is the total bytes_per_frag / * payload_per_fragment */ nr_frags = bytes / bytes_per_frag; bytes_last_frag = bytes % bytes_per_frag; if (bytes_last_frag) nr_frags++; else bytes_last_frag = bytes_per_frag; /* When we allocate the TXB we allocate enough space for the * reserve and full fragment bytes (bytes_per_frag doesn't * include prefix, postfix, header, FCS, etc.) */ txb = rtllib_alloc_txb(nr_frags, frag_size + ieee->tx_headroom, GFP_ATOMIC); if (unlikely(!txb)) { netdev_warn(ieee->dev, "Could not allocate TXB\n"); goto failed; } txb->encrypted = encrypt; txb->payload_size = cpu_to_le16(bytes); if (qos_actived) txb->queue_index = UP2AC(skb->priority); else txb->queue_index = WME_AC_BE; for (i = 0; i < nr_frags; i++) { skb_frag = txb->fragments[i]; tcb_desc = (struct cb_desc *)(skb_frag->cb + MAX_DEV_ADDR_SIZE); if (qos_actived) { skb_frag->priority = skb->priority; tcb_desc->queue_index = UP2AC(skb->priority); } else { skb_frag->priority = WME_AC_BE; tcb_desc->queue_index = WME_AC_BE; } skb_reserve(skb_frag, ieee->tx_headroom); if (encrypt) { if (ieee->hwsec_active) tcb_desc->bHwSec = 1; else tcb_desc->bHwSec = 0; skb_reserve(skb_frag, crypt->ops->extra_mpdu_prefix_len + crypt->ops->extra_msdu_prefix_len); } else { tcb_desc->bHwSec = 0; } frag_hdr = skb_put_data(skb_frag, &header, hdr_len); /* If this is not the last fragment, then add the * MOREFRAGS bit to the frame control */ if (i != nr_frags - 1) { frag_hdr->frame_ctl = cpu_to_le16( fc | RTLLIB_FCTL_MOREFRAGS); bytes = bytes_per_frag; } else { /* The last fragment has the remaining length */ bytes = bytes_last_frag; } if ((qos_actived) && (!bIsMulticast)) { frag_hdr->seq_ctl = cpu_to_le16(rtllib_query_seqnum(ieee, skb_frag, header.addr1)); frag_hdr->seq_ctl = cpu_to_le16(le16_to_cpu(frag_hdr->seq_ctl)<<4 | i); } else { frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4 | i); } /* Put a SNAP header on the first fragment */ if (i == 0) { rtllib_put_snap( skb_put(skb_frag, SNAP_SIZE + sizeof(u16)), ether_type); bytes -= SNAP_SIZE + sizeof(u16); } skb_put_data(skb_frag, skb->data, bytes); /* Advance the SKB... */ skb_pull(skb, bytes); /* Encryption routine will move the header forward in * order to insert the IV between the header and the * payload */ if (encrypt) rtllib_encrypt_fragment(ieee, skb_frag, hdr_len); if (ieee->config & (CFG_RTLLIB_COMPUTE_FCS | CFG_RTLLIB_RESERVE_FCS)) skb_put(skb_frag, 4); } if ((qos_actived) && (!bIsMulticast)) { if (ieee->seq_ctrl[UP2AC(skb->priority) + 1] == 0xFFF) ieee->seq_ctrl[UP2AC(skb->priority) + 1] = 0; else ieee->seq_ctrl[UP2AC(skb->priority) + 1]++; } else { if (ieee->seq_ctrl[0] == 0xFFF) ieee->seq_ctrl[0] = 0; else ieee->seq_ctrl[0]++; } } else { if (unlikely(skb->len < sizeof(struct rtllib_hdr_3addr))) { netdev_warn(ieee->dev, "skb too small (%d).\n", skb->len); goto success; } txb = rtllib_alloc_txb(1, skb->len, GFP_ATOMIC); if (!txb) { netdev_warn(ieee->dev, "Could not allocate TXB\n"); goto failed; } txb->encrypted = 0; txb->payload_size = cpu_to_le16(skb->len); skb_put_data(txb->fragments[0], skb->data, skb->len); } success: if (txb) { struct cb_desc *tcb_desc = (struct cb_desc *) (txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE); tcb_desc->bTxEnableFwCalcDur = 1; tcb_desc->priority = skb->priority; if (ether_type == ETH_P_PAE) { if (ieee->pHTInfo->IOTAction & HT_IOT_ACT_WA_IOT_Broadcom) { tcb_desc->data_rate = MgntQuery_TxRateExcludeCCKRates(ieee); tcb_desc->bTxDisableRateFallBack = false; } else { tcb_desc->data_rate = ieee->basic_rate; tcb_desc->bTxDisableRateFallBack = 1; } tcb_desc->RATRIndex = 7; tcb_desc->bTxUseDriverAssingedRate = 1; } else { if (is_multicast_ether_addr(header.addr1)) tcb_desc->bMulticast = 1; if (is_broadcast_ether_addr(header.addr1)) tcb_desc->bBroadcast = 1; rtllib_txrate_selectmode(ieee, tcb_desc); if (tcb_desc->bMulticast || tcb_desc->bBroadcast) tcb_desc->data_rate = ieee->basic_rate; else tcb_desc->data_rate = rtllib_current_rate(ieee); if (bdhcp) { if (ieee->pHTInfo->IOTAction & HT_IOT_ACT_WA_IOT_Broadcom) { tcb_desc->data_rate = MgntQuery_TxRateExcludeCCKRates(ieee); tcb_desc->bTxDisableRateFallBack = false; } else { tcb_desc->data_rate = MGN_1M; tcb_desc->bTxDisableRateFallBack = 1; } tcb_desc->RATRIndex = 7; tcb_desc->bTxUseDriverAssingedRate = 1; tcb_desc->bdhcp = 1; } rtllib_qurey_ShortPreambleMode(ieee, tcb_desc); rtllib_tx_query_agg_cap(ieee, txb->fragments[0], tcb_desc); rtllib_query_HTCapShortGI(ieee, tcb_desc); rtllib_query_BandwidthMode(ieee, tcb_desc); rtllib_query_protectionmode(ieee, tcb_desc, txb->fragments[0]); } } spin_unlock_irqrestore(&ieee->lock, flags); dev_kfree_skb_any(skb); if (txb) { if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE) { dev->stats.tx_packets++; dev->stats.tx_bytes += le16_to_cpu(txb->payload_size); rtllib_softmac_xmit(txb, ieee); } else { if ((*ieee->hard_start_xmit)(txb, dev) == 0) { stats->tx_packets++; stats->tx_bytes += le16_to_cpu(txb->payload_size); return 0; } rtllib_txb_free(txb); } } return 0; failed: spin_unlock_irqrestore(&ieee->lock, flags); netif_stop_queue(dev); stats->tx_errors++; return 1; } int rtllib_xmit(struct sk_buff *skb, struct net_device *dev) { memset(skb->cb, 0, sizeof(skb->cb)); return rtllib_xmit_inter(skb, dev); }
static int phylink_parse_fixedlink(struct phylink *pl, struct device_node *np) { struct device_node *fixed_node; const struct phy_setting *s; struct gpio_desc *desc; const __be32 *fixed_prop; u32 speed; int ret, len; fixed_node = of_get_child_by_name(np, "fixed-link"); if (fixed_node) { ret = of_property_read_u32(fixed_node, "speed", &speed); pl->link_config.speed = speed; pl->link_config.duplex = DUPLEX_HALF; if (of_property_read_bool(fixed_node, "full-duplex")) pl->link_config.duplex = DUPLEX_FULL; /* We treat the "pause" and "asym-pause" terminology as * defining the link partner's ability. */ if (of_property_read_bool(fixed_node, "pause")) pl->link_config.pause |= MLO_PAUSE_SYM; if (of_property_read_bool(fixed_node, "asym-pause")) pl->link_config.pause |= MLO_PAUSE_ASYM; if (ret == 0) { desc = fwnode_get_named_gpiod(&fixed_node->fwnode, "link-gpios", 0, GPIOD_IN, "?"); if (!IS_ERR(desc)) pl->link_gpio = desc; else if (desc == ERR_PTR(-EPROBE_DEFER)) ret = -EPROBE_DEFER; } of_node_put(fixed_node); if (ret) return ret; } else { fixed_prop = of_get_property(np, "fixed-link", &len); if (!fixed_prop) { netdev_err(pl->netdev, "broken fixed-link?\n"); return -EINVAL; } if (len == 5 * sizeof(*fixed_prop)) { pl->link_config.duplex = be32_to_cpu(fixed_prop[1]) ? DUPLEX_FULL : DUPLEX_HALF; pl->link_config.speed = be32_to_cpu(fixed_prop[2]); if (be32_to_cpu(fixed_prop[3])) pl->link_config.pause |= MLO_PAUSE_SYM; if (be32_to_cpu(fixed_prop[4])) pl->link_config.pause |= MLO_PAUSE_ASYM; } } if (pl->link_config.speed > SPEED_1000 && pl->link_config.duplex != DUPLEX_FULL) netdev_warn(pl->netdev, "fixed link specifies half duplex for %dMbps link?\n", pl->link_config.speed); bitmap_fill(pl->supported, __ETHTOOL_LINK_MODE_MASK_NBITS); linkmode_copy(pl->link_config.advertising, pl->supported); phylink_validate(pl, pl->supported, &pl->link_config); s = phy_lookup_setting(pl->link_config.speed, pl->link_config.duplex, pl->supported, __ETHTOOL_LINK_MODE_MASK_NBITS, true); linkmode_zero(pl->supported); phylink_set(pl->supported, MII); if (s) { __set_bit(s->bit, pl->supported); } else { netdev_warn(pl->netdev, "fixed link %s duplex %dMbps not recognised\n", pl->link_config.duplex == DUPLEX_FULL ? "full" : "half", pl->link_config.speed); } linkmode_and(pl->link_config.advertising, pl->link_config.advertising, pl->supported); pl->link_config.link = 1; pl->link_config.an_complete = 1; return 0; }
/* * Start interface */ static int ems_usb_start(struct ems_usb *dev) { struct net_device *netdev = dev->netdev; int err, i; dev->intr_in_buffer[0] = 0; dev->free_slots = 15; /* initial size */ for (i = 0; i < MAX_RX_URBS; i++) { struct urb *urb = NULL; u8 *buf = NULL; /* create a URB, and a buffer for it */ urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) { netdev_err(netdev, "No memory left for URBs\n"); err = -ENOMEM; break; } buf = usb_alloc_coherent(dev->udev, RX_BUFFER_SIZE, GFP_KERNEL, &urb->transfer_dma); if (!buf) { netdev_err(netdev, "No memory left for USB buffer\n"); usb_free_urb(urb); err = -ENOMEM; break; } usb_fill_bulk_urb(urb, dev->udev, usb_rcvbulkpipe(dev->udev, 2), buf, RX_BUFFER_SIZE, ems_usb_read_bulk_callback, dev); urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; usb_anchor_urb(urb, &dev->rx_submitted); err = usb_submit_urb(urb, GFP_KERNEL); if (err) { usb_unanchor_urb(urb); usb_free_coherent(dev->udev, RX_BUFFER_SIZE, buf, urb->transfer_dma); usb_free_urb(urb); break; } /* Drop reference, USB core will take care of freeing it */ usb_free_urb(urb); } /* Did we submit any URBs */ if (i == 0) { netdev_warn(netdev, "couldn't setup read URBs\n"); return err; } /* Warn if we've couldn't transmit all the URBs */ if (i < MAX_RX_URBS) netdev_warn(netdev, "rx performance may be slow\n"); /* Setup and start interrupt URB */ usb_fill_int_urb(dev->intr_urb, dev->udev, usb_rcvintpipe(dev->udev, 1), dev->intr_in_buffer, INTR_IN_BUFFER_SIZE, ems_usb_read_interrupt_callback, dev, 1); err = usb_submit_urb(dev->intr_urb, GFP_KERNEL); if (err) { netdev_warn(netdev, "intr URB submit failed: %d\n", err); return err; } /* CPC-USB will transfer received message to host */ err = ems_usb_control_cmd(dev, CONTR_CAN_MESSAGE | CONTR_CONT_ON); if (err) goto failed; /* CPC-USB will transfer CAN state changes to host */ err = ems_usb_control_cmd(dev, CONTR_CAN_STATE | CONTR_CONT_ON); if (err) goto failed; /* CPC-USB will transfer bus errors to host */ err = ems_usb_control_cmd(dev, CONTR_BUS_ERROR | CONTR_CONT_ON); if (err) goto failed; err = ems_usb_write_mode(dev, SJA1000_MOD_NORMAL); if (err) goto failed; dev->can.state = CAN_STATE_ERROR_ACTIVE; return 0; failed: netdev_warn(netdev, "couldn't submit control: %d\n", err); return err; }
static int zorro8390_init(struct net_device *dev, unsigned long board, const char *name, void __iomem *ioaddr) { int i; int err; unsigned char SA_prom[32]; int start_page, stop_page; struct ei_device *ei_local = netdev_priv(dev); static u32 zorro8390_offsets[16] = { 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e, }; /* Reset card. Who knows what dain-bramaged state it was left in. */ { unsigned long reset_start_time = jiffies; z_writeb(z_readb(ioaddr + NE_RESET), ioaddr + NE_RESET); while ((z_readb(ioaddr + NE_EN0_ISR) & ENISR_RESET) == 0) if (time_after(jiffies, reset_start_time + 2 * HZ / 100)) { netdev_warn(dev, "not found (no reset ack)\n"); return -ENODEV; } z_writeb(0xff, ioaddr + NE_EN0_ISR); /* Ack all intr. */ } /* Read the 16 bytes of station address PROM. * We must first initialize registers, * similar to NS8390_init(eifdev, 0). * We can't reliably read the SAPROM address without this. * (I learned the hard way!). */ { static const struct { u32 value; u32 offset; } program_seq[] = { {E8390_NODMA + E8390_PAGE0 + E8390_STOP, NE_CMD}, /* Select page 0 */ {0x48, NE_EN0_DCFG}, /* 0x48: Set byte-wide access */ {0x00, NE_EN0_RCNTLO}, /* Clear the count regs */ {0x00, NE_EN0_RCNTHI}, {0x00, NE_EN0_IMR}, /* Mask completion irq */ {0xFF, NE_EN0_ISR}, {E8390_RXOFF, NE_EN0_RXCR}, /* 0x20 Set to monitor */ {E8390_TXOFF, NE_EN0_TXCR}, /* 0x02 and loopback mode */ {32, NE_EN0_RCNTLO}, {0x00, NE_EN0_RCNTHI}, {0x00, NE_EN0_RSARLO}, /* DMA starting at 0x0000 */ {0x00, NE_EN0_RSARHI}, {E8390_RREAD + E8390_START, NE_CMD}, }; for (i = 0; i < ARRAY_SIZE(program_seq); i++) z_writeb(program_seq[i].value, ioaddr + program_seq[i].offset); } for (i = 0; i < 16; i++) { SA_prom[i] = z_readb(ioaddr + NE_DATAPORT); (void)z_readb(ioaddr + NE_DATAPORT); } /* We must set the 8390 for word mode. */ z_writeb(0x49, ioaddr + NE_EN0_DCFG); start_page = NESM_START_PG; stop_page = NESM_STOP_PG; dev->base_addr = (unsigned long)ioaddr; dev->irq = IRQ_AMIGA_PORTS; /* Install the Interrupt handler */ i = request_irq(IRQ_AMIGA_PORTS, __ei_interrupt, IRQF_SHARED, DRV_NAME, dev); if (i) return i; for (i = 0; i < ETH_ALEN; i++) dev->dev_addr[i] = SA_prom[i]; pr_debug("Found ethernet address: %pM\n", dev->dev_addr); ei_status.name = name; ei_status.tx_start_page = start_page; ei_status.stop_page = stop_page; ei_status.word16 = 1; ei_status.rx_start_page = start_page + TX_PAGES; ei_status.reset_8390 = zorro8390_reset_8390; ei_status.block_input = zorro8390_block_input; ei_status.block_output = zorro8390_block_output; ei_status.get_8390_hdr = zorro8390_get_8390_hdr; ei_status.reg_offset = zorro8390_offsets; dev->netdev_ops = &zorro8390_netdev_ops; __NS8390_init(dev, 0); ei_local->msg_enable = zorro8390_msg_enable; err = register_netdev(dev); if (err) { free_irq(IRQ_AMIGA_PORTS, dev); return err; } netdev_info(dev, "%s at 0x%08lx, Ethernet Address %pM\n", name, board, dev->dev_addr); return 0; }
/* The EL3 interrupt handler. */ static irqreturn_t el3_interrupt(int irq, void *dev_id) { struct net_device *dev = (struct net_device *) dev_id; struct el3_private *lp = netdev_priv(dev); unsigned int ioaddr; __u16 status; int i = 0, handled = 1; if (!netif_device_present(dev)) return IRQ_NONE; ioaddr = dev->base_addr; netdev_dbg(dev, "interrupt, status %4.4x.\n", inw(ioaddr + EL3_STATUS)); spin_lock(&lp->lock); while ((status = inw(ioaddr + EL3_STATUS)) & (IntLatch | RxComplete | StatsFull)) { if ((status & 0xe000) != 0x2000) { netdev_dbg(dev, "interrupt from dead card\n"); handled = 0; break; } if (status & RxComplete) el3_rx(dev); if (status & TxAvailable) { netdev_dbg(dev, " TX room bit was handled.\n"); /* There's room in the FIFO for a full-sized packet. */ outw(AckIntr | TxAvailable, ioaddr + EL3_CMD); netif_wake_queue(dev); } if (status & TxComplete) pop_tx_status(dev); if (status & (AdapterFailure | RxEarly | StatsFull)) { /* Handle all uncommon interrupts. */ if (status & StatsFull) /* Empty statistics. */ update_stats(dev); if (status & RxEarly) { /* Rx early is unused. */ el3_rx(dev); outw(AckIntr | RxEarly, ioaddr + EL3_CMD); } if (status & AdapterFailure) { u16 fifo_diag; EL3WINDOW(4); fifo_diag = inw(ioaddr + 4); EL3WINDOW(1); netdev_warn(dev, "adapter failure, FIFO diagnostic register %04x.\n", fifo_diag); if (fifo_diag & 0x0400) { /* Tx overrun */ tc589_wait_for_completion(dev, TxReset); outw(TxEnable, ioaddr + EL3_CMD); } if (fifo_diag & 0x2000) { /* Rx underrun */ tc589_wait_for_completion(dev, RxReset); set_rx_mode(dev); outw(RxEnable, ioaddr + EL3_CMD); } outw(AckIntr | AdapterFailure, ioaddr + EL3_CMD); } } if (++i > 10) { netdev_err(dev, "infinite loop in interrupt, status %4.4x.\n", status); /* Clear all interrupts */ outw(AckIntr | 0xFF, ioaddr + EL3_CMD); break; } /* Acknowledge the IRQ. */ outw(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD); } lp->last_irq = jiffies; spin_unlock(&lp->lock); netdev_dbg(dev, "exiting interrupt, status %4.4x.\n", inw(ioaddr + EL3_STATUS)); return IRQ_RETVAL(handled); }
int rtllib_rx_ADDBAReq(struct rtllib_device *ieee, struct sk_buff *skb) { struct rtllib_hdr_3addr *req = NULL; u16 rc = 0; u8 *dst = NULL, *pDialogToken = NULL, *tag = NULL; struct ba_record *pBA = NULL; union ba_param_set *pBaParamSet = NULL; u16 *pBaTimeoutVal = NULL; union sequence_control *pBaStartSeqCtrl = NULL; struct rx_ts_record *pTS = NULL; if (skb->len < sizeof(struct rtllib_hdr_3addr) + 9) { netdev_warn(ieee->dev, "Invalid skb len in BAREQ(%d / %d)\n", (int)skb->len, (int)(sizeof(struct rtllib_hdr_3addr) + 9)); return -1; } #ifdef VERBOSE_DEBUG print_hex_dump_bytes("rtllib_rx_ADDBAReq(): ", DUMP_PREFIX_NONE, skb->data, skb->len); #endif req = (struct rtllib_hdr_3addr *) skb->data; tag = (u8 *)req; dst = (u8 *)(&req->addr2[0]); tag += sizeof(struct rtllib_hdr_3addr); pDialogToken = tag + 2; pBaParamSet = (union ba_param_set *)(tag + 3); pBaTimeoutVal = (u16 *)(tag + 5); pBaStartSeqCtrl = (union sequence_control *)(req + 7); RT_TRACE(COMP_DBG, "====>rx ADDBAREQ from : %pM\n", dst); if (ieee->current_network.qos_data.active == 0 || (ieee->pHTInfo->bCurrentHTSupport == false) || (ieee->pHTInfo->IOTAction & HT_IOT_ACT_REJECT_ADDBA_REQ)) { rc = ADDBA_STATUS_REFUSED; netdev_warn(ieee->dev, "Failed to reply on ADDBA_REQ as some capability is not ready(%d, %d)\n", ieee->current_network.qos_data.active, ieee->pHTInfo->bCurrentHTSupport); goto OnADDBAReq_Fail; } if (!GetTs(ieee, (struct ts_common_info **)(&pTS), dst, (u8)(pBaParamSet->field.TID), RX_DIR, true)) { rc = ADDBA_STATUS_REFUSED; netdev_warn(ieee->dev, "%s(): can't get TS\n", __func__); goto OnADDBAReq_Fail; } pBA = &pTS->RxAdmittedBARecord; if (pBaParamSet->field.BAPolicy == BA_POLICY_DELAYED) { rc = ADDBA_STATUS_INVALID_PARAM; netdev_warn(ieee->dev, "%s(): BA Policy is not correct\n", __func__); goto OnADDBAReq_Fail; } rtllib_FlushRxTsPendingPkts(ieee, pTS); DeActivateBAEntry(ieee, pBA); pBA->DialogToken = *pDialogToken; pBA->BaParamSet = *pBaParamSet; pBA->BaTimeoutValue = *pBaTimeoutVal; pBA->BaStartSeqCtrl = *pBaStartSeqCtrl; if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev) || (ieee->pHTInfo->IOTAction & HT_IOT_ACT_ALLOW_PEER_AGG_ONE_PKT)) pBA->BaParamSet.field.BufferSize = 1; else pBA->BaParamSet.field.BufferSize = 32; ActivateBAEntry(ieee, pBA, 0); rtllib_send_ADDBARsp(ieee, dst, pBA, ADDBA_STATUS_SUCCESS); return 0; OnADDBAReq_Fail: { struct ba_record BA; BA.BaParamSet = *pBaParamSet; BA.BaTimeoutValue = *pBaTimeoutVal; BA.DialogToken = *pDialogToken; BA.BaParamSet.field.BAPolicy = BA_POLICY_IMMEDIATE; rtllib_send_ADDBARsp(ieee, dst, &BA, rc); return 0; } }
static int smsc95xx_reset(struct usbnet *dev) { struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); u32 read_buf, write_buf, burst_cap = 0; int ret = 0, timeout; netif_dbg(dev, ifup, dev->net, "entering %s\n", __func__); write_buf = HW_CFG_LRST_; ret = smsc95xx_write_reg(dev, HW_CFG, write_buf); if (ret < 0) { netdev_warn(dev->net, "Failed to write HW_CFG_LRST_ bit in HW_CFG register, ret = %d\n", ret); return ret; } timeout = 0; do { ret = smsc95xx_read_reg(dev, HW_CFG, &read_buf); if (ret < 0) { netdev_warn(dev->net, "Failed to read HW_CFG: %d\n", ret); return ret; } udelay(1000 * 10); timeout++; } while ((read_buf & HW_CFG_LRST_) && (timeout < 100)); if (timeout >= 100) { netdev_warn(dev->net, "timeout waiting for completion of Lite Reset\n"); return ret; } write_buf = PM_CTL_PHY_RST_; ret = smsc95xx_write_reg(dev, PM_CTRL, write_buf); if (ret < 0) { netdev_warn(dev->net, "Failed to write PM_CTRL: %d\n", ret); return ret; } timeout = 0; do { ret = smsc95xx_read_reg(dev, PM_CTRL, &read_buf); if (ret < 0) { netdev_warn(dev->net, "Failed to read PM_CTRL: %d\n", ret); return ret; } udelay(1000 * 10); timeout++; } while ((read_buf & PM_CTL_PHY_RST_) && (timeout < 100)); if (timeout >= 100) { netdev_warn(dev->net, "timeout waiting for PHY Reset\n"); return ret; } ret = smsc95xx_read_reg(dev, HW_CFG, &read_buf); if (ret < 0) { netdev_warn(dev->net, "Failed to read HW_CFG: %d\n", ret); return ret; } netif_dbg(dev, ifup, dev->net, "Read Value from HW_CFG : 0x%08x\n", read_buf); read_buf |= HW_CFG_BIR_; ret = smsc95xx_write_reg(dev, HW_CFG, read_buf); if (ret < 0) { netdev_warn(dev->net, "Failed to write HW_CFG_BIR_ bit in HW_CFG register, ret = %d\n", ret); return ret; } ret = smsc95xx_read_reg(dev, HW_CFG, &read_buf); if (ret < 0) { netdev_warn(dev->net, "Failed to read HW_CFG: %d\n", ret); return ret; } netif_dbg(dev, ifup, dev->net, "Read Value from HW_CFG after writing HW_CFG_BIR_: 0x%08x\n", read_buf); if (!turbo_mode) { burst_cap = 0; dev->rx_urb_size = MAX_SINGLE_PACKET_SIZE; } else if (0) { /* highspeed */ burst_cap = DEFAULT_HS_BURST_CAP_SIZE / HS_USB_PKT_SIZE; dev->rx_urb_size = DEFAULT_HS_BURST_CAP_SIZE; } else { burst_cap = DEFAULT_FS_BURST_CAP_SIZE / FS_USB_PKT_SIZE; dev->rx_urb_size = DEFAULT_FS_BURST_CAP_SIZE; } netif_dbg(dev, ifup, dev->net, "rx_urb_size=%ld\n", (ulong)dev->rx_urb_size); ret = smsc95xx_write_reg(dev, BURST_CAP, burst_cap); if (ret < 0) { netdev_warn(dev->net, "Failed to write BURST_CAP: %d\n", ret); return ret; } ret = smsc95xx_read_reg(dev, BURST_CAP, &read_buf); if (ret < 0) { netdev_warn(dev->net, "Failed to read BURST_CAP: %d\n", ret); return ret; } netif_dbg(dev, ifup, dev->net, "Read Value from BURST_CAP after writing: 0x%08x\n", read_buf); read_buf = DEFAULT_BULK_IN_DELAY; ret = smsc95xx_write_reg(dev, BULK_IN_DLY, read_buf); if (ret < 0) { netdev_warn(dev->net, "ret = %d\n", ret); return ret; } ret = smsc95xx_read_reg(dev, BULK_IN_DLY, &read_buf); if (ret < 0) { netdev_warn(dev->net, "Failed to read BULK_IN_DLY: %d\n", ret); return ret; } netif_dbg(dev, ifup, dev->net, "Read Value from BULK_IN_DLY after writing: 0x%08x\n", read_buf); ret = smsc95xx_read_reg(dev, HW_CFG, &read_buf); if (ret < 0) { netdev_warn(dev->net, "Failed to read HW_CFG: %d\n", ret); return ret; } netif_dbg(dev, ifup, dev->net, "Read Value from HW_CFG: 0x%08x\n", read_buf); if (turbo_mode) read_buf |= (HW_CFG_MEF_ | HW_CFG_BCE_); read_buf &= ~HW_CFG_RXDOFF_; /* set Rx data offset=2, Make IP header aligns on word boundary. */ read_buf |= NET_IP_ALIGN << 9; ret = smsc95xx_write_reg(dev, HW_CFG, read_buf); if (ret < 0) { netdev_warn(dev->net, "Failed to write HW_CFG register, ret=%d\n", ret); return ret; } ret = smsc95xx_read_reg(dev, HW_CFG, &read_buf); if (ret < 0) { netdev_warn(dev->net, "Failed to read HW_CFG: %d\n", ret); return ret; } netif_dbg(dev, ifup, dev->net, "Read Value from HW_CFG after writing: 0x%08x\n", read_buf); write_buf = 0xFFFFFFFF; ret = smsc95xx_write_reg(dev, INT_STS, write_buf); if (ret < 0) { netdev_warn(dev->net, "Failed to write INT_STS register, ret=%d\n", ret); return ret; } ret = smsc95xx_read_reg(dev, ID_REV, &read_buf); if (ret < 0) { netdev_warn(dev->net, "Failed to read ID_REV: %d\n", ret); return ret; } netif_dbg(dev, ifup, dev->net, "ID_REV = 0x%08x\n", read_buf); /* Configure GPIO pins as LED outputs */ write_buf = LED_GPIO_CFG_SPD_LED | LED_GPIO_CFG_LNK_LED | LED_GPIO_CFG_FDX_LED; ret = smsc95xx_write_reg(dev, LED_GPIO_CFG, write_buf); if (ret < 0) { netdev_warn(dev->net, "Failed to write LED_GPIO_CFG register, ret=%d\n", ret); return ret; } /* Init Tx */ write_buf = 0; ret = smsc95xx_write_reg(dev, FLOW, write_buf); if (ret < 0) { netdev_warn(dev->net, "Failed to write FLOW: %d\n", ret); return ret; } read_buf = AFC_CFG_DEFAULT; ret = smsc95xx_write_reg(dev, AFC_CFG, read_buf); if (ret < 0) { netdev_warn(dev->net, "Failed to write AFC_CFG: %d\n", ret); return ret; } /* Don't need mac_cr_lock during initialisation */ ret = smsc95xx_read_reg(dev, MAC_CR, &pdata->mac_cr); if (ret < 0) { netdev_warn(dev->net, "Failed to read MAC_CR: %d\n", ret); return ret; } /* Init Rx */ /* Set Vlan */ write_buf = (u32)ETH_P_8021Q; ret = smsc95xx_write_reg(dev, VLAN1, write_buf); if (ret < 0) { netdev_warn(dev->net, "Failed to write VAN1: %d\n", ret); return ret; } ret = smsc95xx_set_csums(dev); if (ret < 0) { netdev_warn(dev->net, "Failed to set csum offload: %d\n", ret); return ret; } smsc95xx_set_multicast(dev); if (smsc95xx_phy_initialize(dev) < 0) return -EIO; ret = smsc95xx_read_reg(dev, INT_EP_CTL, &read_buf); if (ret < 0) { netdev_warn(dev->net, "Failed to read INT_EP_CTL: %d\n", ret); return ret; } /* enable PHY interrupts */ read_buf |= INT_EP_CTL_PHY_INT_; ret = smsc95xx_write_reg(dev, INT_EP_CTL, read_buf); if (ret < 0) { netdev_warn(dev->net, "Failed to write INT_EP_CTL: %d\n", ret); return ret; } smsc95xx_start_tx_path(dev); smsc95xx_start_rx_path(dev); netif_dbg(dev, ifup, dev->net, "%s: return 0\n", __func__); return 0; }
int rtllib_rx_ADDBARsp(struct rtllib_device *ieee, struct sk_buff *skb) { struct rtllib_hdr_3addr *rsp = NULL; struct ba_record *pPendingBA, *pAdmittedBA; struct tx_ts_record *pTS = NULL; u8 *dst = NULL, *pDialogToken = NULL, *tag = NULL; u16 *pStatusCode = NULL, *pBaTimeoutVal = NULL; union ba_param_set *pBaParamSet = NULL; u16 ReasonCode; if (skb->len < sizeof(struct rtllib_hdr_3addr) + 9) { netdev_warn(ieee->dev, "Invalid skb len in BARSP(%d / %d)\n", (int)skb->len, (int)(sizeof(struct rtllib_hdr_3addr) + 9)); return -1; } rsp = (struct rtllib_hdr_3addr *)skb->data; tag = (u8 *)rsp; dst = (u8 *)(&rsp->addr2[0]); tag += sizeof(struct rtllib_hdr_3addr); pDialogToken = tag + 2; pStatusCode = (u16 *)(tag + 3); pBaParamSet = (union ba_param_set *)(tag + 5); pBaTimeoutVal = (u16 *)(tag + 7); RT_TRACE(COMP_DBG, "====>rx ADDBARSP from : %pM\n", dst); if (ieee->current_network.qos_data.active == 0 || ieee->pHTInfo->bCurrentHTSupport == false || ieee->pHTInfo->bCurrentAMPDUEnable == false) { netdev_warn(ieee->dev, "reject to ADDBA_RSP as some capability is not ready(%d, %d, %d)\n", ieee->current_network.qos_data.active, ieee->pHTInfo->bCurrentHTSupport, ieee->pHTInfo->bCurrentAMPDUEnable); ReasonCode = DELBA_REASON_UNKNOWN_BA; goto OnADDBARsp_Reject; } if (!GetTs(ieee, (struct ts_common_info **)(&pTS), dst, (u8)(pBaParamSet->field.TID), TX_DIR, false)) { netdev_warn(ieee->dev, "%s(): can't get TS\n", __func__); ReasonCode = DELBA_REASON_UNKNOWN_BA; goto OnADDBARsp_Reject; } pTS->bAddBaReqInProgress = false; pPendingBA = &pTS->TxPendingBARecord; pAdmittedBA = &pTS->TxAdmittedBARecord; if (pAdmittedBA->bValid == true) { netdev_dbg(ieee->dev, "%s(): ADDBA response already admitted\n", __func__); return -1; } else if ((pPendingBA->bValid == false) || (*pDialogToken != pPendingBA->DialogToken)) { netdev_warn(ieee->dev, "%s(): ADDBA Rsp. BA invalid, DELBA!\n", __func__); ReasonCode = DELBA_REASON_UNKNOWN_BA; goto OnADDBARsp_Reject; } else { netdev_dbg(ieee->dev, "%s(): Recv ADDBA Rsp. BA is admitted! Status code:%X\n", __func__, *pStatusCode); DeActivateBAEntry(ieee, pPendingBA); } if (*pStatusCode == ADDBA_STATUS_SUCCESS) { if (pBaParamSet->field.BAPolicy == BA_POLICY_DELAYED) { pTS->bAddBaReqDelayed = true; DeActivateBAEntry(ieee, pAdmittedBA); ReasonCode = DELBA_REASON_END_BA; goto OnADDBARsp_Reject; } pAdmittedBA->DialogToken = *pDialogToken; pAdmittedBA->BaTimeoutValue = *pBaTimeoutVal; pAdmittedBA->BaStartSeqCtrl = pPendingBA->BaStartSeqCtrl; pAdmittedBA->BaParamSet = *pBaParamSet; DeActivateBAEntry(ieee, pAdmittedBA); ActivateBAEntry(ieee, pAdmittedBA, *pBaTimeoutVal); } else { pTS->bAddBaReqDelayed = true; pTS->bDisable_AddBa = true; ReasonCode = DELBA_REASON_END_BA; goto OnADDBARsp_Reject; } return 0; OnADDBARsp_Reject: { struct ba_record BA; BA.BaParamSet = *pBaParamSet; rtllib_send_DELBA(ieee, dst, &BA, TX_DIR, ReasonCode); return 0; } }
static int qlcnic_set_led(struct net_device *dev, enum ethtool_phys_id_state state) { struct qlcnic_adapter *adapter = netdev_priv(dev); int max_sds_rings = adapter->max_sds_rings; int err = -EIO, active = 1; if (qlcnic_83xx_check(adapter)) return qlcnic_83xx_set_led(dev, state); if (adapter->ahw->op_mode == QLCNIC_NON_PRIV_FUNC) { netdev_warn(dev, "LED test not supported for non " "privilege function\n"); return -EOPNOTSUPP; } switch (state) { case ETHTOOL_ID_ACTIVE: if (test_and_set_bit(__QLCNIC_LED_ENABLE, &adapter->state)) return -EBUSY; if (test_bit(__QLCNIC_RESETTING, &adapter->state)) break; if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) { if (qlcnic_diag_alloc_res(dev, QLCNIC_LED_TEST)) break; set_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state); } if (adapter->nic_ops->config_led(adapter, 1, 0xf) == 0) { err = 0; break; } dev_err(&adapter->pdev->dev, "Failed to set LED blink state.\n"); break; case ETHTOOL_ID_INACTIVE: active = 0; if (test_bit(__QLCNIC_RESETTING, &adapter->state)) break; if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) { if (qlcnic_diag_alloc_res(dev, QLCNIC_LED_TEST)) break; set_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state); } if (adapter->nic_ops->config_led(adapter, 0, 0xf)) dev_err(&adapter->pdev->dev, "Failed to reset LED blink state.\n"); break; default: return -EINVAL; } if (test_and_clear_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state)) qlcnic_diag_free_res(dev, max_sds_rings); if (!active || err) clear_bit(__QLCNIC_LED_ENABLE, &adapter->state); return err; }
int rtllib_rx_DELBA(struct rtllib_device *ieee, struct sk_buff *skb) { struct rtllib_hdr_3addr *delba = NULL; union delba_param_set *pDelBaParamSet = NULL; u16 *pReasonCode = NULL; u8 *dst = NULL; if (skb->len < sizeof(struct rtllib_hdr_3addr) + 6) { netdev_warn(ieee->dev, "Invalid skb len in DELBA(%d / %d)\n", (int)skb->len, (int)(sizeof(struct rtllib_hdr_3addr) + 6)); return -1; } if (ieee->current_network.qos_data.active == 0 || ieee->pHTInfo->bCurrentHTSupport == false) { netdev_warn(ieee->dev, "received DELBA while QOS or HT is not supported(%d, %d)\n", ieee->current_network. qos_data.active, ieee->pHTInfo->bCurrentHTSupport); return -1; } #ifdef VERBOSE_DEBUG print_hex_dump_bytes("rtllib_rx_DELBA(): ", DUMP_PREFIX_NONE, skb->data, skb->len); #endif delba = (struct rtllib_hdr_3addr *)skb->data; dst = (u8 *)(&delba->addr2[0]); delba += sizeof(struct rtllib_hdr_3addr); pDelBaParamSet = (union delba_param_set *)(delba+2); pReasonCode = (u16 *)(delba+4); if (pDelBaParamSet->field.Initiator == 1) { struct rx_ts_record *pRxTs; if (!GetTs(ieee, (struct ts_common_info **)&pRxTs, dst, (u8)pDelBaParamSet->field.TID, RX_DIR, false)) { netdev_warn(ieee->dev, "%s(): can't get TS for RXTS. dst:%pM TID:%d\n", __func__, dst, (u8)pDelBaParamSet->field.TID); return -1; } RxTsDeleteBA(ieee, pRxTs); } else { struct tx_ts_record *pTxTs; if (!GetTs(ieee, (struct ts_common_info **)&pTxTs, dst, (u8)pDelBaParamSet->field.TID, TX_DIR, false)) { netdev_warn(ieee->dev, "%s(): can't get TS for TXTS\n", __func__); return -1; } pTxTs->bUsingBa = false; pTxTs->bAddBaReqInProgress = false; pTxTs->bAddBaReqDelayed = false; del_timer_sync(&pTxTs->TsAddBaTimer); TxTsDeleteBA(ieee, pTxTs); } return 0; }
/* Send close command to device */ static int usb_8dev_cmd_close(struct usb_8dev_priv *priv) { struct usb_8dev_cmd_msg inmsg; struct usb_8dev_cmd_msg outmsg = { .channel = 0, .command = USB_8DEV_CLOSE, .opt1 = 0, .opt2 = 0 }; return usb_8dev_send_cmd(priv, &outmsg, &inmsg); } /* Get firmware and hardware version */ static int usb_8dev_cmd_version(struct usb_8dev_priv *priv, u32 *res) { struct usb_8dev_cmd_msg inmsg; struct usb_8dev_cmd_msg outmsg = { .channel = 0, .command = USB_8DEV_GET_SOFTW_HARDW_VER, .opt1 = 0, .opt2 = 0 }; int err = usb_8dev_send_cmd(priv, &outmsg, &inmsg); if (err) return err; *res = be32_to_cpup((__be32 *)inmsg.data); return err; } /* Set network device mode * * Maybe we should leave this function empty, because the device * set mode variable with open command. */ static int usb_8dev_set_mode(struct net_device *netdev, enum can_mode mode) { struct usb_8dev_priv *priv = netdev_priv(netdev); int err = 0; switch (mode) { case CAN_MODE_START: err = usb_8dev_cmd_open(priv); if (err) netdev_warn(netdev, "couldn't start device"); break; default: return -EOPNOTSUPP; } return err; } /* Read error/status frames */ static void usb_8dev_rx_err_msg(struct usb_8dev_priv *priv, struct usb_8dev_rx_msg *msg) { struct can_frame *cf; struct sk_buff *skb; struct net_device_stats *stats = &priv->netdev->stats; /* Error message: * byte 0: Status * byte 1: bit 7: Receive Passive * byte 1: bit 0-6: Receive Error Counter * byte 2: Transmit Error Counter * byte 3: Always 0 (maybe reserved for future use) */ u8 state = msg->data[0]; u8 rxerr = msg->data[1] & USB_8DEV_RP_MASK; u8 txerr = msg->data[2]; int rx_errors = 0; int tx_errors = 0; skb = alloc_can_err_skb(priv->netdev, &cf); if (!skb) return; switch (state) { case USB_8DEV_STATUSMSG_OK: priv->can.state = CAN_STATE_ERROR_ACTIVE; cf->can_id |= CAN_ERR_PROT; cf->data[2] = CAN_ERR_PROT_ACTIVE; break; case USB_8DEV_STATUSMSG_BUSOFF: priv->can.state = CAN_STATE_BUS_OFF; cf->can_id |= CAN_ERR_BUSOFF; can_bus_off(priv->netdev); break; case USB_8DEV_STATUSMSG_OVERRUN: case USB_8DEV_STATUSMSG_BUSLIGHT: case USB_8DEV_STATUSMSG_BUSHEAVY: cf->can_id |= CAN_ERR_CRTL; break; default: priv->can.state = CAN_STATE_ERROR_WARNING; cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR; priv->can.can_stats.bus_error++; break; } switch (state) { case USB_8DEV_STATUSMSG_OK: case USB_8DEV_STATUSMSG_BUSOFF: break; case USB_8DEV_STATUSMSG_ACK: cf->can_id |= CAN_ERR_ACK; tx_errors = 1; break; case USB_8DEV_STATUSMSG_CRC: cf->data[2] |= CAN_ERR_PROT_UNSPEC; cf->data[3] |= CAN_ERR_PROT_LOC_CRC_SEQ | CAN_ERR_PROT_LOC_CRC_DEL; rx_errors = 1; break; case USB_8DEV_STATUSMSG_BIT0: cf->data[2] |= CAN_ERR_PROT_BIT0; tx_errors = 1; break; case USB_8DEV_STATUSMSG_BIT1: cf->data[2] |= CAN_ERR_PROT_BIT1; tx_errors = 1; break; case USB_8DEV_STATUSMSG_FORM: cf->data[2] |= CAN_ERR_PROT_FORM; rx_errors = 1; break; case USB_8DEV_STATUSMSG_STUFF: cf->data[2] |= CAN_ERR_PROT_STUFF; rx_errors = 1; break; case USB_8DEV_STATUSMSG_OVERRUN: cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW; stats->rx_over_errors++; rx_errors = 1; break; case USB_8DEV_STATUSMSG_BUSLIGHT: priv->can.state = CAN_STATE_ERROR_WARNING; cf->data[1] = (txerr > rxerr) ? CAN_ERR_CRTL_TX_WARNING : CAN_ERR_CRTL_RX_WARNING; priv->can.can_stats.error_warning++; break; case USB_8DEV_STATUSMSG_BUSHEAVY: priv->can.state = CAN_STATE_ERROR_PASSIVE; cf->data[1] = (txerr > rxerr) ? CAN_ERR_CRTL_TX_PASSIVE : CAN_ERR_CRTL_RX_PASSIVE; priv->can.can_stats.error_passive++; break; default: netdev_warn(priv->netdev, "Unknown status/error message (%d)\n", state); break; } if (tx_errors) { cf->data[2] |= CAN_ERR_PROT_TX; stats->tx_errors++; } if (rx_errors) stats->rx_errors++; cf->data[6] = txerr; cf->data[7] = rxerr; priv->bec.txerr = txerr; priv->bec.rxerr = rxerr; netif_rx(skb); stats->rx_packets++; stats->rx_bytes += cf->can_dlc; } /* Read data and status frames */ static void usb_8dev_rx_can_msg(struct usb_8dev_priv *priv, struct usb_8dev_rx_msg *msg) { struct can_frame *cf; struct sk_buff *skb; struct net_device_stats *stats = &priv->netdev->stats; if (msg->type == USB_8DEV_TYPE_ERROR_FRAME && msg->flags == USB_8DEV_ERR_FLAG) { usb_8dev_rx_err_msg(priv, msg); } else if (msg->type == USB_8DEV_TYPE_CAN_FRAME) { skb = alloc_can_skb(priv->netdev, &cf); if (!skb) return; cf->can_id = be32_to_cpu(msg->id); cf->can_dlc = get_can_dlc(msg->dlc & 0xF); if (msg->flags & USB_8DEV_EXTID) cf->can_id |= CAN_EFF_FLAG; if (msg->flags & USB_8DEV_RTR) cf->can_id |= CAN_RTR_FLAG; else memcpy(cf->data, msg->data, cf->can_dlc); netif_rx(skb); stats->rx_packets++; stats->rx_bytes += cf->can_dlc; can_led_event(priv->netdev, CAN_LED_EVENT_RX); } else { netdev_warn(priv->netdev, "frame type %d unknown", msg->type); } } /* Callback for reading data from device * * Check urb status, call read function and resubmit urb read operation. */ static void usb_8dev_read_bulk_callback(struct urb *urb) { struct usb_8dev_priv *priv = urb->context; struct net_device *netdev; int retval; int pos = 0; netdev = priv->netdev; if (!netif_device_present(netdev)) return; switch (urb->status) { case 0: /* success */ break; case -ENOENT: case -ESHUTDOWN: return; default: netdev_info(netdev, "Rx URB aborted (%d)\n", urb->status); goto resubmit_urb; } while (pos < urb->actual_length) { struct usb_8dev_rx_msg *msg; if (pos + sizeof(struct usb_8dev_rx_msg) > urb->actual_length) { netdev_err(priv->netdev, "format error\n"); break; } msg = (struct usb_8dev_rx_msg *)(urb->transfer_buffer + pos); usb_8dev_rx_can_msg(priv, msg); pos += sizeof(struct usb_8dev_rx_msg); } resubmit_urb: usb_fill_bulk_urb(urb, priv->udev, usb_rcvbulkpipe(priv->udev, USB_8DEV_ENDP_DATA_RX), urb->transfer_buffer, RX_BUFFER_SIZE, usb_8dev_read_bulk_callback, priv); retval = usb_submit_urb(urb, GFP_ATOMIC); if (retval == -ENODEV) netif_device_detach(netdev); else if (retval) netdev_err(netdev, "failed resubmitting read bulk urb: %d\n", retval); } /* Callback handler for write operations * * Free allocated buffers, check transmit status and * calculate statistic. */ static void usb_8dev_write_bulk_callback(struct urb *urb) { struct usb_8dev_tx_urb_context *context = urb->context; struct usb_8dev_priv *priv; struct net_device *netdev; BUG_ON(!context); priv = context->priv; netdev = priv->netdev; /* free up our allocated buffer */ usb_free_coherent(urb->dev, urb->transfer_buffer_length, urb->transfer_buffer, urb->transfer_dma); atomic_dec(&priv->active_tx_urbs); if (!netif_device_present(netdev)) return; if (urb->status) netdev_info(netdev, "Tx URB aborted (%d)\n", urb->status); netdev->stats.tx_packets++; netdev->stats.tx_bytes += context->dlc; can_get_echo_skb(netdev, context->echo_index); can_led_event(netdev, CAN_LED_EVENT_TX); /* Release context */ context->echo_index = MAX_TX_URBS; netif_wake_queue(netdev); } /* Send data to device */ static netdev_tx_t usb_8dev_start_xmit(struct sk_buff *skb, struct net_device *netdev) { struct usb_8dev_priv *priv = netdev_priv(netdev); struct net_device_stats *stats = &netdev->stats; struct can_frame *cf = (struct can_frame *) skb->data; struct usb_8dev_tx_msg *msg; struct urb *urb; struct usb_8dev_tx_urb_context *context = NULL; u8 *buf; int i, err; size_t size = sizeof(struct usb_8dev_tx_msg); if (can_dropped_invalid_skb(netdev, skb)) return NETDEV_TX_OK; /* create a URB, and a buffer for it, and copy the data to the URB */ urb = usb_alloc_urb(0, GFP_ATOMIC); if (!urb) { netdev_err(netdev, "No memory left for URBs\n"); goto nomem; } buf = usb_alloc_coherent(priv->udev, size, GFP_ATOMIC, &urb->transfer_dma); if (!buf) { netdev_err(netdev, "No memory left for USB buffer\n"); goto nomembuf; } memset(buf, 0, size); msg = (struct usb_8dev_tx_msg *)buf; msg->begin = USB_8DEV_DATA_START; msg->flags = 0x00; if (cf->can_id & CAN_RTR_FLAG) msg->flags |= USB_8DEV_RTR; if (cf->can_id & CAN_EFF_FLAG) msg->flags |= USB_8DEV_EXTID; msg->id = cpu_to_be32(cf->can_id & CAN_ERR_MASK); msg->dlc = cf->can_dlc; memcpy(msg->data, cf->data, cf->can_dlc); msg->end = USB_8DEV_DATA_END; for (i = 0; i < MAX_TX_URBS; i++) { if (priv->tx_contexts[i].echo_index == MAX_TX_URBS) { context = &priv->tx_contexts[i]; break; } } /* May never happen! When this happens we'd more URBs in flight as * allowed (MAX_TX_URBS). */ if (!context) goto nofreecontext; context->priv = priv; context->echo_index = i; context->dlc = cf->can_dlc; usb_fill_bulk_urb(urb, priv->udev, usb_sndbulkpipe(priv->udev, USB_8DEV_ENDP_DATA_TX), buf, size, usb_8dev_write_bulk_callback, context); urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; usb_anchor_urb(urb, &priv->tx_submitted); can_put_echo_skb(skb, netdev, context->echo_index); atomic_inc(&priv->active_tx_urbs); err = usb_submit_urb(urb, GFP_ATOMIC); if (unlikely(err)) goto failed; else if (atomic_read(&priv->active_tx_urbs) >= MAX_TX_URBS) /* Slow down tx path */ netif_stop_queue(netdev); /* Release our reference to this URB, the USB core will eventually free * it entirely. */ usb_free_urb(urb); return NETDEV_TX_OK; nofreecontext: usb_free_coherent(priv->udev, size, buf, urb->transfer_dma); usb_free_urb(urb); netdev_warn(netdev, "couldn't find free context"); return NETDEV_TX_BUSY; failed: can_free_echo_skb(netdev, context->echo_index); usb_unanchor_urb(urb); usb_free_coherent(priv->udev, size, buf, urb->transfer_dma); atomic_dec(&priv->active_tx_urbs); if (err == -ENODEV) netif_device_detach(netdev); else netdev_warn(netdev, "failed tx_urb %d\n", err); nomembuf: usb_free_urb(urb); nomem: dev_kfree_skb(skb); stats->tx_dropped++; return NETDEV_TX_OK; } static int usb_8dev_get_berr_counter(const struct net_device *netdev, struct can_berr_counter *bec) { struct usb_8dev_priv *priv = netdev_priv(netdev); bec->txerr = priv->bec.txerr; bec->rxerr = priv->bec.rxerr; return 0; } /* Start USB device */ static int usb_8dev_start(struct usb_8dev_priv *priv) { struct net_device *netdev = priv->netdev; int err, i; for (i = 0; i < MAX_RX_URBS; i++) { struct urb *urb = NULL; u8 *buf; /* create a URB, and a buffer for it */ urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) { netdev_err(netdev, "No memory left for URBs\n"); err = -ENOMEM; break; } buf = usb_alloc_coherent(priv->udev, RX_BUFFER_SIZE, GFP_KERNEL, &urb->transfer_dma); if (!buf) { netdev_err(netdev, "No memory left for USB buffer\n"); usb_free_urb(urb); err = -ENOMEM; break; } usb_fill_bulk_urb(urb, priv->udev, usb_rcvbulkpipe(priv->udev, USB_8DEV_ENDP_DATA_RX), buf, RX_BUFFER_SIZE, usb_8dev_read_bulk_callback, priv); urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; usb_anchor_urb(urb, &priv->rx_submitted); err = usb_submit_urb(urb, GFP_KERNEL); if (err) { usb_unanchor_urb(urb); usb_free_coherent(priv->udev, RX_BUFFER_SIZE, buf, urb->transfer_dma); usb_free_urb(urb); break; } /* Drop reference, USB core will take care of freeing it */ usb_free_urb(urb); } /* Did we submit any URBs */ if (i == 0) { netdev_warn(netdev, "couldn't setup read URBs\n"); return err; } /* Warn if we've couldn't transmit all the URBs */ if (i < MAX_RX_URBS) netdev_warn(netdev, "rx performance may be slow\n"); err = usb_8dev_cmd_open(priv); if (err) goto failed; priv->can.state = CAN_STATE_ERROR_ACTIVE; return 0; failed: if (err == -ENODEV) netif_device_detach(priv->netdev); netdev_warn(netdev, "couldn't submit control: %d\n", err); return err; } /* Open USB device */ static int usb_8dev_open(struct net_device *netdev) { struct usb_8dev_priv *priv = netdev_priv(netdev); int err; /* common open */ err = open_candev(netdev); if (err) return err; can_led_event(netdev, CAN_LED_EVENT_OPEN); /* finally start device */ err = usb_8dev_start(priv); if (err) { if (err == -ENODEV) netif_device_detach(priv->netdev); netdev_warn(netdev, "couldn't start device: %d\n", err); close_candev(netdev); return err; } netif_start_queue(netdev); return 0; } static void unlink_all_urbs(struct usb_8dev_priv *priv) { int i; usb_kill_anchored_urbs(&priv->rx_submitted); usb_kill_anchored_urbs(&priv->tx_submitted); atomic_set(&priv->active_tx_urbs, 0); for (i = 0; i < MAX_TX_URBS; i++) priv->tx_contexts[i].echo_index = MAX_TX_URBS; } /* Close USB device */ static int usb_8dev_close(struct net_device *netdev) { struct usb_8dev_priv *priv = netdev_priv(netdev); int err = 0; /* Send CLOSE command to CAN controller */ err = usb_8dev_cmd_close(priv); if (err) netdev_warn(netdev, "couldn't stop device"); priv->can.state = CAN_STATE_STOPPED; netif_stop_queue(netdev); /* Stop polling */ unlink_all_urbs(priv); close_candev(netdev); can_led_event(netdev, CAN_LED_EVENT_STOP); return err; } static const struct net_device_ops usb_8dev_netdev_ops = { .ndo_open = usb_8dev_open, .ndo_stop = usb_8dev_close, .ndo_start_xmit = usb_8dev_start_xmit, .ndo_change_mtu = can_change_mtu, }; static const struct can_bittiming_const usb_8dev_bittiming_const = { .name = "usb_8dev", .tseg1_min = 1, .tseg1_max = 16, .tseg2_min = 1, .tseg2_max = 8, .sjw_max = 4, .brp_min = 1, .brp_max = 1024, .brp_inc = 1, }; /* Probe USB device * * Check device and firmware. * Set supported modes and bittiming constants. * Allocate some memory. */ static int usb_8dev_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct net_device *netdev; struct usb_8dev_priv *priv; int i, err = -ENOMEM; u32 version; char buf[18]; struct usb_device *usbdev = interface_to_usbdev(intf); /* product id looks strange, better we also check iProduct string */ if (usb_string(usbdev, usbdev->descriptor.iProduct, buf, sizeof(buf)) > 0 && strcmp(buf, "USB2CAN converter")) { dev_info(&usbdev->dev, "ignoring: not an USB2CAN converter\n"); return -ENODEV; } netdev = alloc_candev(sizeof(struct usb_8dev_priv), MAX_TX_URBS); if (!netdev) { dev_err(&intf->dev, "Couldn't alloc candev\n"); return -ENOMEM; } priv = netdev_priv(netdev); priv->udev = usbdev; priv->netdev = netdev; priv->can.state = CAN_STATE_STOPPED; priv->can.clock.freq = USB_8DEV_ABP_CLOCK; priv->can.bittiming_const = &usb_8dev_bittiming_const; priv->can.do_set_mode = usb_8dev_set_mode; priv->can.do_get_berr_counter = usb_8dev_get_berr_counter; priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK | CAN_CTRLMODE_LISTENONLY | CAN_CTRLMODE_ONE_SHOT; netdev->netdev_ops = &usb_8dev_netdev_ops; netdev->flags |= IFF_ECHO; /* we support local echo */ init_usb_anchor(&priv->rx_submitted); init_usb_anchor(&priv->tx_submitted); atomic_set(&priv->active_tx_urbs, 0); for (i = 0; i < MAX_TX_URBS; i++) priv->tx_contexts[i].echo_index = MAX_TX_URBS; priv->cmd_msg_buffer = kzalloc(sizeof(struct usb_8dev_cmd_msg), GFP_KERNEL); if (!priv->cmd_msg_buffer) goto cleanup_candev; usb_set_intfdata(intf, priv); SET_NETDEV_DEV(netdev, &intf->dev); mutex_init(&priv->usb_8dev_cmd_lock); err = register_candev(netdev); if (err) { netdev_err(netdev, "couldn't register CAN device: %d\n", err); goto cleanup_cmd_msg_buffer; } err = usb_8dev_cmd_version(priv, &version); if (err) { netdev_err(netdev, "can't get firmware version\n"); goto cleanup_unregister_candev; } else { netdev_info(netdev, "firmware: %d.%d, hardware: %d.%d\n", (version>>24) & 0xff, (version>>16) & 0xff, (version>>8) & 0xff, version & 0xff); } devm_can_led_init(netdev); return 0; cleanup_unregister_candev: unregister_netdev(priv->netdev); cleanup_cmd_msg_buffer: kfree(priv->cmd_msg_buffer); cleanup_candev: free_candev(netdev); return err; } /* Called by the usb core when driver is unloaded or device is removed */ static void usb_8dev_disconnect(struct usb_interface *intf) { struct usb_8dev_priv *priv = usb_get_intfdata(intf); usb_set_intfdata(intf, NULL); if (priv) { netdev_info(priv->netdev, "device disconnected\n"); unregister_netdev(priv->netdev); free_candev(priv->netdev); unlink_all_urbs(priv); } } static struct usb_driver usb_8dev_driver = { .name = "usb_8dev", .probe = usb_8dev_probe, .disconnect = usb_8dev_disconnect, .id_table = usb_8dev_table, }; module_usb_driver(usb_8dev_driver); MODULE_AUTHOR("Bernd Krumboeck <*****@*****.**>"); MODULE_DESCRIPTION("CAN driver for 8 devices USB2CAN interfaces"); MODULE_LICENSE("GPL v2");
static struct sk_buff *rtllib_ADDBA(struct rtllib_device *ieee, u8 *Dst, struct ba_record *pBA, u16 StatusCode, u8 type) { struct sk_buff *skb = NULL; struct rtllib_hdr_3addr *BAReq = NULL; u8 *tag = NULL; u16 len = ieee->tx_headroom + 9; netdev_dbg(ieee->dev, "%s(): frame(%d) sentd to: %pM, ieee->dev:%p\n", __func__, type, Dst, ieee->dev); if (pBA == NULL) { netdev_warn(ieee->dev, "pBA is NULL\n"); return NULL; } skb = dev_alloc_skb(len + sizeof(struct rtllib_hdr_3addr)); if (skb == NULL) return NULL; memset(skb->data, 0, sizeof(struct rtllib_hdr_3addr)); skb_reserve(skb, ieee->tx_headroom); BAReq = (struct rtllib_hdr_3addr *)skb_put(skb, sizeof(struct rtllib_hdr_3addr)); ether_addr_copy(BAReq->addr1, Dst); ether_addr_copy(BAReq->addr2, ieee->dev->dev_addr); ether_addr_copy(BAReq->addr3, ieee->current_network.bssid); BAReq->frame_ctl = cpu_to_le16(RTLLIB_STYPE_MANAGE_ACT); tag = (u8 *)skb_put(skb, 9); *tag++ = ACT_CAT_BA; *tag++ = type; *tag++ = pBA->DialogToken; if (ACT_ADDBARSP == type) { RT_TRACE(COMP_DBG, "====>to send ADDBARSP\n"); put_unaligned_le16(StatusCode, tag); tag += 2; } put_unaligned_le16(pBA->BaParamSet.shortData, tag); tag += 2; put_unaligned_le16(pBA->BaTimeoutValue, tag); tag += 2; if (ACT_ADDBAREQ == type) { memcpy(tag, (u8 *)&(pBA->BaStartSeqCtrl), 2); tag += 2; } #ifdef VERBOSE_DEBUG print_hex_dump_bytes("rtllib_ADDBA(): ", DUMP_PREFIX_NONE, skb->data, skb->len); #endif return skb; }