aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/netxen/netxen_nic_hw.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/netxen/netxen_nic_hw.c')
-rw-r--r--drivers/net/netxen/netxen_nic_hw.c198
1 files changed, 183 insertions, 15 deletions
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c
index d46b4dff783d..9d4e9c9dbe0a 100644
--- a/drivers/net/netxen/netxen_nic_hw.c
+++ b/drivers/net/netxen/netxen_nic_hw.c
@@ -314,8 +314,10 @@ int netxen_nic_set_mac(struct net_device *netdev, void *p)
314 314
315 memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); 315 memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
316 316
317 if (adapter->macaddr_set) 317 /* For P3, MAC addr is not set in NIU */
318 adapter->macaddr_set(adapter, addr->sa_data); 318 if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
319 if (adapter->macaddr_set)
320 adapter->macaddr_set(adapter, addr->sa_data);
319 321
320 return 0; 322 return 0;
321} 323}
@@ -405,10 +407,7 @@ netxen_nic_set_mcast_addr(struct netxen_adapter *adapter,
405 return 0; 407 return 0;
406} 408}
407 409
408/* 410void netxen_p2_nic_set_multi(struct net_device *netdev)
409 * netxen_nic_set_multi - Multicast
410 */
411void netxen_nic_set_multi(struct net_device *netdev)
412{ 411{
413 struct netxen_adapter *adapter = netdev_priv(netdev); 412 struct netxen_adapter *adapter = netdev_priv(netdev);
414 struct dev_mc_list *mc_ptr; 413 struct dev_mc_list *mc_ptr;
@@ -456,18 +455,186 @@ void netxen_nic_set_multi(struct net_device *netdev)
456 netxen_nic_set_mcast_addr(adapter, index, null_addr); 455 netxen_nic_set_mcast_addr(adapter, index, null_addr);
457} 456}
458 457
458static int nx_p3_nic_add_mac(struct netxen_adapter *adapter,
459 u8 *addr, nx_mac_list_t **add_list, nx_mac_list_t **del_list)
460{
461 nx_mac_list_t *cur, *prev;
462
463 /* if in del_list, move it to adapter->mac_list */
464 for (cur = *del_list, prev = NULL; cur;) {
465 if (memcmp(addr, cur->mac_addr, ETH_ALEN) == 0) {
466 if (prev == NULL)
467 *del_list = cur->next;
468 else
469 prev->next = cur->next;
470 cur->next = adapter->mac_list;
471 adapter->mac_list = cur;
472 return 0;
473 }
474 prev = cur;
475 cur = cur->next;
476 }
477
478 /* make sure to add each mac address only once */
479 for (cur = adapter->mac_list; cur; cur = cur->next) {
480 if (memcmp(addr, cur->mac_addr, ETH_ALEN) == 0)
481 return 0;
482 }
483 /* not in del_list, create new entry and add to add_list */
484 cur = kmalloc(sizeof(*cur), in_atomic()? GFP_ATOMIC : GFP_KERNEL);
485 if (cur == NULL) {
486 printk(KERN_ERR "%s: cannot allocate memory. MAC filtering may"
487 "not work properly from now.\n", __func__);
488 return -1;
489 }
490
491 memcpy(cur->mac_addr, addr, ETH_ALEN);
492 cur->next = *add_list;
493 *add_list = cur;
494 return 0;
495}
496
497static int
498netxen_send_cmd_descs(struct netxen_adapter *adapter,
499 struct cmd_desc_type0 *cmd_desc_arr, int nr_elements)
500{
501 uint32_t i, producer;
502 struct netxen_cmd_buffer *pbuf;
503 struct cmd_desc_type0 *cmd_desc;
504
505 if (nr_elements > MAX_PENDING_DESC_BLOCK_SIZE || nr_elements == 0) {
506 printk(KERN_WARNING "%s: Too many command descriptors in a "
507 "request\n", __func__);
508 return -EINVAL;
509 }
510
511 i = 0;
512
513 producer = adapter->cmd_producer;
514 do {
515 cmd_desc = &cmd_desc_arr[i];
516
517 pbuf = &adapter->cmd_buf_arr[producer];
518 pbuf->mss = 0;
519 pbuf->total_length = 0;
520 pbuf->skb = NULL;
521 pbuf->cmd = 0;
522 pbuf->frag_count = 0;
523 pbuf->port = 0;
524
525 /* adapter->ahw.cmd_desc_head[producer] = *cmd_desc; */
526 memcpy(&adapter->ahw.cmd_desc_head[producer],
527 &cmd_desc_arr[i], sizeof(struct cmd_desc_type0));
528
529 producer = get_next_index(producer,
530 adapter->max_tx_desc_count);
531 i++;
532
533 } while (i != nr_elements);
534
535 adapter->cmd_producer = producer;
536
537 /* write producer index to start the xmit */
538
539 netxen_nic_update_cmd_producer(adapter, adapter->cmd_producer);
540
541 return 0;
542}
543
544#define NIC_REQUEST 0x14
545#define NETXEN_MAC_EVENT 0x1
546
547static int nx_p3_sre_macaddr_change(struct net_device *dev,
548 u8 *addr, unsigned op)
549{
550 struct netxen_adapter *adapter = (struct netxen_adapter *)dev->priv;
551 nx_nic_req_t req;
552 nx_mac_req_t mac_req;
553 int rv;
554
555 memset(&req, 0, sizeof(nx_nic_req_t));
556 req.qhdr |= (NIC_REQUEST << 23);
557 req.req_hdr |= NETXEN_MAC_EVENT;
558 req.req_hdr |= ((u64)adapter->portnum << 16);
559 mac_req.op = op;
560 memcpy(&mac_req.mac_addr, addr, 6);
561 req.words[0] = cpu_to_le64(*(u64 *)&mac_req);
562
563 rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
564 if (rv != 0) {
565 printk(KERN_ERR "ERROR. Could not send mac update\n");
566 return rv;
567 }
568
569 return 0;
570}
571
572void netxen_p3_nic_set_multi(struct net_device *netdev)
573{
574 struct netxen_adapter *adapter = netdev_priv(netdev);
575 nx_mac_list_t *cur, *next, *del_list, *add_list = NULL;
576 struct dev_mc_list *mc_ptr;
577 u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
578
579 adapter->set_promisc(adapter, NETXEN_NIU_PROMISC_MODE);
580
581 /*
582 * Programming mac addresses will automaticly enabling L2 filtering.
583 * HW will replace timestamp with L2 conid when L2 filtering is
584 * enabled. This causes problem for LSA. Do not enabling L2 filtering
585 * until that problem is fixed.
586 */
587 if ((netdev->flags & IFF_PROMISC) ||
588 (netdev->mc_count > adapter->max_mc_count))
589 return;
590
591 del_list = adapter->mac_list;
592 adapter->mac_list = NULL;
593
594 nx_p3_nic_add_mac(adapter, netdev->dev_addr, &add_list, &del_list);
595 if (netdev->mc_count > 0) {
596 nx_p3_nic_add_mac(adapter, bcast_addr, &add_list, &del_list);
597 for (mc_ptr = netdev->mc_list; mc_ptr;
598 mc_ptr = mc_ptr->next) {
599 nx_p3_nic_add_mac(adapter, mc_ptr->dmi_addr,
600 &add_list, &del_list);
601 }
602 }
603 for (cur = del_list; cur;) {
604 nx_p3_sre_macaddr_change(netdev, cur->mac_addr, NETXEN_MAC_DEL);
605 next = cur->next;
606 kfree(cur);
607 cur = next;
608 }
609 for (cur = add_list; cur;) {
610 nx_p3_sre_macaddr_change(netdev, cur->mac_addr, NETXEN_MAC_ADD);
611 next = cur->next;
612 cur->next = adapter->mac_list;
613 adapter->mac_list = cur;
614 cur = next;
615 }
616}
617
459/* 618/*
460 * netxen_nic_change_mtu - Change the Maximum Transfer Unit 619 * netxen_nic_change_mtu - Change the Maximum Transfer Unit
461 * @returns 0 on success, negative on failure 620 * @returns 0 on success, negative on failure
462 */ 621 */
622
623#define MTU_FUDGE_FACTOR 100
624
463int netxen_nic_change_mtu(struct net_device *netdev, int mtu) 625int netxen_nic_change_mtu(struct net_device *netdev, int mtu)
464{ 626{
465 struct netxen_adapter *adapter = netdev_priv(netdev); 627 struct netxen_adapter *adapter = netdev_priv(netdev);
466 int eff_mtu = mtu + NETXEN_ENET_HEADER_SIZE + NETXEN_ETH_FCS_SIZE; 628 int max_mtu;
467 629
468 if ((eff_mtu > NETXEN_MAX_MTU) || (eff_mtu < NETXEN_MIN_MTU)) { 630 if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
469 printk(KERN_ERR "%s: %s %d is not supported.\n", 631 max_mtu = P3_MAX_MTU;
470 netxen_nic_driver_name, netdev->name, mtu); 632 else
633 max_mtu = P2_MAX_MTU;
634
635 if (mtu > max_mtu) {
636 printk(KERN_ERR "%s: mtu > %d bytes unsupported\n",
637 netdev->name, max_mtu);
471 return -EINVAL; 638 return -EINVAL;
472 } 639 }
473 640
@@ -475,6 +642,12 @@ int netxen_nic_change_mtu(struct net_device *netdev, int mtu)
475 adapter->set_mtu(adapter, mtu); 642 adapter->set_mtu(adapter, mtu);
476 netdev->mtu = mtu; 643 netdev->mtu = mtu;
477 644
645 mtu += MTU_FUDGE_FACTOR;
646 if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
647 nx_fw_cmd_set_mtu(adapter, mtu);
648 else if (adapter->set_mtu)
649 adapter->set_mtu(adapter, mtu);
650
478 return 0; 651 return 0;
479} 652}
480 653
@@ -1882,11 +2055,6 @@ int netxen_nic_set_mtu_xgb(struct netxen_adapter *adapter, int new_mtu)
1882 return 0; 2055 return 0;
1883} 2056}
1884 2057
1885void netxen_nic_init_niu_gb(struct netxen_adapter *adapter)
1886{
1887 netxen_niu_gbe_init_port(adapter, adapter->physical_port);
1888}
1889
1890void 2058void
1891netxen_crb_writelit_adapter(struct netxen_adapter *adapter, 2059netxen_crb_writelit_adapter(struct netxen_adapter *adapter,
1892 unsigned long off, int data) 2060 unsigned long off, int data)