diff options
author | Scott Wood <scottwood@freescale.com> | 2014-04-07 23:49:35 (GMT) |
---|---|---|
committer | Scott Wood <scottwood@freescale.com> | 2014-04-07 23:49:35 (GMT) |
commit | 62b8c978ee6b8d135d9e7953221de58000dba986 (patch) | |
tree | 683b04b2e627f6710c22c151b23c8cc9a165315e /drivers/staging/silicom | |
parent | 78fd82238d0e5716578c326404184a27ba67fd6e (diff) | |
download | linux-fsl-qoriq-62b8c978ee6b8d135d9e7953221de58000dba986.tar.xz |
Rewind v3.13-rc3+ (78fd82238d0e5716) to v3.12
Diffstat (limited to 'drivers/staging/silicom')
-rw-r--r-- | drivers/staging/silicom/bp_mod.h | 2 | ||||
-rw-r--r-- | drivers/staging/silicom/bpctl_mod.c | 188 |
2 files changed, 142 insertions, 48 deletions
diff --git a/drivers/staging/silicom/bp_mod.h b/drivers/staging/silicom/bp_mod.h index 8154a7b..cfa1f43 100644 --- a/drivers/staging/silicom/bp_mod.h +++ b/drivers/staging/silicom/bp_mod.h @@ -22,7 +22,7 @@ do { \ int i; \ if (1) { \ for (i = 0; i < 1000; i++) { \ - udelay(x); \ + udelay(x) ; \ } \ } else { \ msleep(x); \ diff --git a/drivers/staging/silicom/bpctl_mod.c b/drivers/staging/silicom/bpctl_mod.c index 39dc92a..495272d 100644 --- a/drivers/staging/silicom/bpctl_mod.c +++ b/drivers/staging/silicom/bpctl_mod.c @@ -1,11 +1,11 @@ /******************************************************************************/ /* */ -/* Bypass Control utility, Copyright (c) 2005-2011 Silicom */ +/* Bypass Control utility, Copyright (c) 2005-20011 Silicom */ /* */ /* This program is free software; you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as published by */ /* the Free Software Foundation, located in the file LICENSE. */ -/* Copyright(c) 2007 - 2009, 2013 Intel Corporation. All rights reserved. */ +/* Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved. */ /* */ /* */ /******************************************************************************/ @@ -124,60 +124,80 @@ int bp_proc_create(void); int is_bypass_fn(struct bpctl_dev *pbpctl_dev); int get_dev_idx_bsf(int bus, int slot, int func); -static int bp_get_dev_idx_bsf(struct net_device *dev, int *index) -{ - struct ethtool_drvinfo drvinfo = {0}; - char *buf; - int bus, slot, func; - - if (dev->ethtool_ops && dev->ethtool_ops->get_drvinfo) - dev->ethtool_ops->get_drvinfo(dev, &drvinfo); - else - return -EOPNOTSUPP; - - if (!drvinfo.bus_info) - return -ENODATA; - if (!strcmp(drvinfo.bus_info, "N/A")) - return -ENODATA; - - buf = strchr(drvinfo.bus_info, ':'); - if (!buf) - return -EINVAL; - buf++; - if (sscanf(buf, "%x:%x.%x", &bus, &slot, &func) != 3) - return -EINVAL; - - *index = get_dev_idx_bsf(bus, slot, func); - return 0; -} - +static unsigned long str_to_hex(char *p); static int bp_device_event(struct notifier_block *unused, unsigned long event, void *ptr) { struct net_device *dev = netdev_notifier_info_to_dev(ptr); static struct bpctl_dev *pbpctl_dev, *pbpctl_dev_m; int dev_num = 0, ret = 0, ret_d = 0, time_left = 0; - /* printk("BP_PROC_SUPPORT event =%d %s %d\n", event,dev->name, dev->ifindex ); */ /* return NOTIFY_DONE; */ if (!dev) return NOTIFY_DONE; - if (event == NETDEV_REGISTER) { - int idx_dev; + { + struct ethtool_drvinfo drvinfo; + char cbuf[32]; + char *buf = NULL; + char res[10]; + int i = 0, ifindex, idx_dev = 0; + int bus = 0, slot = 0, func = 0; + ifindex = dev->ifindex; + + memset(res, 0, 10); + memset(&drvinfo, 0, sizeof(struct ethtool_drvinfo)); + + if (dev->ethtool_ops && dev->ethtool_ops->get_drvinfo) { + memset(&drvinfo, 0, sizeof(drvinfo)); + dev->ethtool_ops->get_drvinfo(dev, &drvinfo); + } else + return NOTIFY_DONE; + if (!drvinfo.bus_info) + return NOTIFY_DONE; + if (!strcmp(drvinfo.bus_info, "N/A")) + return NOTIFY_DONE; + memcpy(&cbuf, drvinfo.bus_info, 32); + buf = &cbuf[0]; - if (bp_get_dev_idx_bsf(dev, &idx_dev)) - return NOTIFY_DONE; + while (*buf++ != ':') + ; + for (i = 0; i < 10; i++, buf++) { + if (*buf == ':') + break; + res[i] = *buf; - if (idx_dev == -1) - return NOTIFY_DONE; + } + buf++; + bus = str_to_hex(res); + memset(res, 0, 10); + + for (i = 0; i < 10; i++, buf++) { + if (*buf == '.') + break; + res[i] = *buf; + + } + buf++; + slot = str_to_hex(res); + func = str_to_hex(buf); + idx_dev = get_dev_idx_bsf(bus, slot, func); + + if (idx_dev != -1) { - bpctl_dev_arr[idx_dev].ifindex = dev->ifindex; - bpctl_dev_arr[idx_dev].ndev = dev; + bpctl_dev_arr[idx_dev].ifindex = ifindex; + bpctl_dev_arr[idx_dev].ndev = dev; - bypass_proc_remove_dev_sd(&bpctl_dev_arr[idx_dev]); - bypass_proc_create_dev_sd(&bpctl_dev_arr[idx_dev]); + bypass_proc_remove_dev_sd(&bpctl_dev_arr + [idx_dev]); + bypass_proc_create_dev_sd(&bpctl_dev_arr + [idx_dev]); + + } + + } return NOTIFY_DONE; + } if (event == NETDEV_UNREGISTER) { int idx_dev = 0; @@ -5249,6 +5269,36 @@ int get_dev_idx_bsf(int bus, int slot, int func) return -1; } +static void str_low(char *str) +{ + int i; + + for (i = 0; i < strlen(str); i++) + if ((str[i] >= 65) && (str[i] <= 90)) + str[i] += 32; +} + +static unsigned long str_to_hex(char *p) +{ + unsigned long hex = 0; + unsigned long length = strlen(p), shift = 0; + unsigned char dig = 0; + + str_low(p); + length = strlen(p); + + if (length == 0) + return 0; + + do { + dig = p[--length]; + dig = dig < 'a' ? (dig - '0') : (dig - 'a' + 0xa); + hex |= (dig << shift); + shift += 4; + } while (length); + return hex; +} + static int get_dev_idx(int ifindex) { int idx_dev = 0; @@ -5279,26 +5329,70 @@ static struct bpctl_dev *get_dev_idx_p(int ifindex) static void if_scan_init(void) { + int idx_dev = 0; struct net_device *dev; - + int ifindex; /* rcu_read_lock(); */ /* rtnl_lock(); */ /* rcu_read_lock(); */ for_each_netdev(&init_net, dev) { - int idx_dev; - if (bp_get_dev_idx_bsf(dev, &idx_dev)) - continue; + struct ethtool_drvinfo drvinfo; + char cbuf[32]; + char *buf = NULL; + char res[10]; + int i = 0; + int bus = 0, slot = 0, func = 0; + ifindex = dev->ifindex; + + memset(res, 0, 10); + memset(&drvinfo, 0, sizeof(struct ethtool_drvinfo)); - if (idx_dev == -1) + if (dev->ethtool_ops && dev->ethtool_ops->get_drvinfo) { + memset(&drvinfo, 0, sizeof(drvinfo)); + dev->ethtool_ops->get_drvinfo(dev, &drvinfo); + } else continue; + if (!strcmp(drvinfo.bus_info, "N/A")) + continue; + memcpy(&cbuf, drvinfo.bus_info, 32); + buf = &cbuf[0]; + + while (*buf++ != ':') + ; + for (i = 0; i < 10; i++, buf++) { + if (*buf == ':') + break; + res[i] = *buf; + + } + buf++; + bus = str_to_hex(res); + memset(res, 0, 10); + + for (i = 0; i < 10; i++, buf++) { + if (*buf == '.') + break; + res[i] = *buf; + + } + buf++; + slot = str_to_hex(res); + func = str_to_hex(buf); + idx_dev = get_dev_idx_bsf(bus, slot, func); + + if (idx_dev != -1) { + + bpctl_dev_arr[idx_dev].ifindex = ifindex; + bpctl_dev_arr[idx_dev].ndev = dev; + + } - bpctl_dev_arr[idx_dev].ifindex = dev->ifindex; - bpctl_dev_arr[idx_dev].ndev = dev; } /* rtnl_unlock(); */ /* rcu_read_unlock(); */ + } static long device_ioctl(struct file *file, /* see include/linux/fs.h */ |