diff options
Diffstat (limited to 'drivers/staging/most')
-rw-r--r-- | drivers/staging/most/aim-network/networking.c | 307 | ||||
-rw-r--r-- | drivers/staging/most/aim-network/networking.h | 21 | ||||
-rw-r--r-- | drivers/staging/most/hdm-dim2/Kconfig | 1 | ||||
-rw-r--r-- | drivers/staging/most/hdm-dim2/dim2_hal.c | 17 | ||||
-rw-r--r-- | drivers/staging/most/hdm-dim2/dim2_hdm.c | 18 | ||||
-rw-r--r-- | drivers/staging/most/hdm-dim2/dim2_reg.h | 1 | ||||
-rw-r--r-- | drivers/staging/most/hdm-i2c/hdm_i2c.c | 7 | ||||
-rw-r--r-- | drivers/staging/most/hdm-usb/Kconfig | 2 | ||||
-rw-r--r-- | drivers/staging/most/hdm-usb/hdm_usb.c | 15 | ||||
-rw-r--r-- | drivers/staging/most/mostcore/mostcore.h | 7 |
10 files changed, 184 insertions, 212 deletions
diff --git a/drivers/staging/most/aim-network/networking.c b/drivers/staging/most/aim-network/networking.c index ce1764cba5f0..936f013c350e 100644 --- a/drivers/staging/most/aim-network/networking.c +++ b/drivers/staging/most/aim-network/networking.c @@ -22,7 +22,6 @@ #include <linux/wait.h> #include <linux/kobject.h> #include "mostcore.h" -#include "networking.h" #define MEP_HDR_LEN 8 #define MDP_HDR_LEN 16 @@ -65,17 +64,16 @@ struct net_dev_channel { struct net_dev_context { struct most_interface *iface; - bool channels_opened; bool is_mamac; struct net_device *dev; struct net_dev_channel rx; struct net_dev_channel tx; - struct completion mac_compl; struct list_head list; }; static struct list_head net_devices = LIST_HEAD_INIT(net_devices); -static struct spinlock list_lock; +static struct mutex probe_disc_mt; /* ch->linked = true, most_nd_open */ +static struct spinlock list_lock; /* list_head, ch->linked = false, dev_hold */ static struct most_aim aim; static int skb_to_mamac(const struct sk_buff *skb, struct mbo *mbo) @@ -157,14 +155,12 @@ static int skb_to_mep(const struct sk_buff *skb, struct mbo *mbo) static int most_nd_set_mac_address(struct net_device *dev, void *p) { - struct net_dev_context *nd = dev->ml_priv; + struct net_dev_context *nd = netdev_priv(dev); int err = eth_mac_addr(dev, p); if (err) return err; - BUG_ON(nd->dev != dev); - nd->is_mamac = (dev->dev_addr[0] == 0 && dev->dev_addr[1] == 0 && dev->dev_addr[2] == 0 && dev->dev_addr[3] == 0); @@ -178,71 +174,52 @@ static int most_nd_set_mac_address(struct net_device *dev, void *p) return 0; } +static void on_netinfo(struct most_interface *iface, + unsigned char link_stat, unsigned char *mac_addr); + static int most_nd_open(struct net_device *dev) { - struct net_dev_context *nd = dev->ml_priv; - long ret; - - netdev_info(dev, "open net device\n"); - - BUG_ON(nd->dev != dev); + struct net_dev_context *nd = netdev_priv(dev); + int ret = 0; - if (nd->channels_opened) - return -EFAULT; - - BUG_ON(!nd->tx.linked || !nd->rx.linked); + mutex_lock(&probe_disc_mt); if (most_start_channel(nd->iface, nd->rx.ch_id, &aim)) { netdev_err(dev, "most_start_channel() failed\n"); - return -EBUSY; + ret = -EBUSY; + goto unlock; } if (most_start_channel(nd->iface, nd->tx.ch_id, &aim)) { netdev_err(dev, "most_start_channel() failed\n"); most_stop_channel(nd->iface, nd->rx.ch_id, &aim); - return -EBUSY; + ret = -EBUSY; + goto unlock; } - if (!is_valid_ether_addr(dev->dev_addr)) { - nd->iface->request_netinfo(nd->iface, nd->tx.ch_id); - ret = wait_for_completion_interruptible_timeout( - &nd->mac_compl, msecs_to_jiffies(5000)); - if (!ret) { - netdev_err(dev, "mac timeout\n"); - ret = -EBUSY; - goto err; - } - - if (ret < 0) { - netdev_warn(dev, "mac waiting interrupted\n"); - goto err; - } - } - - nd->channels_opened = true; + netif_carrier_off(dev); + if (is_valid_ether_addr(dev->dev_addr)) + netif_dormant_off(dev); + else + netif_dormant_on(dev); netif_wake_queue(dev); - return 0; + if (nd->iface->request_netinfo) + nd->iface->request_netinfo(nd->iface, nd->tx.ch_id, on_netinfo); -err: - most_stop_channel(nd->iface, nd->tx.ch_id, &aim); - most_stop_channel(nd->iface, nd->rx.ch_id, &aim); +unlock: + mutex_unlock(&probe_disc_mt); return ret; } static int most_nd_stop(struct net_device *dev) { - struct net_dev_context *nd = dev->ml_priv; - - netdev_info(dev, "stop net device\n"); + struct net_dev_context *nd = netdev_priv(dev); - BUG_ON(nd->dev != dev); netif_stop_queue(dev); - - if (nd->channels_opened) { - most_stop_channel(nd->iface, nd->rx.ch_id, &aim); - most_stop_channel(nd->iface, nd->tx.ch_id, &aim); - nd->channels_opened = false; - } + if (nd->iface->request_netinfo) + nd->iface->request_netinfo(nd->iface, nd->tx.ch_id, NULL); + most_stop_channel(nd->iface, nd->rx.ch_id, &aim); + most_stop_channel(nd->iface, nd->tx.ch_id, &aim); return 0; } @@ -250,12 +227,10 @@ static int most_nd_stop(struct net_device *dev) static netdev_tx_t most_nd_start_xmit(struct sk_buff *skb, struct net_device *dev) { - struct net_dev_context *nd = dev->ml_priv; + struct net_dev_context *nd = netdev_priv(dev); struct mbo *mbo; int ret; - BUG_ON(nd->dev != dev); - mbo = most_get_mbo(nd->iface, nd->tx.ch_id, &aim); if (!mbo) { @@ -296,33 +271,29 @@ static void most_nd_setup(struct net_device *dev) dev->netdev_ops = &most_nd_ops; } -static void most_net_rm_netdev_safe(struct net_dev_context *nd) +static struct net_dev_context *get_net_dev(struct most_interface *iface) { - if (!nd->dev) - return; - - pr_info("remove net device %p\n", nd->dev); + struct net_dev_context *nd; - unregister_netdev(nd->dev); - free_netdev(nd->dev); - nd->dev = NULL; + list_for_each_entry(nd, &net_devices, list) + if (nd->iface == iface) + return nd; + return NULL; } -static struct net_dev_context *get_net_dev_context( - struct most_interface *iface) +static struct net_dev_context *get_net_dev_hold(struct most_interface *iface) { - struct net_dev_context *nd, *tmp; + struct net_dev_context *nd; unsigned long flags; spin_lock_irqsave(&list_lock, flags); - list_for_each_entry_safe(nd, tmp, &net_devices, list) { - if (nd->iface == iface) { - spin_unlock_irqrestore(&list_lock, flags); - return nd; - } - } + nd = get_net_dev(iface); + if (nd && nd->rx.linked && nd->tx.linked) + dev_hold(nd->dev); + else + nd = NULL; spin_unlock_irqrestore(&list_lock, flags); - return NULL; + return nd; } static int aim_probe_channel(struct most_interface *iface, int channel_idx, @@ -331,7 +302,9 @@ static int aim_probe_channel(struct most_interface *iface, int channel_idx, { struct net_dev_context *nd; struct net_dev_channel *ch; + struct net_device *dev; unsigned long flags; + int ret = 0; if (!iface) return -EINVAL; @@ -339,54 +312,45 @@ static int aim_probe_channel(struct most_interface *iface, int channel_idx, if (ccfg->data_type != MOST_CH_ASYNC) return -EINVAL; - nd = get_net_dev_context(iface); - + mutex_lock(&probe_disc_mt); + nd = get_net_dev(iface); if (!nd) { - nd = kzalloc(sizeof(*nd), GFP_KERNEL); - if (!nd) - return -ENOMEM; + dev = alloc_netdev(sizeof(struct net_dev_context), "meth%d", + NET_NAME_UNKNOWN, most_nd_setup); + if (!dev) { + ret = -ENOMEM; + goto unlock; + } - init_completion(&nd->mac_compl); + nd = netdev_priv(dev); nd->iface = iface; + nd->dev = dev; spin_lock_irqsave(&list_lock, flags); list_add(&nd->list, &net_devices); spin_unlock_irqrestore(&list_lock, flags); - } - ch = ccfg->direction == MOST_CH_TX ? &nd->tx : &nd->rx; - if (ch->linked) { - pr_err("only one channel per instance & direction allowed\n"); - return -EINVAL; - } - - if (nd->tx.linked || nd->rx.linked) { - struct net_device *dev = - alloc_netdev(0, "meth%d", NET_NAME_UNKNOWN, - most_nd_setup); - - if (!dev) { - pr_err("no memory for net_device\n"); - return -ENOMEM; + ch = ccfg->direction == MOST_CH_TX ? &nd->tx : &nd->rx; + } else { + ch = ccfg->direction == MOST_CH_TX ? &nd->tx : &nd->rx; + if (ch->linked) { + pr_err("direction is allocated\n"); + ret = -EINVAL; + goto unlock; } - nd->dev = dev; - ch->ch_id = channel_idx; - ch->linked = true; - - dev->ml_priv = nd; - if (register_netdev(dev)) { - pr_err("registering net device failed\n"); - ch->linked = false; - free_netdev(dev); - return -EINVAL; + if (register_netdev(nd->dev)) { + pr_err("register_netdev() failed\n"); + ret = -EINVAL; + goto unlock; } } - ch->ch_id = channel_idx; ch->linked = true; - return 0; +unlock: + mutex_unlock(&probe_disc_mt); + return ret; } static int aim_disconnect_channel(struct most_interface *iface, @@ -395,34 +359,45 @@ static int aim_disconnect_channel(struct most_interface *iface, struct net_dev_context *nd; struct net_dev_channel *ch; unsigned long flags; + int ret = 0; - nd = get_net_dev_context(iface); - if (!nd) - return -EINVAL; + mutex_lock(&probe_disc_mt); + nd = get_net_dev(iface); + if (!nd) { + ret = -EINVAL; + goto unlock; + } - if (nd->rx.linked && channel_idx == nd->rx.ch_id) + if (nd->rx.linked && channel_idx == nd->rx.ch_id) { ch = &nd->rx; - else if (nd->tx.linked && channel_idx == nd->tx.ch_id) + } else if (nd->tx.linked && channel_idx == nd->tx.ch_id) { ch = &nd->tx; - else - return -EINVAL; - - ch->linked = false; + } else { + ret = -EINVAL; + goto unlock; + } - /* - * do not call most_stop_channel() here, because channels are - * going to be closed in ndo_stop() after unregister_netdev() - */ - most_net_rm_netdev_safe(nd); + if (nd->rx.linked && nd->tx.linked) { + spin_lock_irqsave(&list_lock, flags); + ch->linked = false; + spin_unlock_irqrestore(&list_lock, flags); - if (!nd->rx.linked && !nd->tx.linked) { + /* + * do not call most_stop_channel() here, because channels are + * going to be closed in ndo_stop() after unregister_netdev() + */ + unregister_netdev(nd->dev); + } else { spin_lock_irqsave(&list_lock, flags); list_del(&nd->list); spin_unlock_irqrestore(&list_lock, flags); - kfree(nd); + + free_netdev(nd->dev); } - return 0; +unlock: + mutex_unlock(&probe_disc_mt); + return ret; } static int aim_resume_tx_channel(struct most_interface *iface, @@ -430,14 +405,17 @@ static int aim_resume_tx_channel(struct most_interface *iface, { struct net_dev_context *nd; - nd = get_net_dev_context(iface); - if (!nd || !nd->channels_opened || nd->tx.ch_id != channel_idx) + nd = get_net_dev_hold(iface); + if (!nd) return 0; - if (!nd->dev) - return 0; + if (nd->tx.ch_id != channel_idx) + goto put_nd; netif_wake_queue(nd->dev); + +put_nd: + dev_put(nd->dev); return 0; } @@ -450,25 +428,31 @@ static int aim_rx_data(struct mbo *mbo) struct sk_buff *skb; struct net_device *dev; unsigned int skb_len; + int ret = 0; - nd = get_net_dev_context(mbo->ifp); - if (!nd || !nd->channels_opened || nd->rx.ch_id != mbo->hdm_channel_id) + nd = get_net_dev_hold(mbo->ifp); + if (!nd) return -EIO; - dev = nd->dev; - if (!dev) { - pr_err_once("drop packet: missing net_device\n"); - return -EIO; + if (nd->rx.ch_id != mbo->hdm_channel_id) { + ret = -EIO; + goto put_nd; } + dev = nd->dev; + if (nd->is_mamac) { - if (!PMS_IS_MAMAC(buf, len)) - return -EIO; + if (!PMS_IS_MAMAC(buf, len)) { + ret = -EIO; + goto put_nd; + } skb = dev_alloc_skb(len - MDP_HDR_LEN + 2 * ETH_ALEN + 2); } else { - if (!PMS_IS_MEP(buf, len)) - return -EIO; + if (!PMS_IS_MEP(buf, len)) { + ret = -EIO; + goto put_nd; + } skb = dev_alloc_skb(len - MEP_HDR_LEN); } @@ -486,11 +470,11 @@ static int aim_rx_data(struct mbo *mbo) ether_addr_copy(skb_put(skb, ETH_ALEN), dev->dev_addr); /* src */ - memcpy(skb_put(skb, 4), &zero, 4); - memcpy(skb_put(skb, 2), buf + 5, 2); + skb_put_data(skb, &zero, 4); + skb_put_data(skb, buf + 5, 2); /* eth type */ - memcpy(skb_put(skb, 2), buf + 10, 2); + skb_put_data(skb, buf + 10, 2); buf += MDP_HDR_LEN; len -= MDP_HDR_LEN; @@ -499,7 +483,7 @@ static int aim_rx_data(struct mbo *mbo) len -= MEP_HDR_LEN; } - memcpy(skb_put(skb, len), buf, len); + skb_put_data(skb, buf, len); skb->protocol = eth_type_trans(skb, dev); skb_len = skb->len; if (netif_rx(skb) == NET_RX_SUCCESS) { @@ -511,7 +495,10 @@ static int aim_rx_data(struct mbo *mbo) out: most_put_mbo(mbo); - return 0; + +put_nd: + dev_put(nd->dev); + return ret; } static struct most_aim aim = { @@ -524,68 +511,54 @@ static struct most_aim aim = { static int __init most_net_init(void) { - pr_info("most_net_init()\n"); spin_lock_init(&list_lock); + mutex_init(&probe_disc_mt); return most_register_aim(&aim); } static void __exit most_net_exit(void) { - struct net_dev_context *nd, *tmp; - unsigned long flags; - - spin_lock_irqsave(&list_lock, flags); - list_for_each_entry_safe(nd, tmp, &net_devices, list) { - list_del(&nd->list); - spin_unlock_irqrestore(&list_lock, flags); - /* - * do not call most_stop_channel() here, because channels are - * going to be closed in ndo_stop() after unregister_netdev() - */ - most_net_rm_netdev_safe(nd); - kfree(nd); - spin_lock_irqsave(&list_lock, flags); - } - spin_unlock_irqrestore(&list_lock, flags); - most_deregister_aim(&aim); - pr_info("most_net_exit()\n"); } /** - * most_deliver_netinfo - callback for HDM to be informed about HW's MAC + * on_netinfo - callback for HDM to be informed about HW's MAC * @param iface - most interface instance * @param link_stat - link status * @param mac_addr - MAC address */ -void most_deliver_netinfo(struct most_interface *iface, - unsigned char link_stat, unsigned char *mac_addr) +static void on_netinfo(struct most_interface *iface, + unsigned char link_stat, unsigned char *mac_addr) { struct net_dev_context *nd; struct net_device *dev; const u8 *m = mac_addr; - nd = get_net_dev_context(iface); + nd = get_net_dev_hold(iface); if (!nd) return; dev = nd->dev; - if (!dev) - return; + + if (link_stat) + netif_carrier_on(dev); + else + netif_carrier_off(dev); if (m && is_valid_ether_addr(m)) { if (!is_valid_ether_addr(dev->dev_addr)) { netdev_info(dev, "set mac %02x-%02x-%02x-%02x-%02x-%02x\n", m[0], m[1], m[2], m[3], m[4], m[5]); ether_addr_copy(dev->dev_addr, m); - complete(&nd->mac_compl); + netif_dormant_off(dev); } else if (!ether_addr_equal(dev->dev_addr, m)) { netdev_warn(dev, "reject mac %02x-%02x-%02x-%02x-%02x-%02x\n", m[0], m[1], m[2], m[3], m[4], m[5]); } } + + dev_put(nd->dev); } -EXPORT_SYMBOL(most_deliver_netinfo); module_init(most_net_init); module_exit(most_net_exit); diff --git a/drivers/staging/most/aim-network/networking.h b/drivers/staging/most/aim-network/networking.h deleted file mode 100644 index 6f346d410525..000000000000 --- a/drivers/staging/most/aim-network/networking.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Networking AIM - Networking Application Interface Module for MostCore - * - * Copyright (C) 2015, Microchip Technology Germany II GmbH & Co. KG - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * This file is licensed under GPLv2. - */ -#ifndef _NETWORKING_H_ -#define _NETWORKING_H_ - -#include "mostcore.h" - -void most_deliver_netinfo(struct most_interface *iface, - unsigned char link_stat, unsigned char *mac_addr); - -#endif diff --git a/drivers/staging/most/hdm-dim2/Kconfig b/drivers/staging/most/hdm-dim2/Kconfig index 28a0e1791600..663bfebff674 100644 --- a/drivers/staging/most/hdm-dim2/Kconfig +++ b/drivers/staging/most/hdm-dim2/Kconfig @@ -4,7 +4,6 @@ config HDM_DIM2 tristate "DIM2 HDM" - depends on AIM_NETWORK depends on HAS_IOMEM ---help--- diff --git a/drivers/staging/most/hdm-dim2/dim2_hal.c b/drivers/staging/most/hdm-dim2/dim2_hal.c index d604ec09df28..91484643d289 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hal.c +++ b/drivers/staging/most/hdm-dim2/dim2_hal.c @@ -217,12 +217,15 @@ static inline void dim2_clear_ctr(u32 ctr_addr) } static void dim2_configure_cat(u8 cat_base, u8 ch_addr, u8 ch_type, - bool read_not_write, bool sync_mfe) + bool read_not_write) { + bool isoc_fce = ch_type == CAT_CT_VAL_ISOC; + bool sync_mfe = ch_type == CAT_CT_VAL_SYNC; u16 const cat = (read_not_write << CAT_RNW_BIT) | (ch_type << CAT_CT_SHIFT) | (ch_addr << CAT_CL_SHIFT) | + (isoc_fce << CAT_FCE_BIT) | (sync_mfe << CAT_MFE_BIT) | (false << CAT_MT_BIT) | (true << CAT_CE_BIT); @@ -350,13 +353,13 @@ static void dim2_clear_ctram(void) static void dim2_configure_channel( u8 ch_addr, u8 type, u8 is_tx, u16 dbr_address, u16 hw_buffer_size, - u16 packet_length, bool sync_mfe) + u16 packet_length) { dim2_configure_cdt(ch_addr, dbr_address, hw_buffer_size, packet_length); - dim2_configure_cat(MLB_CAT, ch_addr, type, is_tx ? 1 : 0, sync_mfe); + dim2_configure_cat(MLB_CAT, ch_addr, type, is_tx ? 1 : 0); dim2_configure_adt(ch_addr); - dim2_configure_cat(AHB_CAT, ch_addr, type, is_tx ? 0 : 1, sync_mfe); + dim2_configure_cat(AHB_CAT, ch_addr, type, is_tx ? 0 : 1); /* unmask interrupt for used channel, enable mlb_sys_int[0] interrupt */ dimcb_io_write(&g.dim2->ACMR0, @@ -771,7 +774,7 @@ static u8 init_ctrl_async(struct dim_channel *ch, u8 type, u8 is_tx, channel_init(ch, ch_address / 2); dim2_configure_channel(ch->addr, type, is_tx, - ch->dbr_addr, ch->dbr_size, 0, false); + ch->dbr_addr, ch->dbr_size, 0); return DIM_NO_ERROR; } @@ -857,7 +860,7 @@ u8 dim_init_isoc(struct dim_channel *ch, u8 is_tx, u16 ch_address, isoc_init(ch, ch_address / 2, packet_length); dim2_configure_channel(ch->addr, CAT_CT_VAL_ISOC, is_tx, ch->dbr_addr, - ch->dbr_size, packet_length, false); + ch->dbr_size, packet_length); return DIM_NO_ERROR; } @@ -885,7 +888,7 @@ u8 dim_init_sync(struct dim_channel *ch, u8 is_tx, u16 ch_address, dim2_clear_dbr(ch->dbr_addr, ch->dbr_size); dim2_configure_channel(ch->addr, CAT_CT_VAL_SYNC, is_tx, - ch->dbr_addr, ch->dbr_size, 0, true); + ch->dbr_addr, ch->dbr_size, 0); return DIM_NO_ERROR; } diff --git a/drivers/staging/most/hdm-dim2/dim2_hdm.c b/drivers/staging/most/hdm-dim2/dim2_hdm.c index 902824e728ea..4607d03c577b 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hdm.c +++ b/drivers/staging/most/hdm-dim2/dim2_hdm.c @@ -26,7 +26,6 @@ #include <linux/kthread.h> #include <mostcore.h> -#include <networking.h> #include "dim2_hal.h" #include "dim2_hdm.h" #include "dim2_errors.h" @@ -107,6 +106,8 @@ struct dim2_hdm { unsigned char link_state; int atx_idx; struct medialb_bus bus; + void (*on_netinfo)(struct most_interface *, + unsigned char, unsigned char *); }; #define iface_to_hdm(iface) container_of(iface, struct dim2_hdm, most_iface) @@ -287,8 +288,11 @@ static int deliver_netinfo_thread(void *data) if (dev->deliver_netinfo) { dev->deliver_netinfo--; - most_deliver_netinfo(&dev->most_iface, dev->link_state, - dev->mac_addrs); + if (dev->on_netinfo) { + dev->on_netinfo(&dev->most_iface, + dev->link_state, + dev->mac_addrs); + } } } @@ -654,12 +658,18 @@ static int enqueue(struct most_interface *most_iface, int ch_idx, * Send a command to INIC which triggers retrieving of network info by means of * "Message exchange over MDP/MEP". Return 0 on success, negative on failure. */ -static void request_netinfo(struct most_interface *most_iface, int ch_idx) +static void request_netinfo(struct most_interface *most_iface, int ch_idx, + void (*on_netinfo)(struct most_interface *, + unsigned char, unsigned char *)) { struct dim2_hdm *dev = iface_to_hdm(most_iface); struct mbo *mbo; u8 *data; + dev->on_netinfo = on_netinfo; + if (!on_netinfo) + return; + if (dev->atx_idx < 0) { pr_err("Async Tx Not initialized\n"); return; diff --git a/drivers/staging/most/hdm-dim2/dim2_reg.h b/drivers/staging/most/hdm-dim2/dim2_reg.h index 01fe499411ff..f7d9fbcd29f2 100644 --- a/drivers/staging/most/hdm-dim2/dim2_reg.h +++ b/drivers/staging/most/hdm-dim2/dim2_reg.h @@ -141,6 +141,7 @@ enum { ADT1_CTRL_ASYNC_BD_MASK = DIM2_MASK(11), ADT1_ISOC_SYNC_BD_MASK = DIM2_MASK(13), + CAT_FCE_BIT = 14, CAT_MFE_BIT = 14, CAT_MT_BIT = 13, diff --git a/drivers/staging/most/hdm-i2c/hdm_i2c.c b/drivers/staging/most/hdm-i2c/hdm_i2c.c index 1d5b22927bcd..2b4de404e46a 100644 --- a/drivers/staging/most/hdm-i2c/hdm_i2c.c +++ b/drivers/staging/most/hdm-i2c/hdm_i2c.c @@ -185,12 +185,6 @@ static int poison_channel(struct most_interface *most_iface, return 0; } -static void request_netinfo(struct most_interface *most_iface, - int ch_idx) -{ - pr_info("request_netinfo()\n"); -} - static void do_rx_work(struct hdm_i2c *dev) { struct mbo *mbo; @@ -343,7 +337,6 @@ static int i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) dev->most_iface.configure = configure_channel; dev->most_iface.enqueue = enqueue; dev->most_iface.poison_channel = poison_channel; - dev->most_iface.request_netinfo = request_netinfo; INIT_LIST_HEAD(&dev->rx.list); mutex_init(&dev->rx.list_mutex); diff --git a/drivers/staging/most/hdm-usb/Kconfig b/drivers/staging/most/hdm-usb/Kconfig index ec1546312ee6..487f1f34776c 100644 --- a/drivers/staging/most/hdm-usb/Kconfig +++ b/drivers/staging/most/hdm-usb/Kconfig @@ -5,7 +5,7 @@ config HDM_USB tristate "USB HDM" depends on USB && NET - select AIM_NETWORK + ---help--- Say Y here if you want to connect via USB to network tranceiver. This device driver depends on the networking AIM. diff --git a/drivers/staging/most/hdm-usb/hdm_usb.c b/drivers/staging/most/hdm-usb/hdm_usb.c index a95b5910d9fc..d0f68cb3c173 100644 --- a/drivers/staging/most/hdm-usb/hdm_usb.c +++ b/drivers/staging/most/hdm-usb/hdm_usb.c @@ -30,7 +30,6 @@ #include <linux/etherdevice.h> #include <linux/uaccess.h> #include "mostcore.h" -#include "networking.h" #define USB_MTU 512 #define NO_ISOCHRONOUS_URB 0 @@ -126,6 +125,8 @@ struct most_dev { struct mutex io_mutex; struct timer_list link_stat_timer; struct work_struct poll_work_obj; + void (*on_netinfo)(struct most_interface *, unsigned char, + unsigned char *); }; #define to_mdev(d) container_of(d, struct most_dev, iface) @@ -719,12 +720,19 @@ exit: * polls for the NI state of the INIC every 2 seconds. * */ -static void hdm_request_netinfo(struct most_interface *iface, int channel) +static void hdm_request_netinfo(struct most_interface *iface, int channel, + void (*on_netinfo)(struct most_interface *, + unsigned char, + unsigned char *)) { struct most_dev *mdev; BUG_ON(!iface); mdev = to_mdev(iface); + mdev->on_netinfo = on_netinfo; + if (!on_netinfo) + return; + mdev->link_stat_timer.expires = jiffies + HZ; mod_timer(&mdev->link_stat_timer, mdev->link_stat_timer.expires); } @@ -786,7 +794,8 @@ static void wq_netinfo(struct work_struct *wq_obj) hw_addr[4] = lo >> 8; hw_addr[5] = lo; - most_deliver_netinfo(&mdev->iface, link, hw_addr); + if (mdev->on_netinfo) + mdev->on_netinfo(&mdev->iface, link, hw_addr); } /** diff --git a/drivers/staging/most/mostcore/mostcore.h b/drivers/staging/most/mostcore/mostcore.h index 5f8339bd046f..915e5159d1eb 100644 --- a/drivers/staging/most/mostcore/mostcore.h +++ b/drivers/staging/most/mostcore/mostcore.h @@ -233,6 +233,8 @@ struct mbo { * The callback returns a negative value on error, otherwise 0. * @request_netinfo: triggers retrieving of network info from the HDM by * means of "Message exchange over MDP/MEP" + * The call of the function request_netinfo with the parameter on_netinfo as + * NULL prohibits use of the previously obtained function pointer. * @priv Private field used by mostcore to store context information. */ struct most_interface { @@ -246,7 +248,10 @@ struct most_interface { int (*enqueue)(struct most_interface *iface, int channel_idx, struct mbo *mbo); int (*poison_channel)(struct most_interface *iface, int channel_idx); - void (*request_netinfo)(struct most_interface *iface, int channel_idx); + void (*request_netinfo)(struct most_interface *iface, int channel_idx, + void (*on_netinfo)(struct most_interface *iface, + unsigned char link_stat, + unsigned char *mac_addr)); void *priv; }; |