Commit e657e078 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net

Pull networking fixes from David Miller:
 "This is what we usually expect at this stage of the game, lots of
  little things, mostly in drivers.  With the occasional 'oops didn't
  mean to do that' kind of regressions in the core code."

 1) Uninitialized data in __ip_vs_get_timeouts(), from Arnd Bergmann

 2) Reject invalid ACK sequences in Fast Open sockets, from Jerry Chu.

 3) Lost error code on return from _rtl_usb_receive(), from Christian
    Lamparter.

 4) Fix reset resume on USB rt2x00, from Stanislaw Gruszka.

 5) Release resources on error in pch_gbe driver, from Veaceslav Falico.

 6) Default hop limit not set correctly in ip6_template_metrics[], fix
    from Li RongQing.

 7) Gianfar PTP code requests wrong kind of resource during probe, fix
    from Wei Yang.

 8) Fix VHOST net driver on big-endian, from Michael S Tsirkin.

 9) Mallenox driver bug fixes from Jack Morgenstein, Or Gerlitz, Moni
    Shoua, Dotan Barak, and Uri Habusha.

10) usbnet leaks memory on TX path, fix from Hemant Kumar.

11) Use socket state test, rather than presence of FIN bit packet, to
    determine FIONREAD/SIOCINQ value.  Fix from Eric Dumazet.

12) Fix cxgb4 build failure, from Vipul Pandya.

13) Provide a SYN_DATA_ACKED state to complement SYN_FASTOPEN in socket
    info dumps.  From Yuchung Cheng.

14) Fix leak of security path in kfree_skb_partial().  Fix from Eric
    Dumazet.

15) Handle RX FIFO overflows more resiliently in pch_gbe driver, from
    Veaceslav Falico.

16) Fix MAINTAINERS file pattern for networking drivers, from Jean
    Delvare.

17) Add iPhone5 IDs to IPHETH driver, from Jay Purohit.

18) VLAN device type change restriction is too strict, and should not
    trigger for the automatically generated vlan0 device.  Fix from Jiri
    Pirko.

19) Make PMTU/redirect flushing work properly again in ipv4, from
    Steffen Klassert.

20) Fix memory corruptions by using kfree_rcu() in netlink_release().
    From Eric Dumazet.

21) More qmi_wwan device IDs, from Bjørn Mork.

22) Fix unintentional change of SNAT/DNAT hooks in generic NAT
    infrastructure, from Elison Niven.

23) Fix 3.6.x regression in xt_TEE netfilter module, from Eric Dumazet.

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (57 commits)
  tilegx: fix some issues in the SW TSO support
  qmi_wwan/cdc_ether: move Novatel 551 and E362 to qmi_wwan
  net: usb: Fix memory leak on Tx data path
  net/mlx4_core: Unmap UAR also in the case of error flow
  net/mlx4_en: Don't use vlan tag value as an indication for vlan presence
  net/mlx4_en: Fix double-release-range in tx-rings
  bas_gigaset: fix pre_reset handling
  vhost: fix mergeable bufs on BE hosts
  gianfar_ptp: use iomem, not ioports resource tree in probe
  ipv6: Set default hoplimit as zero.
  NET_VENDOR_TI: make available for am33xx as well
  pch_gbe: fix error handling in pch_gbe_up()
  b43: Fix oops on unload when firmware not found
  mwifiex: clean up scan state on error
  mwifiex: return -EBUSY if specific scan request cannot be honored
  brcmfmac: fix potential NULL dereference
  Revert "ath9k_hw: Updated AR9003 tx gain table for 5GHz"
  ath9k_htc: Add PID/VID for a Ubiquiti WiFiStation
  rt2x00: usb: fix reset resume
  rtlwifi: pass rx setup error code to caller
  ...
