int hieth_mdio_write( struct hieth_mdio_local *ld, int phy_addr, int regnum, int val) { int ret = 0; hieth_assert((!(phy_addr & (~0x1F))) && (!(regnum & (~0x1F)))); hieth_trace(4, "phy_addr = %d, regnum = %d", phy_addr, regnum); local_lock(ld); if (!wait_mdio_ready(ld)) { hieth_error("mdio busy"); ret = -1; goto error_exit; } mdio_phywrite(ld, phy_addr, regnum, val); error_exit: local_unlock(ld); return val; }
int hieth_mdio_read(struct hieth_mdio_local *ld, int phy_addr, int regnum) { int val = 0; hieth_assert((!(phy_addr & (~0x1F))) && (!(regnum & (~0x1F)))); local_lock(ld); if (!wait_mdio_ready(ld)) { hieth_error("mdio busy"); goto error_exit; } mdio_start_phyread(ld, phy_addr, regnum); if (wait_mdio_ready(ld)) val = mdio_get_phyread_val(ld); else hieth_error("read timeout"); error_exit: local_unlock(ld); hieth_trace(4, "phy_addr = %d, regnum = %d, val = 0x%04x", phy_addr, regnum, val); return val; }
struct sk_buff *hieth_platdev_alloc_skb(struct hieth_netdev_local *ld) { struct sk_buff *skb; int i; skb = ld->rx_pool.sk_pool[ld->rx_pool.next_free_skb++]; if (ld->rx_pool.next_free_skb == CONFIG_HIETH_MAX_RX_POOLS) ld->rx_pool.next_free_skb = 0; /*current skb is used by kernel or other process,find another skb*/ if (skb_shared(skb) || (atomic_read(&(skb_shinfo(skb)->dataref)) > 1)) { for (i = 0; i < CONFIG_HIETH_MAX_RX_POOLS; i++) { skb = ld->rx_pool.sk_pool[ld->rx_pool.next_free_skb++]; if (ld->rx_pool.next_free_skb == CONFIG_HIETH_MAX_RX_POOLS) ld->rx_pool.next_free_skb = 0; if ((skb_shared(skb) == 0) && (atomic_read(&(skb_shinfo(skb)->dataref)) <= 1)) break; } if (i == CONFIG_HIETH_MAX_RX_POOLS) { ld->stat.rx_pool_dry_times++; hieth_trace(7, "%ld: no free skb\n", ld->stat.rx_pool_dry_times); return NULL; } } memset(skb, 0, offsetof(struct sk_buff, tail)); skb->data = skb->tail = skb->head; skb->end = skb->data + (skb->truesize - sizeof(struct sk_buff)); skb->len = 0; skb->data_len = 0; skb->cloned = 0; atomic_inc(&skb->users); return skb; }
static void hieth_monitor_func(unsigned long arg) { struct net_device *dev = (struct net_device *)arg; struct hieth_netdev_local *ld = netdev_priv(dev); if (!ld || !netif_running(dev)) { hieth_trace(7, "network driver is stoped."); return; } hieth_feed_hw(ld); hieth_xmit_release_skb(ld); ld->monitor.expires = jiffies + msecs_to_jiffies(CONFIG_HIETH_MONITOR_TIMER); add_timer(&ld->monitor); return; }