.rxQoSMode = UCC_GETH_QOS_MODE_DEFAULT,
.aufc = UPSMR_AUTOMATIC_FLOW_CONTROL_MODE_NONE,
.padAndCrc = MACCFG2_PAD_AND_CRC_MODE_PAD_AND_CRC,
- .numThreadsTx = UCC_GETH_NUM_OF_THREADS_4,
- .numThreadsRx = UCC_GETH_NUM_OF_THREADS_4,
+ .numThreadsTx = UCC_GETH_NUM_OF_THREADS_1,
+ .numThreadsRx = UCC_GETH_NUM_OF_THREADS_1,
.riscTx = QE_RISC_ALLOCATION_RISC1_AND_RISC2,
.riscRx = QE_RISC_ALLOCATION_RISC1_AND_RISC2,
};
if ((ugeth->phy_interface == PHY_INTERFACE_MODE_RMII) ||
(ugeth->phy_interface == PHY_INTERFACE_MODE_RGMII) ||
(ugeth->phy_interface == PHY_INTERFACE_MODE_RGMII_ID) ||
+ (ugeth->phy_interface == PHY_INTERFACE_MODE_RGMII_RXID) ||
+ (ugeth->phy_interface == PHY_INTERFACE_MODE_RGMII_TXID) ||
(ugeth->phy_interface == PHY_INTERFACE_MODE_RTBI)) {
upsmr |= UPSMR_RPM;
switch (ugeth->max_speed) {
if ((ugeth->phy_interface == PHY_INTERFACE_MODE_RMII) ||
(ugeth->phy_interface == PHY_INTERFACE_MODE_RGMII) ||
(ugeth->phy_interface == PHY_INTERFACE_MODE_RGMII_ID) ||
+ (ugeth->phy_interface == PHY_INTERFACE_MODE_RGMII_RXID) ||
+ (ugeth->phy_interface == PHY_INTERFACE_MODE_RGMII_TXID) ||
(ugeth->phy_interface == PHY_INTERFACE_MODE_RTBI)) {
if (phydev->speed == SPEED_10)
upsmr |= UPSMR_R10M;
if (!ugeth)
return;
- if (ugeth->uccf)
+ if (ugeth->uccf) {
ucc_fast_free(ugeth->uccf);
+ ugeth->uccf = NULL;
+ }
if (ugeth->p_thread_data_tx) {
qe_muram_free(ugeth->thread_dat_tx_offset);
ug_info = ugeth->ug_info;
uf_info = &ug_info->uf_info;
- /* Create CQs for hash tables */
- INIT_LIST_HEAD(&ugeth->group_hash_q);
- INIT_LIST_HEAD(&ugeth->ind_hash_q);
-
if (!((uf_info->bd_mem_part == MEM_PART_SYSTEM) ||
(uf_info->bd_mem_part == MEM_PART_MURAM))) {
if (netif_msg_probe(ugeth))
u16 length, howmany = 0;
u32 bd_status;
u8 *bdBuffer;
- struct net_device * dev;
+ struct net_device *dev;
ugeth_vdbg("%s: IN", __FUNCTION__);
ugeth_vdbg("%s: IN", __FUNCTION__);
- if (!ugeth)
- return IRQ_NONE;
-
uccf = ugeth->uccf;
ug_info = ugeth->ug_info;
return IRQ_HANDLED;
}
+#ifdef CONFIG_NET_POLL_CONTROLLER
+/*
+ * Polling 'interrupt' - used by things like netconsole to send skbs
+ * without having to re-enable interrupts. It's not called while
+ * the interrupt routine is executing.
+ */
+static void ucc_netpoll(struct net_device *dev)
+{
+ struct ucc_geth_private *ugeth = netdev_priv(dev);
+ int irq = ugeth->ug_info->uf_info.irq;
+
+ disable_irq(irq);
+ ucc_geth_irq_handler(irq, dev);
+ enable_irq(irq);
+}
+#endif /* CONFIG_NET_POLL_CONTROLLER */
+
/* Called when something needs to use the ethernet device */
/* Returns 0 for success. */
static int ucc_geth_open(struct net_device *dev)
return PHY_INTERFACE_MODE_RGMII;
if (strcasecmp(phy_connection_type, "rgmii-id") == 0)
return PHY_INTERFACE_MODE_RGMII_ID;
+ if (strcasecmp(phy_connection_type, "rgmii-txid") == 0)
+ return PHY_INTERFACE_MODE_RGMII_TXID;
+ if (strcasecmp(phy_connection_type, "rgmii-rxid") == 0)
+ return PHY_INTERFACE_MODE_RGMII_RXID;
if (strcasecmp(phy_connection_type, "rtbi") == 0)
return PHY_INTERFACE_MODE_RTBI;
int err, ucc_num, max_speed = 0;
const phandle *ph;
const unsigned int *prop;
+ const char *sprop;
const void *mac_addr;
phy_interface_t phy_interface;
static const int enet_to_speed[] = {
ug_info->uf_info.ucc_num = ucc_num;
- prop = of_get_property(np, "rx-clock", NULL);
- ug_info->uf_info.rx_clock = *prop;
- prop = of_get_property(np, "tx-clock", NULL);
- ug_info->uf_info.tx_clock = *prop;
+ sprop = of_get_property(np, "rx-clock-name", NULL);
+ if (sprop) {
+ ug_info->uf_info.rx_clock = qe_clock_source(sprop);
+ if ((ug_info->uf_info.rx_clock < QE_CLK_NONE) ||
+ (ug_info->uf_info.rx_clock > QE_CLK24)) {
+ printk(KERN_ERR
+ "ucc_geth: invalid rx-clock-name property\n");
+ return -EINVAL;
+ }
+ } else {
+ prop = of_get_property(np, "rx-clock", NULL);
+ if (!prop) {
+ /* If both rx-clock-name and rx-clock are missing,
+ we want to tell people to use rx-clock-name. */
+ printk(KERN_ERR
+ "ucc_geth: missing rx-clock-name property\n");
+ return -EINVAL;
+ }
+ if ((*prop < QE_CLK_NONE) || (*prop > QE_CLK24)) {
+ printk(KERN_ERR
+ "ucc_geth: invalid rx-clock propperty\n");
+ return -EINVAL;
+ }
+ ug_info->uf_info.rx_clock = *prop;
+ }
+
+ sprop = of_get_property(np, "tx-clock-name", NULL);
+ if (sprop) {
+ ug_info->uf_info.tx_clock = qe_clock_source(sprop);
+ if ((ug_info->uf_info.tx_clock < QE_CLK_NONE) ||
+ (ug_info->uf_info.tx_clock > QE_CLK24)) {
+ printk(KERN_ERR
+ "ucc_geth: invalid tx-clock-name property\n");
+ return -EINVAL;
+ }
+ } else {
+ prop = of_get_property(np, "rx-clock", NULL);
+ if (!prop) {
+ printk(KERN_ERR
+ "ucc_geth: mising tx-clock-name property\n");
+ return -EINVAL;
+ }
+ if ((*prop < QE_CLK_NONE) || (*prop > QE_CLK24)) {
+ printk(KERN_ERR
+ "ucc_geth: invalid tx-clock property\n");
+ return -EINVAL;
+ }
+ ug_info->uf_info.tx_clock = *prop;
+ }
+
err = of_address_to_resource(np, 0, &res);
if (err)
return -EINVAL;
case PHY_INTERFACE_MODE_GMII:
case PHY_INTERFACE_MODE_RGMII:
case PHY_INTERFACE_MODE_RGMII_ID:
+ case PHY_INTERFACE_MODE_RGMII_RXID:
+ case PHY_INTERFACE_MODE_RGMII_TXID:
case PHY_INTERFACE_MODE_TBI:
case PHY_INTERFACE_MODE_RTBI:
max_speed = SPEED_1000;
ug_info->uf_info.utfs = UCC_GETH_UTFS_GIGA_INIT;
ug_info->uf_info.utfet = UCC_GETH_UTFET_GIGA_INIT;
ug_info->uf_info.utftt = UCC_GETH_UTFTT_GIGA_INIT;
+ ug_info->numThreadsTx = UCC_GETH_NUM_OF_THREADS_4;
+ ug_info->numThreadsRx = UCC_GETH_NUM_OF_THREADS_4;
}
/* Set the bus id */
ugeth = netdev_priv(dev);
spin_lock_init(&ugeth->lock);
+ /* Create CQs for hash tables */
+ INIT_LIST_HEAD(&ugeth->group_hash_q);
+ INIT_LIST_HEAD(&ugeth->ind_hash_q);
+
dev_set_drvdata(device, dev);
/* Set the dev->base_addr to the gfar reg region */
#ifdef CONFIG_UGETH_NAPI
netif_napi_add(dev, &ugeth->napi, ucc_geth_poll, UCC_GETH_DEV_WEIGHT);
#endif /* CONFIG_UGETH_NAPI */
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ dev->poll_controller = ucc_netpoll;
+#endif
dev->stop = ucc_geth_close;
// dev->change_mtu = ucc_geth_change_mtu;
dev->mtu = 1500;
struct net_device *dev = dev_get_drvdata(device);
struct ucc_geth_private *ugeth = netdev_priv(dev);
- dev_set_drvdata(device, NULL);
- ucc_geth_memclean(ugeth);
+ unregister_netdev(dev);
free_netdev(dev);
+ ucc_geth_memclean(ugeth);
+ dev_set_drvdata(device, NULL);
return 0;
}