parents f761237e 330ee004
...@@ -5062,7 +5062,13 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git ...@@ -5062,7 +5062,13 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git
S: Odd Fixes S: Odd Fixes
F: drivers/net/ F: drivers/net/
F: include/linux/if_* F: include/linux/if_*
F: include/linux/*device.h F: include/linux/netdevice.h
F: include/linux/arcdevice.h
F: include/linux/etherdevice.h
F: include/linux/fcdevice.h
F: include/linux/fddidevice.h
F: include/linux/hippidevice.h
F: include/linux/inetdevice.h
NETXEN (1/10) GbE SUPPORT NETXEN (1/10) GbE SUPPORT
M: Sony Chacko <sony.chacko@qlogic.com> M: Sony Chacko <sony.chacko@qlogic.com>
......
...@@ -158,9 +158,10 @@ static int bcma_register_cores(struct bcma_bus *bus) ...@@ -158,9 +158,10 @@ static int bcma_register_cores(struct bcma_bus *bus)
static void bcma_unregister_cores(struct bcma_bus *bus) static void bcma_unregister_cores(struct bcma_bus *bus)
{ {
struct bcma_device *core; struct bcma_device *core, *tmp;
list_for_each_entry(core, &bus->cores, list) { list_for_each_entry_safe(core, tmp, &bus->cores, list) {
list_del(&core->list);
if (core->dev_registered) if (core->dev_registered)
device_unregister(&core->dev); device_unregister(&core->dev);
} }
......
...@@ -617,7 +617,13 @@ static void int_in_work(struct work_struct *work) ...@@ -617,7 +617,13 @@ static void int_in_work(struct work_struct *work)
if (rc == 0) if (rc == 0)
/* success, resubmit interrupt read URB */ /* success, resubmit interrupt read URB */
rc = usb_submit_urb(urb, GFP_ATOMIC); rc = usb_submit_urb(urb, GFP_ATOMIC);
if (rc != 0 && rc != -ENODEV) {
switch (rc) {
case 0: /* success */
case -ENODEV: /* device gone */
case -EINVAL: /* URB already resubmitted, or terminal badness */
break;
default: /* failure: try to recover by resetting the device */
dev_err(cs->dev, "clear halt failed: %s\n", get_usb_rcmsg(rc)); dev_err(cs->dev, "clear halt failed: %s\n", get_usb_rcmsg(rc));
rc = usb_lock_device_for_reset(ucs->udev, ucs->interface); rc = usb_lock_device_for_reset(ucs->udev, ucs->interface);
if (rc == 0) { if (rc == 0) {
...@@ -2442,7 +2448,9 @@ static void gigaset_disconnect(struct usb_interface *interface) ...@@ -2442,7 +2448,9 @@ static void gigaset_disconnect(struct usb_interface *interface)
} }
/* gigaset_suspend /* gigaset_suspend
* This function is called before the USB connection is suspended. * This function is called before the USB connection is suspended
* or before the USB device is reset.
* In the latter case, message == PMSG_ON.
*/ */
static int gigaset_suspend(struct usb_interface *intf, pm_message_t message) static int gigaset_suspend(struct usb_interface *intf, pm_message_t message)
{ {
...@@ -2498,7 +2506,12 @@ static int gigaset_suspend(struct usb_interface *intf, pm_message_t message) ...@@ -2498,7 +2506,12 @@ static int gigaset_suspend(struct usb_interface *intf, pm_message_t message)
del_timer_sync(&ucs->timer_atrdy); del_timer_sync(&ucs->timer_atrdy);
del_timer_sync(&ucs->timer_cmd_in); del_timer_sync(&ucs->timer_cmd_in);
del_timer_sync(&ucs->timer_int_in); del_timer_sync(&ucs->timer_int_in);
cancel_work_sync(&ucs->int_in_wq);
/* don't try to cancel int_in_wq from within reset as it
* might be the one requesting the reset
*/
if (message.event != PM_EVENT_ON)
cancel_work_sync(&ucs->int_in_wq);
gig_dbg(DEBUG_SUSPEND, "suspend complete"); gig_dbg(DEBUG_SUSPEND, "suspend complete");
return 0; return 0;
......
...@@ -144,9 +144,22 @@ ...@@ -144,9 +144,22 @@
#define FLEXCAN_MB_CODE_MASK (0xf0ffffff) #define FLEXCAN_MB_CODE_MASK (0xf0ffffff)
/* FLEXCAN hardware feature flags */ /*
* FLEXCAN hardware feature flags
*
* Below is some version info we got:
* SOC Version IP-Version Glitch- [TR]WRN_INT
* Filter? connected?
* MX25 FlexCAN2 03.00.00.00 no no
* MX28 FlexCAN2 03.00.04.00 yes yes
* MX35 FlexCAN2 03.00.00.00 no no
* MX53 FlexCAN2 03.00.00.00 yes no
* MX6s FlexCAN3 10.00.12.00 yes yes
*
* Some SOCs do not have the RX_WARN & TX_WARN interrupt line connected.
*/
#define FLEXCAN_HAS_V10_FEATURES BIT(1) /* For core version >= 10 */ #define FLEXCAN_HAS_V10_FEATURES BIT(1) /* For core version >= 10 */
#define FLEXCAN_HAS_BROKEN_ERR_STATE BIT(2) /* Broken error state handling */ #define FLEXCAN_HAS_BROKEN_ERR_STATE BIT(2) /* [TR]WRN_INT not connected */
/* Structure of the message buffer */ /* Structure of the message buffer */
struct flexcan_mb { struct flexcan_mb {
...@@ -205,7 +218,7 @@ static struct flexcan_devtype_data fsl_p1010_devtype_data = { ...@@ -205,7 +218,7 @@ static struct flexcan_devtype_data fsl_p1010_devtype_data = {
}; };
static struct flexcan_devtype_data fsl_imx28_devtype_data; static struct flexcan_devtype_data fsl_imx28_devtype_data;
static struct flexcan_devtype_data fsl_imx6q_devtype_data = { static struct flexcan_devtype_data fsl_imx6q_devtype_data = {
.features = FLEXCAN_HAS_V10_FEATURES | FLEXCAN_HAS_BROKEN_ERR_STATE, .features = FLEXCAN_HAS_V10_FEATURES,
}; };
static const struct can_bittiming_const flexcan_bittiming_const = { static const struct can_bittiming_const flexcan_bittiming_const = {
......
...@@ -30,9 +30,10 @@ ...@@ -30,9 +30,10 @@
#include "sja1000.h" #include "sja1000.h"
MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>"); MODULE_AUTHOR("Stephane Grosjean <s.grosjean@peak-system.com>");
MODULE_DESCRIPTION("Socket-CAN driver for PEAK PCAN PCI family cards"); MODULE_DESCRIPTION("Socket-CAN driver for PEAK PCAN PCI family cards");
MODULE_SUPPORTED_DEVICE("PEAK PCAN PCI/PCIe/PCIeC miniPCI CAN cards"); MODULE_SUPPORTED_DEVICE("PEAK PCAN PCI/PCIe/PCIeC miniPCI CAN cards");
MODULE_SUPPORTED_DEVICE("PEAK PCAN miniPCIe/cPCI PC/104+ PCI/104e CAN Cards");
MODULE_LICENSE("GPL v2"); MODULE_LICENSE("GPL v2");
#define DRV_NAME "peak_pci" #define DRV_NAME "peak_pci"
...@@ -64,7 +65,11 @@ struct peak_pci_chan { ...@@ -64,7 +65,11 @@ struct peak_pci_chan {
#define PEAK_PCI_DEVICE_ID 0x0001 /* for PCI/PCIe slot cards */ #define PEAK_PCI_DEVICE_ID 0x0001 /* for PCI/PCIe slot cards */
#define PEAK_PCIEC_DEVICE_ID 0x0002 /* for ExpressCard slot cards */ #define PEAK_PCIEC_DEVICE_ID 0x0002 /* for ExpressCard slot cards */
#define PEAK_PCIE_DEVICE_ID 0x0003 /* for nextgen PCIe slot cards */ #define PEAK_PCIE_DEVICE_ID 0x0003 /* for nextgen PCIe slot cards */
#define PEAK_MPCI_DEVICE_ID 0x0008 /* The miniPCI slot cards */ #define PEAK_CPCI_DEVICE_ID 0x0004 /* for nextgen cPCI slot cards */
#define PEAK_MPCI_DEVICE_ID 0x0005 /* for nextgen miniPCI slot cards */
#define PEAK_PC_104P_DEVICE_ID 0x0006 /* PCAN-PC/104+ cards */
#define PEAK_PCI_104E_DEVICE_ID 0x0007 /* PCAN-PCI/104 Express cards */
#define PEAK_MPCIE_DEVICE_ID 0x0008 /* The miniPCIe slot cards */
#define PEAK_PCI_CHAN_MAX 4 #define PEAK_PCI_CHAN_MAX 4
...@@ -76,6 +81,10 @@ static DEFINE_PCI_DEVICE_TABLE(peak_pci_tbl) = { ...@@ -76,6 +81,10 @@ static DEFINE_PCI_DEVICE_TABLE(peak_pci_tbl) = {
{PEAK_PCI_VENDOR_ID, PEAK_PCI_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, {PEAK_PCI_VENDOR_ID, PEAK_PCI_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
{PEAK_PCI_VENDOR_ID, PEAK_PCIE_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, {PEAK_PCI_VENDOR_ID, PEAK_PCIE_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
{PEAK_PCI_VENDOR_ID, PEAK_MPCI_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, {PEAK_PCI_VENDOR_ID, PEAK_MPCI_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
{PEAK_PCI_VENDOR_ID, PEAK_MPCIE_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
{PEAK_PCI_VENDOR_ID, PEAK_PC_104P_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
{PEAK_PCI_VENDOR_ID, PEAK_PCI_104E_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
{PEAK_PCI_VENDOR_ID, PEAK_CPCI_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
#ifdef CONFIG_CAN_PEAK_PCIEC #ifdef CONFIG_CAN_PEAK_PCIEC
{PEAK_PCI_VENDOR_ID, PEAK_PCIEC_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, {PEAK_PCI_VENDOR_ID, PEAK_PCIEC_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
#endif #endif
......
...@@ -251,6 +251,8 @@ struct adapter_params { ...@@ -251,6 +251,8 @@ struct adapter_params {
unsigned char rev; /* chip revision */ unsigned char rev; /* chip revision */
unsigned char offload; unsigned char offload;
unsigned char bypass;
unsigned int ofldq_wr_cred; unsigned int ofldq_wr_cred;
}; };
...@@ -642,6 +644,23 @@ extern int dbfifo_int_thresh; ...@@ -642,6 +644,23 @@ extern int dbfifo_int_thresh;
#define for_each_port(adapter, iter) \ #define for_each_port(adapter, iter) \
for (iter = 0; iter < (adapter)->params.nports; ++iter) for (iter = 0; iter < (adapter)->params.nports; ++iter)
static inline int is_bypass(struct adapter *adap)
{
return adap->params.bypass;
}
static inline int is_bypass_device(int device)
{
/* this should be set based upon device capabilities */
switch (device) {
case 0x440b:
case 0x440c:
return 1;
default:
return 0;
}
}
static inline unsigned int core_ticks_per_usec(const struct adapter *adap) static inline unsigned int core_ticks_per_usec(const struct adapter *adap)
{ {
return adap->params.vpd.cclk / 1000; return adap->params.vpd.cclk / 1000;
......
...@@ -3513,18 +3513,6 @@ static int adap_init0_no_config(struct adapter *adapter, int reset) ...@@ -3513,18 +3513,6 @@ static int adap_init0_no_config(struct adapter *adapter, int reset)
if (ret < 0) if (ret < 0)
goto bye; goto bye;
#ifndef CONFIG_CHELSIO_T4_OFFLOAD
/*
* If we're a pure NIC driver then disable all offloading facilities.
* This will allow the firmware to optimize aspects of the hardware
* configuration which will result in improved performance.
*/
caps_cmd.ofldcaps = 0;
caps_cmd.iscsicaps = 0;
caps_cmd.rdmacaps = 0;
caps_cmd.fcoecaps = 0;
#endif
if (caps_cmd.niccaps & htons(FW_CAPS_CONFIG_NIC_VM)) { if (caps_cmd.niccaps & htons(FW_CAPS_CONFIG_NIC_VM)) {
if (!vf_acls) if (!vf_acls)
caps_cmd.niccaps ^= htons(FW_CAPS_CONFIG_NIC_VM); caps_cmd.niccaps ^= htons(FW_CAPS_CONFIG_NIC_VM);
...@@ -3745,6 +3733,7 @@ static int adap_init0(struct adapter *adap) ...@@ -3745,6 +3733,7 @@ static int adap_init0(struct adapter *adap)
u32 v, port_vec; u32 v, port_vec;
enum dev_state state; enum dev_state state;
u32 params[7], val[7]; u32 params[7], val[7];
struct fw_caps_config_cmd caps_cmd;
int reset = 1, j; int reset = 1, j;
/* /*
...@@ -3898,6 +3887,9 @@ static int adap_init0(struct adapter *adap) ...@@ -3898,6 +3887,9 @@ static int adap_init0(struct adapter *adap)
goto bye; goto bye;
} }
if (is_bypass_device(adap->pdev->device))
adap->params.bypass = 1;
/* /*
* Grab some of our basic fundamental operating parameters. * Grab some of our basic fundamental operating parameters.
*/ */
...@@ -3940,13 +3932,12 @@ static int adap_init0(struct adapter *adap) ...@@ -3940,13 +3932,12 @@ static int adap_init0(struct adapter *adap)
adap->tids.aftid_end = val[1]; adap->tids.aftid_end = val[1];
} }
#ifdef CONFIG_CHELSIO_T4_OFFLOAD
/* /*
* Get device capabilities so we can determine what resources we need * Get device capabilities so we can determine what resources we need
* to manage. * to manage.
*/ */
memset(&caps_cmd, 0, sizeof(caps_cmd)); memset(&caps_cmd, 0, sizeof(caps_cmd));
caps_cmd.op_to_write = htonl(V_FW_CMD_OP(FW_CAPS_CONFIG_CMD) | caps_cmd.op_to_write = htonl(FW_CMD_OP(FW_CAPS_CONFIG_CMD) |
FW_CMD_REQUEST | FW_CMD_READ); FW_CMD_REQUEST | FW_CMD_READ);
caps_cmd.retval_len16 = htonl(FW_LEN16(caps_cmd)); caps_cmd.retval_len16 = htonl(FW_LEN16(caps_cmd));
ret = t4_wr_mbox(adap, adap->mbox, &caps_cmd, sizeof(caps_cmd), ret = t4_wr_mbox(adap, adap->mbox, &caps_cmd, sizeof(caps_cmd),
...@@ -3991,15 +3982,6 @@ static int adap_init0(struct adapter *adap) ...@@ -3991,15 +3982,6 @@ static int adap_init0(struct adapter *adap)
adap->vres.ddp.size = val[4] - val[3] + 1; adap->vres.ddp.size = val[4] - val[3] + 1;
adap->params.ofldq_wr_cred = val[5]; adap->params.ofldq_wr_cred = val[5];
params[0] = FW_PARAM_PFVF(ETHOFLD_START);
params[1] = FW_PARAM_PFVF(ETHOFLD_END);
ret = t4_query_params(adap, adap->mbox, adap->fn, 0, 2,
params, val);
if ((val[0] != val[1]) && (ret >= 0)) {
adap->tids.uotid_base = val[0];
adap->tids.nuotids = val[1] - val[0] + 1;
}
adap->params.offload = 1; adap->params.offload = 1;
} }
if (caps_cmd.rdmacaps) { if (caps_cmd.rdmacaps) {
...@@ -4048,7 +4030,6 @@ static int adap_init0(struct adapter *adap) ...@@ -4048,7 +4030,6 @@ static int adap_init0(struct adapter *adap)
} }
#undef FW_PARAM_PFVF #undef FW_PARAM_PFVF
#undef FW_PARAM_DEV #undef FW_PARAM_DEV
#endif /* CONFIG_CHELSIO_T4_OFFLOAD */
/* /*
* These are finalized by FW initialization, load their values now. * These are finalized by FW initialization, load their values now.
......
...@@ -102,6 +102,9 @@ struct tid_info { ...@@ -102,6 +102,9 @@ struct tid_info {
unsigned int ftid_base; unsigned int ftid_base;
unsigned int aftid_base; unsigned int aftid_base;
unsigned int aftid_end; unsigned int aftid_end;
/* Server filter region */
unsigned int sftid_base;
unsigned int nsftids;
spinlock_t atid_lock ____cacheline_aligned_in_smp; spinlock_t atid_lock ____cacheline_aligned_in_smp;
union aopen_entry *afree; union aopen_entry *afree;
......
...@@ -478,7 +478,7 @@ static int gianfar_ptp_probe(struct platform_device *dev) ...@@ -478,7 +478,7 @@ static int gianfar_ptp_probe(struct platform_device *dev)
pr_err("no resource\n"); pr_err("no resource\n");
goto no_resource; goto no_resource;
} }
if (request_resource(&ioport_resource, etsects->rsrc)) { if (request_resource(&iomem_resource, etsects->rsrc)) {
pr_err("resource busy\n"); pr_err("resource busy\n");
goto no_resource; goto no_resource;
} }
......
...@@ -143,7 +143,6 @@ void mlx4_en_destroy_tx_ring(struct mlx4_en_priv *priv, ...@@ -143,7 +143,6 @@ void mlx4_en_destroy_tx_ring(struct mlx4_en_priv *priv,
mlx4_bf_free(mdev->dev, &ring->bf); mlx4_bf_free(mdev->dev, &ring->bf);
mlx4_qp_remove(mdev->dev, &ring->qp); mlx4_qp_remove(mdev->dev, &ring->qp);
mlx4_qp_free(mdev->dev, &ring->qp); mlx4_qp_free(mdev->dev, &ring->qp);
mlx4_qp_release_range(mdev->dev, ring->qpn, 1);
mlx4_en_unmap_buffer(&ring->wqres.buf); mlx4_en_unmap_buffer(&ring->wqres.buf);
mlx4_free_hwq_res(mdev->dev, &ring->wqres, ring->buf_size); mlx4_free_hwq_res(mdev->dev, &ring->wqres, ring->buf_size);
kfree(ring->bounce_buf); kfree(ring->bounce_buf);
...@@ -712,7 +711,7 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -712,7 +711,7 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
if (bounce) if (bounce)
tx_desc = mlx4_en_bounce_to_desc(priv, ring, index, desc_size); tx_desc = mlx4_en_bounce_to_desc(priv, ring, index, desc_size);
if (ring->bf_enabled && desc_size <= MAX_BF && !bounce && !vlan_tag) { if (ring->bf_enabled && desc_size <= MAX_BF && !bounce && !vlan_tx_tag_present(skb)) {
*(__be32 *) (&tx_desc->ctrl.vlan_tag) |= cpu_to_be32(ring->doorbell_qpn); *(__be32 *) (&tx_desc->ctrl.vlan_tag) |= cpu_to_be32(ring->doorbell_qpn);
op_own |= htonl((bf_index & 0xffff) << 8); op_own |= htonl((bf_index & 0xffff) << 8);
/* Ensure new descirptor hits memory /* Ensure new descirptor hits memory
......
...@@ -837,6 +837,18 @@ static void __iomem *mlx4_get_eq_uar(struct mlx4_dev *dev, struct mlx4_eq *eq) ...@@ -837,6 +837,18 @@ static void __iomem *mlx4_get_eq_uar(struct mlx4_dev *dev, struct mlx4_eq *eq)
return priv->eq_table.uar_map[index] + 0x800 + 8 * (eq->eqn % 4); return priv->eq_table.uar_map[index] + 0x800 + 8 * (eq->eqn % 4);
} }
static void mlx4_unmap_uar(struct mlx4_dev *dev)
{
struct mlx4_priv *priv = mlx4_priv(dev);
int i;
for (i = 0; i < mlx4_num_eq_uar(dev); ++i)
if (priv->eq_table.uar_map[i]) {
iounmap(priv->eq_table.uar_map[i]);
priv->eq_table.uar_map[i] = NULL;
}
}
static int mlx4_create_eq(struct mlx4_dev *dev, int nent, static int mlx4_create_eq(struct mlx4_dev *dev, int nent,
u8 intr, struct mlx4_eq *eq) u8 intr, struct mlx4_eq *eq)
{ {
...@@ -1201,6 +1213,7 @@ int mlx4_init_eq_table(struct mlx4_dev *dev) ...@@ -1201,6 +1213,7 @@ int mlx4_init_eq_table(struct mlx4_dev *dev)
mlx4_free_irqs(dev); mlx4_free_irqs(dev);
err_out_bitmap: err_out_bitmap:
mlx4_unmap_uar(dev);
mlx4_bitmap_cleanup(&priv->eq_table.bitmap); mlx4_bitmap_cleanup(&priv->eq_table.bitmap);
err_out_free: err_out_free:
...@@ -1225,10 +1238,7 @@ void mlx4_cleanup_eq_table(struct mlx4_dev *dev) ...@@ -1225,10 +1238,7 @@ void mlx4_cleanup_eq_table(struct mlx4_dev *dev)
if (!mlx4_is_slave(dev)) if (!mlx4_is_slave(dev))
mlx4_unmap_clr_int(dev); mlx4_unmap_clr_int(dev);
for (i = 0; i < mlx4_num_eq_uar(dev); ++i) mlx4_unmap_uar(dev);
if (priv->eq_table.uar_map[i])
iounmap(priv->eq_table.uar_map[i]);
mlx4_bitmap_cleanup(&priv->eq_table.bitmap); mlx4_bitmap_cleanup(&priv->eq_table.bitmap);
kfree(priv->eq_table.uar_map); kfree(priv->eq_table.uar_map);
......
...@@ -338,26 +338,6 @@ static void pch_gbe_wait_clr_bit(void *reg, u32 bit) ...@@ -338,26 +338,6 @@ static void pch_gbe_wait_clr_bit(void *reg, u32 bit)
pr_err("Error: busy bit is not cleared\n"); pr_err("Error: busy bit is not cleared\n");
} }
/**
* pch_gbe_wait_clr_bit_irq - Wait to clear a bit for interrupt context
* @reg: Pointer of register
* @busy: Busy bit
*/
static int pch_gbe_wait_clr_bit_irq(void *reg, u32 bit)
{
u32 tmp;
int ret = -1;
/* wait busy */
tmp = 20;
while ((ioread32(reg) & bit) && --tmp)
udelay(5);
if (!tmp)
pr_err("Error: busy bit is not cleared\n");
else
ret = 0;
return ret;
}
/** /**
* pch_gbe_mac_mar_set - Set MAC address register * pch_gbe_mac_mar_set - Set MAC address register
* @hw: Pointer to the HW structure * @hw: Pointer to the HW structure
...@@ -409,15 +389,20 @@ static void pch_gbe_mac_reset_hw(struct pch_gbe_hw *hw) ...@@ -409,15 +389,20 @@ static void pch_gbe_mac_reset_hw(struct pch_gbe_hw *hw)
return; return;
} }
static void pch_gbe_mac_reset_rx(struct pch_gbe_hw *hw) static void pch_gbe_disable_mac_rx(struct pch_gbe_hw *hw)
{ {
/* Read the MAC addresses. and store to the private data */ u32 rctl;
pch_gbe_mac_read_mac_addr(hw); /* Disables Receive MAC */
iowrite32(PCH_GBE_RX_RST, &hw->reg->RESET); rctl = ioread32(&hw->reg->MAC_RX_EN);
pch_gbe_wait_clr_bit_irq(&hw->reg->RESET, PCH_GBE_RX_RST); iowrite32((rctl & ~PCH_GBE_MRE_MAC_RX_EN), &hw->reg->MAC_RX_EN);
/* Setup the MAC addresses */ }
pch_gbe_mac_mar_set(hw, hw->mac.addr, 0);
return; static void pch_gbe_enable_mac_rx(struct pch_gbe_hw *hw)
{
u32 rctl;
/* Enables Receive MAC */
rctl = ioread32(&hw->reg->MAC_RX_EN);
iowrite32((rctl | PCH_GBE_MRE_MAC_RX_EN), &hw->reg->MAC_RX_EN);
} }
/** /**
...@@ -913,7 +898,7 @@ static void pch_gbe_setup_rctl(struct pch_gbe_adapter *adapter) ...@@ -913,7 +898,7 @@ static void pch_gbe_setup_rctl(struct pch_gbe_adapter *adapter)
static void pch_gbe_configure_rx(struct pch_gbe_adapter *adapter) static void pch_gbe_configure_rx(struct pch_gbe_adapter *adapter)
{ {
struct pch_gbe_hw *hw = &adapter->hw; struct pch_gbe_hw *hw = &adapter->hw;
u32 rdba, rdlen, rctl, rxdma; u32 rdba, rdlen, rxdma;
pr_debug("dma adr = 0x%08llx size = 0x%08x\n", pr_debug("dma adr = 0x%08llx size = 0x%08x\n",
(unsigned long long)adapter->rx_ring->dma, (unsigned long long)adapter->rx_ring->dma,
...@@ -921,9 +906,7 @@ static void pch_gbe_configure_rx(struct pch_gbe_adapter *adapter) ...@@ -921,9 +906,7 @@ static void pch_gbe_configure_rx(struct pch_gbe_adapter *adapter)
pch_gbe_mac_force_mac_fc(hw); pch_gbe_mac_force_mac_fc(hw);
/* Disables Receive MAC */ pch_gbe_disable_mac_rx(hw);
rctl = ioread32(&hw->reg->MAC_RX_EN);
iowrite32((rctl & ~PCH_GBE_MRE_MAC_RX_EN), &hw->reg->MAC_RX_EN);
/* Disables Receive DMA */ /* Disables Receive DMA */
rxdma = ioread32(&hw->reg->DMA_CTRL); rxdma = ioread32(&hw->reg->DMA_CTRL);
...@@ -1316,38 +1299,17 @@ void pch_gbe_update_stats(struct pch_gbe_adapter *adapter) ...@@ -1316,38 +1299,17 @@ void pch_gbe_update_stats(struct pch_gbe_adapter *adapter)
spin_unlock_irqrestore(&adapter->stats_lock, flags); spin_unlock_irqrestore(&adapter->stats_lock, flags);
} }
static void pch_gbe_stop_receive(struct pch_gbe_adapter *adapter) static void pch_gbe_disable_dma_rx(struct pch_gbe_hw *hw)
{ {
struct pch_gbe_hw *hw = &adapter->hw;
u32 rxdma; u32 rxdma;
u16 value;
int ret;
/* Disable Receive DMA */ /* Disable Receive DMA */
rxdma = ioread32(&hw->reg->DMA_CTRL); rxdma = ioread32(&hw->reg->DMA_CTRL);
rxdma &= ~PCH_GBE_RX_DMA_EN; rxdma &= ~PCH_GBE_RX_DMA_EN;
iowrite32(rxdma, &hw->reg->DMA_CTRL); iowrite32(rxdma, &hw->reg->DMA_CTRL);
/* Wait Rx DMA BUS is IDLE */
ret = pch_gbe_wait_clr_bit_irq(&hw->reg->RX_DMA_ST, PCH_GBE_IDLE_CHECK);
if (ret) {
/* Disable Bus master */
pci_read_config_word(adapter->pdev, PCI_COMMAND, &value);
value &= ~PCI_COMMAND_MASTER;
pci_write_config_word(adapter->pdev, PCI_COMMAND, value);
/* Stop Receive */
pch_gbe_mac_reset_rx(hw);
/* Enable Bus master */
value |= PCI_COMMAND_MASTER;
pci_write_config_word(adapter->pdev, PCI_COMMAND, value);
} else {
/* Stop Receive */
pch_gbe_mac_reset_rx(hw);
}
/* reprogram multicast address register after reset */
pch_gbe_set_multi(adapter->netdev);
} }
static void pch_gbe_start_receive(struct pch_gbe_hw *hw) static void pch_gbe_enable_dma_rx(struct pch_gbe_hw *hw)
{ {
u32 rxdma; u32 rxdma;
...@@ -1355,9 +1317,6 @@ static void pch_gbe_start_receive(struct pch_gbe_hw *hw) ...@@ -1355,9 +1317,6 @@ static void pch_gbe_start_receive(struct pch_gbe_hw *hw)
rxdma = ioread32(&hw->reg->DMA_CTRL); rxdma = ioread32(&hw->reg->DMA_CTRL);
rxdma |= PCH_GBE_RX_DMA_EN; rxdma |= PCH_GBE_RX_DMA_EN;
iowrite32(rxdma, &hw->reg->DMA_CTRL); iowrite32(rxdma, &hw->reg->DMA_CTRL);
/* Enables Receive */
iowrite32(PCH_GBE_MRE_MAC_RX_EN, &hw->reg->MAC_RX_EN);
return;
} }
/** /**
...@@ -1393,7 +1352,7 @@ static irqreturn_t pch_gbe_intr(int irq, void *data) ...@@ -1393,7 +1352,7 @@ static irqreturn_t pch_gbe_intr(int irq, void *data)
int_en = ioread32(&hw->reg->INT_EN); int_en = ioread32(&hw->reg->INT_EN);
iowrite32((int_en & ~PCH_GBE_INT_RX_FIFO_ERR), iowrite32((int_en & ~PCH_GBE_INT_RX_FIFO_ERR),
&hw->reg->INT_EN); &hw->reg->INT_EN);
pch_gbe_stop_receive(adapter); pch_gbe_disable_dma_rx(&adapter->hw);
int_st |= ioread32(&hw->reg->INT_ST); int_st |= ioread32(&hw->reg->INT_ST);
int_st = int_st & ioread32(&hw->reg->INT_EN); int_st = int_st & ioread32(&hw->reg->INT_EN);
} }
...@@ -1971,12 +1930,12 @@ int pch_gbe_up(struct pch_gbe_adapter *adapter) ...@@ -1971,12 +1930,12 @@ int pch_gbe_up(struct pch_gbe_adapter *adapter)
struct net_device *netdev = adapter->netdev; struct net_device *netdev = adapter->netdev;
struct pch_gbe_tx_ring *tx_ring = adapter->tx_ring; struct pch_gbe_tx_ring *tx_ring = adapter->tx_ring;
struct pch_gbe_rx_ring *rx_ring = adapter->rx_ring; struct pch_gbe_rx_ring *rx_ring = adapter->rx_ring;
int err; int err = -EINVAL;
/* Ensure we have a valid MAC */ /* Ensure we have a valid MAC */
if (!is_valid_ether_addr(adapter->hw.mac.addr)) { if (!is_valid_ether_addr(adapter->hw.mac.addr)) {
pr_err("Error: Invalid MAC address\n"); pr_err("Error: Invalid MAC address\n");
return -EINVAL; goto out;
} }
/* hardware has been reset, we need to reload some things */ /* hardware has been reset, we need to reload some things */
...@@ -1989,18 +1948,19 @@ int pch_gbe_up(struct pch_gbe_adapter *adapter) ...@@ -1989,18 +1948,19 @@ int pch_gbe_up(struct pch_gbe_adapter *adapter)
err = pch_gbe_request_irq(adapter); err = pch_gbe_request_irq(adapter);
if (err) { if (err) {
pr_err("Error: can't bring device up\n"); pr_err("Error: can't bring device up - irq request failed\n");
return err; goto out;
} }
err = pch_gbe_alloc_rx_buffers_pool(adapter, rx_ring, rx_ring->count); err = pch_gbe_alloc_rx_buffers_pool(adapter, rx_ring, rx_ring->count);
if (err) { if (err) {
pr_err("Error: can't bring device up\n"); pr_err("Error: can't bring device up - alloc rx buffers pool failed\n");
return err; goto freeirq;
} }
pch_gbe_alloc_tx_buffers(adapter, tx_ring); pch_gbe_alloc_tx_buffers(adapter, tx_ring);
pch_gbe_alloc_rx_buffers(adapter, rx_ring, rx_ring->count); pch_gbe_alloc_rx_buffers(adapter, rx_ring, rx_ring->count);
adapter->tx_queue_len = netdev->tx_queue_len; adapter->tx_queue_len = netdev->tx_queue_len;
pch_gbe_start_receive(&adapter->hw); pch_gbe_enable_dma_rx(&adapter->hw);
pch_gbe_enable_mac_rx(&adapter->hw);
mod_timer(&adapter->watchdog_timer, jiffies); mod_timer(&adapter->watchdog_timer, jiffies);
...@@ -2009,6 +1969,11 @@ int pch_gbe_up(struct pch_gbe_adapter *adapter) ...@@ -2009,6 +1969,11 @@ int pch_gbe_up(struct pch_gbe_adapter *adapter)
netif_start_queue(adapter->netdev); netif_start_queue(adapter->netdev);
return 0; return 0;
freeirq:
pch_gbe_free_irq(adapter);
out:
return err;
} }
/** /**
...@@ -2405,7 +2370,6 @@ static int pch_gbe_napi_poll(struct napi_struct *napi, int budget) ...@@ -2405,7 +2370,6 @@ static int pch_gbe_napi_poll(struct napi_struct *napi, int budget)
int work_done = 0; int work_done = 0;
bool poll_end_flag = false; bool poll_end_flag = false;
bool cleaned = false; bool cleaned = false;
u32 int_en;
pr_debug("budget : %d\n", budget); pr_debug("budget : %d\n", budget);
...@@ -2422,19 +2386,13 @@ static int pch_gbe_napi_poll(struct napi_struct *napi, int budget) ...@@ -2422,19 +2386,13 @@ static int pch_gbe_napi_poll(struct napi_struct *napi, int budget)
if (poll_end_flag) { if (poll_end_flag) {
napi_complete(napi); napi_complete(napi);
if (adapter->rx_stop_flag) {
adapter->rx_stop_flag = false;
pch_gbe_start_receive(&adapter->hw);
}
pch_gbe_irq_enable(adapter); pch_gbe_irq_enable(adapter);
} else }
if (adapter->rx_stop_flag) {
adapter->rx_stop_flag = false; if (adapter->rx_stop_flag) {
pch_gbe_start_receive(&adapter->hw); adapter->rx_stop_flag = false;
int_en = ioread32(&adapter->hw.reg->INT_EN); pch_gbe_enable_dma_rx(&adapter->hw);
iowrite32((int_en | PCH_GBE_INT_RX_FIFO_ERR), }
&adapter->hw.reg->INT_EN);
}
pr_debug("poll_end_flag : %d work_done : %d budget : %d\n", pr_debug("poll_end_flag : %d work_done : %d budget : %d\n",
poll_end_flag, work_done, budget); poll_end_flag, work_done, budget);
......
...@@ -2525,6 +2525,13 @@ static int ql_alloc_net_req_rsp_queues(struct ql3_adapter *qdev) ...@@ -2525,6 +2525,13 @@ static int ql_alloc_net_req_rsp_queues(struct ql3_adapter *qdev)
qdev->req_q_size = qdev->req_q_size =
(u32) (NUM_REQ_Q_ENTRIES * sizeof(struct ob_mac_iocb_req)); (u32) (NUM_REQ_Q_ENTRIES * sizeof(struct ob_mac_iocb_req));
qdev->rsp_q_size = NUM_RSP_Q_ENTRIES * sizeof(struct net_rsp_iocb);
/* The barrier is required to ensure request and response queue
* addr writes to the registers.
*/
wmb();
qdev->req_q_virt_addr = qdev->req_q_virt_addr =
pci_alloc_consistent(qdev->pdev, pci_alloc_consistent(qdev->pdev,
(size_t) qdev->req_q_size, (size_t) qdev->req_q_size,
...@@ -2536,8 +2543,6 @@ static int ql_alloc_net_req_rsp_queues(struct ql3_adapter *qdev) ...@@ -2536,8 +2543,6 @@ static int ql_alloc_net_req_rsp_queues(struct ql3_adapter *qdev)
return -ENOMEM; return -ENOMEM;
} }
qdev->rsp_q_size = NUM_RSP_Q_ENTRIES * sizeof(struct net_rsp_iocb);
qdev->rsp_q_virt_addr = qdev->rsp_q_virt_addr =
pci_alloc_consistent(qdev->pdev, pci_alloc_consistent(qdev->pdev,
(size_t) qdev->rsp_q_size, (size_t) qdev->rsp_q_size,
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
config NET_VENDOR_TI config NET_VENDOR_TI
bool "Texas Instruments (TI) devices" bool "Texas Instruments (TI) devices"
default y default y
depends on PCI || EISA || AR7 || (ARM && (ARCH_DAVINCI || ARCH_OMAP3)) depends on PCI || EISA || AR7 || (ARM && (ARCH_DAVINCI || ARCH_OMAP3 || SOC_AM33XX))
---help--- ---help---
If you have a network (Ethernet) card belonging to this class, say Y If you have a network (Ethernet) card belonging to this class, say Y
and read the Ethernet-HOWTO, available from and read the Ethernet-HOWTO, available from
......
...@@ -1334,11 +1334,11 @@ static int tso_count_edescs(struct sk_buff *skb) ...@@ -1334,11 +1334,11 @@ static int tso_count_edescs(struct sk_buff *skb)
{ {
struct skb_shared_info *sh = skb_shinfo(skb); struct skb_shared_info *sh = skb_shinfo(skb);
unsigned int sh_len = skb_transport_offset(skb) + tcp_hdrlen(skb); unsigned int sh_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
unsigned int data_len = skb->data_len + skb->hdr_len - sh_len; unsigned int data_len = skb->len - sh_len;
unsigned int p_len = sh->gso_size; unsigned int p_len = sh->gso_size;
long f_id = -1; /* id of the current fragment */ long f_id = -1; /* id of the current fragment */
long f_size = skb->hdr_len; /* size of the current fragment */ long f_size = skb_headlen(skb) - sh_len; /* current fragment size */
long f_used = sh_len; /* bytes used from the current fragment */ long f_used = 0; /* bytes used from the current fragment */
long n; /* size of the current piece of payload */ long n; /* size of the current piece of payload */
int num_edescs = 0; int num_edescs = 0;
int segment; int segment;
...@@ -1353,7 +1353,7 @@ static int tso_count_edescs(struct sk_buff *skb) ...@@ -1353,7 +1353,7 @@ static int tso_count_edescs(struct sk_buff *skb)
/* Advance as needed. */ /* Advance as needed. */
while (f_used >= f_size) { while (f_used >= f_size) {
f_id++; f_id++;
f_size = sh->frags[f_id].size; f_size = skb_frag_size(&sh->frags[f_id]);
f_used = 0; f_used = 0;
} }
...@@ -1384,13 +1384,13 @@ static void tso_headers_prepare(struct sk_buff *skb, unsigned char *headers, ...@@ -1384,13 +1384,13 @@ static void tso_headers_prepare(struct sk_buff *skb, unsigned char *headers,
struct iphdr *ih; struct iphdr *ih;
struct tcphdr *th; struct tcphdr *th;
unsigned int sh_len = skb_transport_offset(skb) + tcp_hdrlen(skb); unsigned int sh_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
unsigned int data_len = skb->data_len + skb->hdr_len - sh_len; unsigned int data_len = skb->len - sh_len;
unsigned char *data = skb->data; unsigned char *data = skb->data;
unsigned int ih_off, th_off, p_len; unsigned int ih_off, th_off, p_len;
unsigned int isum_seed, tsum_seed, id, seq; unsigned int isum_seed, tsum_seed, id, seq;
long f_id = -1; /* id of the current fragment */ long f_id = -1; /* id of the current fragment */
long f_size = skb->hdr_len; /* size of the current fragment */ long f_size = skb_headlen(skb) - sh_len; /* current fragment size */
long f_used = sh_len; /* bytes used from the current fragment */ long f_used = 0; /* bytes used from the current fragment */
long n; /* size of the current piece of payload */ long n; /* size of the current piece of payload */
int segment; int segment;
...@@ -1405,7 +1405,7 @@ static void tso_headers_prepare(struct sk_buff *skb, unsigned char *headers, ...@@ -1405,7 +1405,7 @@ static void tso_headers_prepare(struct sk_buff *skb, unsigned char *headers,
isum_seed = ((0xFFFF - ih->check) + isum_seed = ((0xFFFF - ih->check) +
(0xFFFF - ih->tot_len) + (0xFFFF - ih->tot_len) +
(0xFFFF - ih->id)); (0xFFFF - ih->id));
tsum_seed = th->check + (0xFFFF ^ htons(sh_len + data_len)); tsum_seed = th->check + (0xFFFF ^ htons(skb->len));
id = ntohs(ih->id); id = ntohs(ih->id);
seq = ntohl(th->seq); seq = ntohl(th->seq);
...@@ -1444,7 +1444,7 @@ static void tso_headers_prepare(struct sk_buff *skb, unsigned char *headers, ...@@ -1444,7 +1444,7 @@ static void tso_headers_prepare(struct sk_buff *skb, unsigned char *headers,
/* Advance as needed. */ /* Advance as needed. */
while (f_used >= f_size) { while (f_used >= f_size) {
f_id++; f_id++;
f_size = sh->frags[f_id].size; f_size = skb_frag_size(&sh->frags[f_id]);
f_used = 0; f_used = 0;
} }
...@@ -1478,14 +1478,14 @@ static void tso_egress(struct net_device *dev, gxio_mpipe_equeue_t *equeue, ...@@ -1478,14 +1478,14 @@ static void tso_egress(struct net_device *dev, gxio_mpipe_equeue_t *equeue,
struct tile_net_priv *priv = netdev_priv(dev); struct tile_net_priv *priv = netdev_priv(dev);
struct skb_shared_info *sh = skb_shinfo(skb); struct skb_shared_info *sh = skb_shinfo(skb);
unsigned int sh_len = skb_transport_offset(skb) + tcp_hdrlen(skb); unsigned int sh_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
unsigned int data_len = skb->data_len + skb->hdr_len - sh_len; unsigned int data_len = skb->len - sh_len;
unsigned int p_len = sh->gso_size; unsigned int p_len = sh->gso_size;
gxio_mpipe_edesc_t edesc_head = { { 0 } }; gxio_mpipe_edesc_t edesc_head = { { 0 } };
gxio_mpipe_edesc_t edesc_body = { { 0 } }; gxio_mpipe_edesc_t edesc_body = { { 0 } };
long f_id = -1; /* id of the current fragment */ long f_id = -1; /* id of the current fragment */
long f_size = skb->hdr_len; /* size of the current fragment */ long f_size = skb_headlen(skb) - sh_len; /* current fragment size */
long f_used = sh_len; /* bytes used from the current fragment */ long f_used = 0; /* bytes used from the current fragment */
void *f_data = skb->data; void *f_data = skb->data + sh_len;
long n; /* size of the current piece of payload */ long n; /* size of the current piece of payload */
unsigned long tx_packets = 0, tx_bytes = 0; unsigned long tx_packets = 0, tx_bytes = 0;
unsigned int csum_start; unsigned int csum_start;
...@@ -1516,15 +1516,18 @@ static void tso_egress(struct net_device *dev, gxio_mpipe_equeue_t *equeue, ...@@ -1516,15 +1516,18 @@ static void tso_egress(struct net_device *dev, gxio_mpipe_equeue_t *equeue,
/* Egress the payload. */ /* Egress the payload. */
while (p_used < p_len) { while (p_used < p_len) {
void *va;
/* Advance as needed. */ /* Advance as needed. */
while (f_used >= f_size) { while (f_used >= f_size) {
f_id++; f_id++;
f_size = sh->frags[f_id].size; f_size = skb_frag_size(&sh->frags[f_id]);
f_used = 0;
f_data = tile_net_frag_buf(&sh->frags[f_id]); f_data = tile_net_frag_buf(&sh->frags[f_id]);
f_used = 0;
} }
va = f_data + f_used;
/* Use bytes from the current fragment. */ /* Use bytes from the current fragment. */
n = p_len - p_used; n = p_len - p_used;
if (n > f_size - f_used) if (n > f_size - f_used)
...@@ -1533,7 +1536,7 @@ static void tso_egress(struct net_device *dev, gxio_mpipe_equeue_t *equeue, ...@@ -1533,7 +1536,7 @@ static void tso_egress(struct net_device *dev, gxio_mpipe_equeue_t *equeue,
p_used += n; p_used += n;
/* Egress a piece of the payload. */ /* Egress a piece of the payload. */
edesc_body.va = va_to_tile_io_addr(f_data) + f_used; edesc_body.va = va_to_tile_io_addr(va);
edesc_body.xfer_size = n; edesc_body.xfer_size = n;
edesc_body.bound = !(p_used < p_len); edesc_body.bound = !(p_used < p_len);
gxio_mpipe_equeue_put_at(equeue, edesc_body, slot); gxio_mpipe_equeue_put_at(equeue, edesc_body, slot);
......
...@@ -15,6 +15,11 @@ if PHYLIB ...@@ -15,6 +15,11 @@ if PHYLIB
comment "MII PHY device drivers" comment "MII PHY device drivers"
config AT803X_PHY
tristate "Drivers for Atheros AT803X PHYs"
---help---
Currently supports the AT8030 and AT8035 model
config AMD_PHY config AMD_PHY
tristate "Drivers for the AMD PHYs" tristate "Drivers for the AMD PHYs"
---help--- ---help---
......
...@@ -25,6 +25,7 @@ obj-$(CONFIG_STE10XP) += ste10Xp.o ...@@ -25,6 +25,7 @@ obj-$(CONFIG_STE10XP) += ste10Xp.o
obj-$(CONFIG_MICREL_PHY) += micrel.o obj-$(CONFIG_MICREL_PHY) += micrel.o
obj-$(CONFIG_MDIO_OCTEON) += mdio-octeon.o obj-$(CONFIG_MDIO_OCTEON) += mdio-octeon.o
obj-$(CONFIG_MICREL_KS8995MA) += spi_ks8995.o obj-$(CONFIG_MICREL_KS8995MA) += spi_ks8995.o
obj-$(CONFIG_AT803X_PHY) += at803x.o
obj-$(CONFIG_AMD_PHY) += amd.o obj-$(CONFIG_AMD_PHY) += amd.o
obj-$(CONFIG_MDIO_BUS_MUX) += mdio-mux.o obj-$(CONFIG_MDIO_BUS_MUX) += mdio-mux.o
obj-$(CONFIG_MDIO_BUS_MUX_GPIO) += mdio-mux-gpio.o obj-$(CONFIG_MDIO_BUS_MUX_GPIO) += mdio-mux-gpio.o
......
/*
* drivers/net/phy/at803x.c
*
* Driver for Atheros 803x PHY
*
* Author: Matus Ujhelyi <ujhelyi.m@gmail.com>
*
* 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; either version 2 of the License, or (at your
* option) any later version.
*/
#include <linux/phy.h>
#include <linux/module.h>
#include <linux/string.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#define AT803X_INTR_ENABLE 0x12
#define AT803X_INTR_STATUS 0x13
#define AT803X_WOL_ENABLE 0x01
#define AT803X_DEVICE_ADDR 0x03
#define AT803X_LOC_MAC_ADDR_0_15_OFFSET 0x804C
#define AT803X_LOC_MAC_ADDR_16_31_OFFSET 0x804B
#define AT803X_LOC_MAC_ADDR_32_47_OFFSET 0x804A
#define AT803X_MMD_ACCESS_CONTROL 0x0D
#define AT803X_MMD_ACCESS_CONTROL_DATA 0x0E
#define AT803X_FUNC_DATA 0x4003
MODULE_DESCRIPTION("Atheros 803x PHY driver");
MODULE_AUTHOR("Matus Ujhelyi");
MODULE_LICENSE("GPL");
static void at803x_set_wol_mac_addr(struct phy_device *phydev)
{
struct net_device *ndev = phydev->attached_dev;
const u8 *mac;
unsigned int i, offsets[] = {
AT803X_LOC_MAC_ADDR_32_47_OFFSET,
AT803X_LOC_MAC_ADDR_16_31_OFFSET,
AT803X_LOC_MAC_ADDR_0_15_OFFSET,
};
if (!ndev)
return;
mac = (const u8 *) ndev->dev_addr;
if (!is_valid_ether_addr(mac))
return;
for (i = 0; i < 3; i++) {
phy_write(phydev, AT803X_MMD_ACCESS_CONTROL,
AT803X_DEVICE_ADDR);
phy_write(phydev, AT803X_MMD_ACCESS_CONTROL_DATA,
offsets[i]);
phy_write(phydev, AT803X_MMD_ACCESS_CONTROL,
AT803X_FUNC_DATA);
phy_write(phydev, AT803X_MMD_ACCESS_CONTROL_DATA,
mac[(i * 2) + 1] | (mac[(i * 2)] << 8));
}
}
static int at803x_config_init(struct phy_device *phydev)
{
int val;
u32 features;
int status;
features = SUPPORTED_TP | SUPPORTED_MII | SUPPORTED_AUI |
SUPPORTED_FIBRE | SUPPORTED_BNC;
val = phy_read(phydev, MII_BMSR);
if (val < 0)
return val;
if (val & BMSR_ANEGCAPABLE)
features |= SUPPORTED_Autoneg;
if (val & BMSR_100FULL)
features |= SUPPORTED_100baseT_Full;
if (val & BMSR_100HALF)
features |= SUPPORTED_100baseT_Half;
if (val & BMSR_10FULL)
features |= SUPPORTED_10baseT_Full;
if (val & BMSR_10HALF)
features |= SUPPORTED_10baseT_Half;
if (val & BMSR_ESTATEN) {
val = phy_read(phydev, MII_ESTATUS);
if (val < 0)
return val;
if (val & ESTATUS_1000_TFULL)
features |= SUPPORTED_1000baseT_Full;
if (val & ESTATUS_1000_THALF)
features |= SUPPORTED_1000baseT_Half;
}
phydev->supported = features;
phydev->advertising = features;
/* enable WOL */
at803x_set_wol_mac_addr(phydev);
status = phy_write(phydev, AT803X_INTR_ENABLE, AT803X_WOL_ENABLE);
status = phy_read(phydev, AT803X_INTR_STATUS);
return 0;
}
/* ATHEROS 8035 */
static struct phy_driver at8035_driver = {
.phy_id = 0x004dd072,
.name = "Atheros 8035 ethernet",
.phy_id_mask = 0xffffffef,
.config_init = at803x_config_init,
.features = PHY_GBIT_FEATURES,
.flags = PHY_HAS_INTERRUPT,
.config_aneg = &genphy_config_aneg,
.read_status = &genphy_read_status,
.driver = {
.owner = THIS_MODULE,
},
};
/* ATHEROS 8030 */
static struct phy_driver at8030_driver = {
.phy_id = 0x004dd076,
.name = "Atheros 8030 ethernet",
.phy_id_mask = 0xffffffef,
.config_init = at803x_config_init,
.features = PHY_GBIT_FEATURES,
.flags = PHY_HAS_INTERRUPT,
.config_aneg = &genphy_config_aneg,
.read_status = &genphy_read_status,
.driver = {
.owner = THIS_MODULE,
},
};
static int __init atheros_init(void)
{
int ret;
ret = phy_driver_register(&at8035_driver);
if (ret)
goto err1;
ret = phy_driver_register(&at8030_driver);
if (ret)
goto err2;
return 0;
err2:
phy_driver_unregister(&at8035_driver);
err1:
return ret;
}
static void __exit atheros_exit(void)
{
phy_driver_unregister(&at8035_driver);
phy_driver_unregister(&at8030_driver);
}
module_init(atheros_init);
module_exit(atheros_exit);
static struct mdio_device_id __maybe_unused atheros_tbl[] = {
{ 0x004dd076, 0xffffffef },
{ 0x004dd072, 0xffffffef },
{ }
};
MODULE_DEVICE_TABLE(mdio, atheros_tbl);
...@@ -592,6 +592,32 @@ static const struct usb_device_id products [] = { ...@@ -592,6 +592,32 @@ static const struct usb_device_id products [] = {
.driver_info = 0, .driver_info = 0,
}, },
/* Novatel USB551L and MC551 - handled by qmi_wwan */
{
.match_flags = USB_DEVICE_ID_MATCH_VENDOR
| USB_DEVICE_ID_MATCH_PRODUCT
| USB_DEVICE_ID_MATCH_INT_INFO,
.idVendor = NOVATEL_VENDOR_ID,
.idProduct = 0xB001,
.bInterfaceClass = USB_CLASS_COMM,
.bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET,
.bInterfaceProtocol = USB_CDC_PROTO_NONE,
.driver_info = 0,
},
/* Novatel E362 - handled by qmi_wwan */
{
.match_flags = USB_DEVICE_ID_MATCH_VENDOR
| USB_DEVICE_ID_MATCH_PRODUCT
| USB_DEVICE_ID_MATCH_INT_INFO,
.idVendor = NOVATEL_VENDOR_ID,
.idProduct = 0x9010,
.bInterfaceClass = USB_CLASS_COMM,
.bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET,
.bInterfaceProtocol = USB_CDC_PROTO_NONE,
.driver_info = 0,
},
/* /*
* WHITELIST!!! * WHITELIST!!!
* *
...@@ -604,21 +630,6 @@ static const struct usb_device_id products [] = { ...@@ -604,21 +630,6 @@ static const struct usb_device_id products [] = {
* because of bugs/quirks in a given product (like Zaurus, above). * because of bugs/quirks in a given product (like Zaurus, above).
*/ */
{ {
/* Novatel USB551L */
/* This match must come *before* the generic CDC-ETHER match so that
* we get FLAG_WWAN set on the device, since it's descriptors are
* generic CDC-ETHER.
*/
.match_flags = USB_DEVICE_ID_MATCH_VENDOR
| USB_DEVICE_ID_MATCH_PRODUCT
| USB_DEVICE_ID_MATCH_INT_INFO,
.idVendor = NOVATEL_VENDOR_ID,
.idProduct = 0xB001,
.bInterfaceClass = USB_CLASS_COMM,
.bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET,
.bInterfaceProtocol = USB_CDC_PROTO_NONE,
.driver_info = (unsigned long)&wwan_info,
}, {
/* ZTE (Vodafone) K3805-Z */ /* ZTE (Vodafone) K3805-Z */
.match_flags = USB_DEVICE_ID_MATCH_VENDOR .match_flags = USB_DEVICE_ID_MATCH_VENDOR
| USB_DEVICE_ID_MATCH_PRODUCT | USB_DEVICE_ID_MATCH_PRODUCT
......
...@@ -62,6 +62,7 @@ ...@@ -62,6 +62,7 @@
#define USB_PRODUCT_IPAD 0x129a #define USB_PRODUCT_IPAD 0x129a
#define USB_PRODUCT_IPHONE_4_VZW 0x129c #define USB_PRODUCT_IPHONE_4_VZW 0x129c
#define USB_PRODUCT_IPHONE_4S 0x12a0 #define USB_PRODUCT_IPHONE_4S 0x12a0
#define USB_PRODUCT_IPHONE_5 0x12a8
#define IPHETH_USBINTF_CLASS 255 #define IPHETH_USBINTF_CLASS 255
#define IPHETH_USBINTF_SUBCLASS 253 #define IPHETH_USBINTF_SUBCLASS 253
...@@ -113,6 +114,10 @@ static struct usb_device_id ipheth_table[] = { ...@@ -113,6 +114,10 @@ static struct usb_device_id ipheth_table[] = {
USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_4S, USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_4S,
IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS,
IPHETH_USBINTF_PROTO) }, IPHETH_USBINTF_PROTO) },
{ USB_DEVICE_AND_INTERFACE_INFO(
USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_5,
IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS,
IPHETH_USBINTF_PROTO) },
{ } { }
}; };
MODULE_DEVICE_TABLE(usb, ipheth_table); MODULE_DEVICE_TABLE(usb, ipheth_table);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment