diff options
Diffstat (limited to 'drivers/net/benet')
-rw-r--r-- | drivers/net/benet/be.h | 9 | ||||
-rw-r--r-- | drivers/net/benet/be_cmds.c | 10 | ||||
-rw-r--r-- | drivers/net/benet/be_cmds.h | 2 | ||||
-rw-r--r-- | drivers/net/benet/be_ethtool.c | 2 | ||||
-rw-r--r-- | drivers/net/benet/be_hw.h | 3 | ||||
-rw-r--r-- | drivers/net/benet/be_main.c | 299 |
6 files changed, 246 insertions, 79 deletions
diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index 8f0752553681..20842c5fd8fb 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h | |||
@@ -83,6 +83,8 @@ static inline char *nic_name(struct pci_dev *pdev) | |||
83 | 83 | ||
84 | #define FW_VER_LEN 32 | 84 | #define FW_VER_LEN 32 |
85 | 85 | ||
86 | #define BE_MAX_VF 32 | ||
87 | |||
86 | struct be_dma_mem { | 88 | struct be_dma_mem { |
87 | void *va; | 89 | void *va; |
88 | dma_addr_t dma; | 90 | dma_addr_t dma; |
@@ -280,8 +282,15 @@ struct be_adapter { | |||
280 | u8 port_type; | 282 | u8 port_type; |
281 | u8 transceiver; | 283 | u8 transceiver; |
282 | u8 generation; /* BladeEngine ASIC generation */ | 284 | u8 generation; /* BladeEngine ASIC generation */ |
285 | |||
286 | bool sriov_enabled; | ||
287 | u32 vf_if_handle[BE_MAX_VF]; | ||
288 | u32 vf_pmac_id[BE_MAX_VF]; | ||
289 | u8 base_eq_id; | ||
283 | }; | 290 | }; |
284 | 291 | ||
292 | #define be_physfn(adapter) (!adapter->pdev->is_virtfn) | ||
293 | |||
285 | /* BladeEngine Generation numbers */ | 294 | /* BladeEngine Generation numbers */ |
286 | #define BE_GEN2 2 | 295 | #define BE_GEN2 2 |
287 | #define BE_GEN3 3 | 296 | #define BE_GEN3 3 |
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index d0ef4ac987cd..da8793026bb1 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c | |||
@@ -843,7 +843,8 @@ int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q, | |||
843 | * Uses mbox | 843 | * Uses mbox |
844 | */ | 844 | */ |
845 | int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags, u32 en_flags, | 845 | int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags, u32 en_flags, |
846 | u8 *mac, bool pmac_invalid, u32 *if_handle, u32 *pmac_id) | 846 | u8 *mac, bool pmac_invalid, u32 *if_handle, u32 *pmac_id, |
847 | u32 domain) | ||
847 | { | 848 | { |
848 | struct be_mcc_wrb *wrb; | 849 | struct be_mcc_wrb *wrb; |
849 | struct be_cmd_req_if_create *req; | 850 | struct be_cmd_req_if_create *req; |
@@ -860,6 +861,7 @@ int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags, u32 en_flags, | |||
860 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, | 861 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, |
861 | OPCODE_COMMON_NTWK_INTERFACE_CREATE, sizeof(*req)); | 862 | OPCODE_COMMON_NTWK_INTERFACE_CREATE, sizeof(*req)); |
862 | 863 | ||
864 | req->hdr.domain = domain; | ||
863 | req->capability_flags = cpu_to_le32(cap_flags); | 865 | req->capability_flags = cpu_to_le32(cap_flags); |
864 | req->enable_flags = cpu_to_le32(en_flags); | 866 | req->enable_flags = cpu_to_le32(en_flags); |
865 | req->pmac_invalid = pmac_invalid; | 867 | req->pmac_invalid = pmac_invalid; |
@@ -1157,13 +1159,13 @@ int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id, | |||
1157 | req->interface_id = if_id; | 1159 | req->interface_id = if_id; |
1158 | if (netdev) { | 1160 | if (netdev) { |
1159 | int i; | 1161 | int i; |
1160 | struct dev_mc_list *mc; | 1162 | struct netdev_hw_addr *ha; |
1161 | 1163 | ||
1162 | req->num_mac = cpu_to_le16(netdev_mc_count(netdev)); | 1164 | req->num_mac = cpu_to_le16(netdev_mc_count(netdev)); |
1163 | 1165 | ||
1164 | i = 0; | 1166 | i = 0; |
1165 | netdev_for_each_mc_addr(mc, netdev) | 1167 | netdev_for_each_mc_addr(ha, netdev) |
1166 | memcpy(req->mac[i].byte, mc->dmi_addr, ETH_ALEN); | 1168 | memcpy(req->mac[i].byte, ha->addr, ETH_ALEN); |
1167 | } else { | 1169 | } else { |
1168 | req->promiscuous = 1; | 1170 | req->promiscuous = 1; |
1169 | } | 1171 | } |
diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h index cce61f9a3714..763dc199e337 100644 --- a/drivers/net/benet/be_cmds.h +++ b/drivers/net/benet/be_cmds.h | |||
@@ -878,7 +878,7 @@ extern int be_cmd_pmac_add(struct be_adapter *adapter, u8 *mac_addr, | |||
878 | extern int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id, u32 pmac_id); | 878 | extern int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id, u32 pmac_id); |
879 | extern int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags, | 879 | extern int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags, |
880 | u32 en_flags, u8 *mac, bool pmac_invalid, | 880 | u32 en_flags, u8 *mac, bool pmac_invalid, |
881 | u32 *if_handle, u32 *pmac_id); | 881 | u32 *if_handle, u32 *pmac_id, u32 domain); |
882 | extern int be_cmd_if_destroy(struct be_adapter *adapter, u32 if_handle); | 882 | extern int be_cmd_if_destroy(struct be_adapter *adapter, u32 if_handle); |
883 | extern int be_cmd_eq_create(struct be_adapter *adapter, | 883 | extern int be_cmd_eq_create(struct be_adapter *adapter, |
884 | struct be_queue_info *eq, int eq_delay); | 884 | struct be_queue_info *eq, int eq_delay); |
diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c index 51e1065e7897..d488d52d710a 100644 --- a/drivers/net/benet/be_ethtool.c +++ b/drivers/net/benet/be_ethtool.c | |||
@@ -496,7 +496,7 @@ be_test_ddr_dma(struct be_adapter *adapter) | |||
496 | ddrdma_cmd.va = pci_alloc_consistent(adapter->pdev, ddrdma_cmd.size, | 496 | ddrdma_cmd.va = pci_alloc_consistent(adapter->pdev, ddrdma_cmd.size, |
497 | &ddrdma_cmd.dma); | 497 | &ddrdma_cmd.dma); |
498 | if (!ddrdma_cmd.va) { | 498 | if (!ddrdma_cmd.va) { |
499 | dev_err(&adapter->pdev->dev, "Memory allocation failure \n"); | 499 | dev_err(&adapter->pdev->dev, "Memory allocation failure\n"); |
500 | return -ENOMEM; | 500 | return -ENOMEM; |
501 | } | 501 | } |
502 | 502 | ||
diff --git a/drivers/net/benet/be_hw.h b/drivers/net/benet/be_hw.h index 2d4a4b827637..063026de4957 100644 --- a/drivers/net/benet/be_hw.h +++ b/drivers/net/benet/be_hw.h | |||
@@ -99,6 +99,9 @@ | |||
99 | /* Number of entries posted */ | 99 | /* Number of entries posted */ |
100 | #define DB_MCCQ_NUM_POSTED_SHIFT (16) /* bits 16 - 29 */ | 100 | #define DB_MCCQ_NUM_POSTED_SHIFT (16) /* bits 16 - 29 */ |
101 | 101 | ||
102 | /********** SRIOV VF PCICFG OFFSET ********/ | ||
103 | #define SRIOV_VF_PCICFG_OFFSET (4096) | ||
104 | |||
102 | /* Flashrom related descriptors */ | 105 | /* Flashrom related descriptors */ |
103 | #define IMAGE_TYPE_FIRMWARE 160 | 106 | #define IMAGE_TYPE_FIRMWARE 160 |
104 | #define IMAGE_TYPE_BOOTCODE 224 | 107 | #define IMAGE_TYPE_BOOTCODE 224 |
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index ec6ace802256..49d51965312e 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c | |||
@@ -26,8 +26,11 @@ MODULE_AUTHOR("ServerEngines Corporation"); | |||
26 | MODULE_LICENSE("GPL"); | 26 | MODULE_LICENSE("GPL"); |
27 | 27 | ||
28 | static unsigned int rx_frag_size = 2048; | 28 | static unsigned int rx_frag_size = 2048; |
29 | static unsigned int num_vfs; | ||
29 | module_param(rx_frag_size, uint, S_IRUGO); | 30 | module_param(rx_frag_size, uint, S_IRUGO); |
31 | module_param(num_vfs, uint, S_IRUGO); | ||
30 | MODULE_PARM_DESC(rx_frag_size, "Size of a fragment that holds rcvd data."); | 32 | MODULE_PARM_DESC(rx_frag_size, "Size of a fragment that holds rcvd data."); |
33 | MODULE_PARM_DESC(num_vfs, "Number of PCI VFs to initialize"); | ||
31 | 34 | ||
32 | static DEFINE_PCI_DEVICE_TABLE(be_dev_ids) = { | 35 | static DEFINE_PCI_DEVICE_TABLE(be_dev_ids) = { |
33 | { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) }, | 36 | { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) }, |
@@ -138,12 +141,19 @@ static int be_mac_addr_set(struct net_device *netdev, void *p) | |||
138 | if (!is_valid_ether_addr(addr->sa_data)) | 141 | if (!is_valid_ether_addr(addr->sa_data)) |
139 | return -EADDRNOTAVAIL; | 142 | return -EADDRNOTAVAIL; |
140 | 143 | ||
144 | /* MAC addr configuration will be done in hardware for VFs | ||
145 | * by their corresponding PFs. Just copy to netdev addr here | ||
146 | */ | ||
147 | if (!be_physfn(adapter)) | ||
148 | goto netdev_addr; | ||
149 | |||
141 | status = be_cmd_pmac_del(adapter, adapter->if_handle, adapter->pmac_id); | 150 | status = be_cmd_pmac_del(adapter, adapter->if_handle, adapter->pmac_id); |
142 | if (status) | 151 | if (status) |
143 | return status; | 152 | return status; |
144 | 153 | ||
145 | status = be_cmd_pmac_add(adapter, (u8 *)addr->sa_data, | 154 | status = be_cmd_pmac_add(adapter, (u8 *)addr->sa_data, |
146 | adapter->if_handle, &adapter->pmac_id); | 155 | adapter->if_handle, &adapter->pmac_id); |
156 | netdev_addr: | ||
147 | if (!status) | 157 | if (!status) |
148 | memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); | 158 | memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); |
149 | 159 | ||
@@ -386,26 +396,48 @@ static void wrb_fill_hdr(struct be_eth_hdr_wrb *hdr, struct sk_buff *skb, | |||
386 | AMAP_SET_BITS(struct amap_eth_hdr_wrb, len, hdr, len); | 396 | AMAP_SET_BITS(struct amap_eth_hdr_wrb, len, hdr, len); |
387 | } | 397 | } |
388 | 398 | ||
399 | static void unmap_tx_frag(struct pci_dev *pdev, struct be_eth_wrb *wrb, | ||
400 | bool unmap_single) | ||
401 | { | ||
402 | dma_addr_t dma; | ||
403 | |||
404 | be_dws_le_to_cpu(wrb, sizeof(*wrb)); | ||
405 | |||
406 | dma = (u64)wrb->frag_pa_hi << 32 | (u64)wrb->frag_pa_lo; | ||
407 | if (dma != 0) { | ||
408 | if (unmap_single) | ||
409 | pci_unmap_single(pdev, dma, wrb->frag_len, | ||
410 | PCI_DMA_TODEVICE); | ||
411 | else | ||
412 | pci_unmap_page(pdev, dma, wrb->frag_len, | ||
413 | PCI_DMA_TODEVICE); | ||
414 | } | ||
415 | } | ||
389 | 416 | ||
390 | static int make_tx_wrbs(struct be_adapter *adapter, | 417 | static int make_tx_wrbs(struct be_adapter *adapter, |
391 | struct sk_buff *skb, u32 wrb_cnt, bool dummy_wrb) | 418 | struct sk_buff *skb, u32 wrb_cnt, bool dummy_wrb) |
392 | { | 419 | { |
393 | u64 busaddr; | 420 | dma_addr_t busaddr; |
394 | u32 i, copied = 0; | 421 | int i, copied = 0; |
395 | struct pci_dev *pdev = adapter->pdev; | 422 | struct pci_dev *pdev = adapter->pdev; |
396 | struct sk_buff *first_skb = skb; | 423 | struct sk_buff *first_skb = skb; |
397 | struct be_queue_info *txq = &adapter->tx_obj.q; | 424 | struct be_queue_info *txq = &adapter->tx_obj.q; |
398 | struct be_eth_wrb *wrb; | 425 | struct be_eth_wrb *wrb; |
399 | struct be_eth_hdr_wrb *hdr; | 426 | struct be_eth_hdr_wrb *hdr; |
427 | bool map_single = false; | ||
428 | u16 map_head; | ||
400 | 429 | ||
401 | hdr = queue_head_node(txq); | 430 | hdr = queue_head_node(txq); |
402 | atomic_add(wrb_cnt, &txq->used); | ||
403 | queue_head_inc(txq); | 431 | queue_head_inc(txq); |
432 | map_head = txq->head; | ||
404 | 433 | ||
405 | if (skb->len > skb->data_len) { | 434 | if (skb->len > skb->data_len) { |
406 | int len = skb->len - skb->data_len; | 435 | int len = skb->len - skb->data_len; |
407 | busaddr = pci_map_single(pdev, skb->data, len, | 436 | busaddr = pci_map_single(pdev, skb->data, len, |
408 | PCI_DMA_TODEVICE); | 437 | PCI_DMA_TODEVICE); |
438 | if (pci_dma_mapping_error(pdev, busaddr)) | ||
439 | goto dma_err; | ||
440 | map_single = true; | ||
409 | wrb = queue_head_node(txq); | 441 | wrb = queue_head_node(txq); |
410 | wrb_fill(wrb, busaddr, len); | 442 | wrb_fill(wrb, busaddr, len); |
411 | be_dws_cpu_to_le(wrb, sizeof(*wrb)); | 443 | be_dws_cpu_to_le(wrb, sizeof(*wrb)); |
@@ -419,6 +451,8 @@ static int make_tx_wrbs(struct be_adapter *adapter, | |||
419 | busaddr = pci_map_page(pdev, frag->page, | 451 | busaddr = pci_map_page(pdev, frag->page, |
420 | frag->page_offset, | 452 | frag->page_offset, |
421 | frag->size, PCI_DMA_TODEVICE); | 453 | frag->size, PCI_DMA_TODEVICE); |
454 | if (pci_dma_mapping_error(pdev, busaddr)) | ||
455 | goto dma_err; | ||
422 | wrb = queue_head_node(txq); | 456 | wrb = queue_head_node(txq); |
423 | wrb_fill(wrb, busaddr, frag->size); | 457 | wrb_fill(wrb, busaddr, frag->size); |
424 | be_dws_cpu_to_le(wrb, sizeof(*wrb)); | 458 | be_dws_cpu_to_le(wrb, sizeof(*wrb)); |
@@ -438,6 +472,16 @@ static int make_tx_wrbs(struct be_adapter *adapter, | |||
438 | be_dws_cpu_to_le(hdr, sizeof(*hdr)); | 472 | be_dws_cpu_to_le(hdr, sizeof(*hdr)); |
439 | 473 | ||
440 | return copied; | 474 | return copied; |
475 | dma_err: | ||
476 | txq->head = map_head; | ||
477 | while (copied) { | ||
478 | wrb = queue_head_node(txq); | ||
479 | unmap_tx_frag(pdev, wrb, map_single); | ||
480 | map_single = false; | ||
481 | copied -= wrb->frag_len; | ||
482 | queue_head_inc(txq); | ||
483 | } | ||
484 | return 0; | ||
441 | } | 485 | } |
442 | 486 | ||
443 | static netdev_tx_t be_xmit(struct sk_buff *skb, | 487 | static netdev_tx_t be_xmit(struct sk_buff *skb, |
@@ -462,6 +506,7 @@ static netdev_tx_t be_xmit(struct sk_buff *skb, | |||
462 | * *BEFORE* ringing the tx doorbell, so that we serialze the | 506 | * *BEFORE* ringing the tx doorbell, so that we serialze the |
463 | * tx compls of the current transmit which'll wake up the queue | 507 | * tx compls of the current transmit which'll wake up the queue |
464 | */ | 508 | */ |
509 | atomic_add(wrb_cnt, &txq->used); | ||
465 | if ((BE_MAX_TX_FRAG_COUNT + atomic_read(&txq->used)) >= | 510 | if ((BE_MAX_TX_FRAG_COUNT + atomic_read(&txq->used)) >= |
466 | txq->len) { | 511 | txq->len) { |
467 | netif_stop_queue(netdev); | 512 | netif_stop_queue(netdev); |
@@ -541,6 +586,9 @@ static void be_vlan_add_vid(struct net_device *netdev, u16 vid) | |||
541 | { | 586 | { |
542 | struct be_adapter *adapter = netdev_priv(netdev); | 587 | struct be_adapter *adapter = netdev_priv(netdev); |
543 | 588 | ||
589 | if (!be_physfn(adapter)) | ||
590 | return; | ||
591 | |||
544 | adapter->vlan_tag[vid] = 1; | 592 | adapter->vlan_tag[vid] = 1; |
545 | adapter->vlans_added++; | 593 | adapter->vlans_added++; |
546 | if (adapter->vlans_added <= (adapter->max_vlans + 1)) | 594 | if (adapter->vlans_added <= (adapter->max_vlans + 1)) |
@@ -551,6 +599,9 @@ static void be_vlan_rem_vid(struct net_device *netdev, u16 vid) | |||
551 | { | 599 | { |
552 | struct be_adapter *adapter = netdev_priv(netdev); | 600 | struct be_adapter *adapter = netdev_priv(netdev); |
553 | 601 | ||
602 | if (!be_physfn(adapter)) | ||
603 | return; | ||
604 | |||
554 | adapter->vlan_tag[vid] = 0; | 605 | adapter->vlan_tag[vid] = 0; |
555 | vlan_group_set_device(adapter->vlan_grp, vid, NULL); | 606 | vlan_group_set_device(adapter->vlan_grp, vid, NULL); |
556 | adapter->vlans_added--; | 607 | adapter->vlans_added--; |
@@ -588,6 +639,28 @@ done: | |||
588 | return; | 639 | return; |
589 | } | 640 | } |
590 | 641 | ||
642 | static int be_set_vf_mac(struct net_device *netdev, int vf, u8 *mac) | ||
643 | { | ||
644 | struct be_adapter *adapter = netdev_priv(netdev); | ||
645 | int status; | ||
646 | |||
647 | if (!adapter->sriov_enabled) | ||
648 | return -EPERM; | ||
649 | |||
650 | if (!is_valid_ether_addr(mac) || (vf >= num_vfs)) | ||
651 | return -EINVAL; | ||
652 | |||
653 | status = be_cmd_pmac_del(adapter, adapter->vf_if_handle[vf], | ||
654 | adapter->vf_pmac_id[vf]); | ||
655 | |||
656 | status = be_cmd_pmac_add(adapter, mac, adapter->vf_if_handle[vf], | ||
657 | &adapter->vf_pmac_id[vf]); | ||
658 | if (!status) | ||
659 | dev_err(&adapter->pdev->dev, "MAC %pM set on VF %d Failed\n", | ||
660 | mac, vf); | ||
661 | return status; | ||
662 | } | ||
663 | |||
591 | static void be_rx_rate_update(struct be_adapter *adapter) | 664 | static void be_rx_rate_update(struct be_adapter *adapter) |
592 | { | 665 | { |
593 | struct be_drvr_stats *stats = drvr_stats(adapter); | 666 | struct be_drvr_stats *stats = drvr_stats(adapter); |
@@ -791,7 +864,6 @@ static void be_rx_compl_process(struct be_adapter *adapter, | |||
791 | 864 | ||
792 | skb->truesize = skb->len + sizeof(struct sk_buff); | 865 | skb->truesize = skb->len + sizeof(struct sk_buff); |
793 | skb->protocol = eth_type_trans(skb, adapter->netdev); | 866 | skb->protocol = eth_type_trans(skb, adapter->netdev); |
794 | skb->dev = adapter->netdev; | ||
795 | 867 | ||
796 | vlanf = AMAP_GET_BITS(struct amap_eth_rx_compl, vtp, rxcp); | 868 | vlanf = AMAP_GET_BITS(struct amap_eth_rx_compl, vtp, rxcp); |
797 | vtm = AMAP_GET_BITS(struct amap_eth_rx_compl, vtm, rxcp); | 869 | vtm = AMAP_GET_BITS(struct amap_eth_rx_compl, vtm, rxcp); |
@@ -1012,35 +1084,26 @@ static void be_tx_compl_process(struct be_adapter *adapter, u16 last_index) | |||
1012 | struct be_eth_wrb *wrb; | 1084 | struct be_eth_wrb *wrb; |
1013 | struct sk_buff **sent_skbs = adapter->tx_obj.sent_skb_list; | 1085 | struct sk_buff **sent_skbs = adapter->tx_obj.sent_skb_list; |
1014 | struct sk_buff *sent_skb; | 1086 | struct sk_buff *sent_skb; |
1015 | u64 busaddr; | 1087 | u16 cur_index, num_wrbs = 1; /* account for hdr wrb */ |
1016 | u16 cur_index, num_wrbs = 0; | 1088 | bool unmap_skb_hdr = true; |
1017 | 1089 | ||
1018 | cur_index = txq->tail; | 1090 | sent_skb = sent_skbs[txq->tail]; |
1019 | sent_skb = sent_skbs[cur_index]; | ||
1020 | BUG_ON(!sent_skb); | 1091 | BUG_ON(!sent_skb); |
1021 | sent_skbs[cur_index] = NULL; | 1092 | sent_skbs[txq->tail] = NULL; |
1022 | wrb = queue_tail_node(txq); | 1093 | |
1023 | be_dws_le_to_cpu(wrb, sizeof(*wrb)); | 1094 | /* skip header wrb */ |
1024 | busaddr = ((u64)wrb->frag_pa_hi << 32) | (u64)wrb->frag_pa_lo; | ||
1025 | if (busaddr != 0) { | ||
1026 | pci_unmap_single(adapter->pdev, busaddr, | ||
1027 | wrb->frag_len, PCI_DMA_TODEVICE); | ||
1028 | } | ||
1029 | num_wrbs++; | ||
1030 | queue_tail_inc(txq); | 1095 | queue_tail_inc(txq); |
1031 | 1096 | ||
1032 | while (cur_index != last_index) { | 1097 | do { |
1033 | cur_index = txq->tail; | 1098 | cur_index = txq->tail; |
1034 | wrb = queue_tail_node(txq); | 1099 | wrb = queue_tail_node(txq); |
1035 | be_dws_le_to_cpu(wrb, sizeof(*wrb)); | 1100 | unmap_tx_frag(adapter->pdev, wrb, (unmap_skb_hdr && |
1036 | busaddr = ((u64)wrb->frag_pa_hi << 32) | (u64)wrb->frag_pa_lo; | 1101 | sent_skb->len > sent_skb->data_len)); |
1037 | if (busaddr != 0) { | 1102 | unmap_skb_hdr = false; |
1038 | pci_unmap_page(adapter->pdev, busaddr, | 1103 | |
1039 | wrb->frag_len, PCI_DMA_TODEVICE); | ||
1040 | } | ||
1041 | num_wrbs++; | 1104 | num_wrbs++; |
1042 | queue_tail_inc(txq); | 1105 | queue_tail_inc(txq); |
1043 | } | 1106 | } while (cur_index != last_index); |
1044 | 1107 | ||
1045 | atomic_sub(num_wrbs, &txq->used); | 1108 | atomic_sub(num_wrbs, &txq->used); |
1046 | 1109 | ||
@@ -1255,6 +1318,8 @@ static int be_tx_queues_create(struct be_adapter *adapter) | |||
1255 | /* Ask BE to create Tx Event queue */ | 1318 | /* Ask BE to create Tx Event queue */ |
1256 | if (be_cmd_eq_create(adapter, eq, adapter->tx_eq.cur_eqd)) | 1319 | if (be_cmd_eq_create(adapter, eq, adapter->tx_eq.cur_eqd)) |
1257 | goto tx_eq_free; | 1320 | goto tx_eq_free; |
1321 | adapter->base_eq_id = adapter->tx_eq.q.id; | ||
1322 | |||
1258 | /* Alloc TX eth compl queue */ | 1323 | /* Alloc TX eth compl queue */ |
1259 | cq = &adapter->tx_obj.cq; | 1324 | cq = &adapter->tx_obj.cq; |
1260 | if (be_queue_alloc(adapter, cq, TX_CQ_LEN, | 1325 | if (be_queue_alloc(adapter, cq, TX_CQ_LEN, |
@@ -1382,7 +1447,7 @@ rx_eq_free: | |||
1382 | /* There are 8 evt ids per func. Retruns the evt id's bit number */ | 1447 | /* There are 8 evt ids per func. Retruns the evt id's bit number */ |
1383 | static inline int be_evt_bit_get(struct be_adapter *adapter, u32 eq_id) | 1448 | static inline int be_evt_bit_get(struct be_adapter *adapter, u32 eq_id) |
1384 | { | 1449 | { |
1385 | return eq_id % 8; | 1450 | return eq_id - adapter->base_eq_id; |
1386 | } | 1451 | } |
1387 | 1452 | ||
1388 | static irqreturn_t be_intx(int irq, void *dev) | 1453 | static irqreturn_t be_intx(int irq, void *dev) |
@@ -1560,6 +1625,28 @@ static void be_msix_enable(struct be_adapter *adapter) | |||
1560 | return; | 1625 | return; |
1561 | } | 1626 | } |
1562 | 1627 | ||
1628 | static void be_sriov_enable(struct be_adapter *adapter) | ||
1629 | { | ||
1630 | #ifdef CONFIG_PCI_IOV | ||
1631 | int status; | ||
1632 | if (be_physfn(adapter) && num_vfs) { | ||
1633 | status = pci_enable_sriov(adapter->pdev, num_vfs); | ||
1634 | adapter->sriov_enabled = status ? false : true; | ||
1635 | } | ||
1636 | #endif | ||
1637 | return; | ||
1638 | } | ||
1639 | |||
1640 | static void be_sriov_disable(struct be_adapter *adapter) | ||
1641 | { | ||
1642 | #ifdef CONFIG_PCI_IOV | ||
1643 | if (adapter->sriov_enabled) { | ||
1644 | pci_disable_sriov(adapter->pdev); | ||
1645 | adapter->sriov_enabled = false; | ||
1646 | } | ||
1647 | #endif | ||
1648 | } | ||
1649 | |||
1563 | static inline int be_msix_vec_get(struct be_adapter *adapter, u32 eq_id) | 1650 | static inline int be_msix_vec_get(struct be_adapter *adapter, u32 eq_id) |
1564 | { | 1651 | { |
1565 | return adapter->msix_entries[ | 1652 | return adapter->msix_entries[ |
@@ -1617,6 +1704,9 @@ static int be_irq_register(struct be_adapter *adapter) | |||
1617 | status = be_msix_register(adapter); | 1704 | status = be_msix_register(adapter); |
1618 | if (status == 0) | 1705 | if (status == 0) |
1619 | goto done; | 1706 | goto done; |
1707 | /* INTx is not supported for VF */ | ||
1708 | if (!be_physfn(adapter)) | ||
1709 | return status; | ||
1620 | } | 1710 | } |
1621 | 1711 | ||
1622 | /* INTx */ | 1712 | /* INTx */ |
@@ -1690,14 +1780,17 @@ static int be_open(struct net_device *netdev) | |||
1690 | goto ret_sts; | 1780 | goto ret_sts; |
1691 | be_link_status_update(adapter, link_up); | 1781 | be_link_status_update(adapter, link_up); |
1692 | 1782 | ||
1693 | status = be_vid_config(adapter); | 1783 | if (be_physfn(adapter)) |
1784 | status = be_vid_config(adapter); | ||
1694 | if (status) | 1785 | if (status) |
1695 | goto ret_sts; | 1786 | goto ret_sts; |
1696 | 1787 | ||
1697 | status = be_cmd_set_flow_control(adapter, | 1788 | if (be_physfn(adapter)) { |
1698 | adapter->tx_fc, adapter->rx_fc); | 1789 | status = be_cmd_set_flow_control(adapter, |
1699 | if (status) | 1790 | adapter->tx_fc, adapter->rx_fc); |
1700 | goto ret_sts; | 1791 | if (status) |
1792 | goto ret_sts; | ||
1793 | } | ||
1701 | 1794 | ||
1702 | schedule_delayed_work(&adapter->work, msecs_to_jiffies(100)); | 1795 | schedule_delayed_work(&adapter->work, msecs_to_jiffies(100)); |
1703 | ret_sts: | 1796 | ret_sts: |
@@ -1723,7 +1816,7 @@ static int be_setup_wol(struct be_adapter *adapter, bool enable) | |||
1723 | PCICFG_PM_CONTROL_OFFSET, PCICFG_PM_CONTROL_MASK); | 1816 | PCICFG_PM_CONTROL_OFFSET, PCICFG_PM_CONTROL_MASK); |
1724 | if (status) { | 1817 | if (status) { |
1725 | dev_err(&adapter->pdev->dev, | 1818 | dev_err(&adapter->pdev->dev, |
1726 | "Could not enable Wake-on-lan \n"); | 1819 | "Could not enable Wake-on-lan\n"); |
1727 | pci_free_consistent(adapter->pdev, cmd.size, cmd.va, | 1820 | pci_free_consistent(adapter->pdev, cmd.size, cmd.va, |
1728 | cmd.dma); | 1821 | cmd.dma); |
1729 | return status; | 1822 | return status; |
@@ -1745,22 +1838,48 @@ static int be_setup_wol(struct be_adapter *adapter, bool enable) | |||
1745 | static int be_setup(struct be_adapter *adapter) | 1838 | static int be_setup(struct be_adapter *adapter) |
1746 | { | 1839 | { |
1747 | struct net_device *netdev = adapter->netdev; | 1840 | struct net_device *netdev = adapter->netdev; |
1748 | u32 cap_flags, en_flags; | 1841 | u32 cap_flags, en_flags, vf = 0; |
1749 | int status; | 1842 | int status; |
1843 | u8 mac[ETH_ALEN]; | ||
1750 | 1844 | ||
1751 | cap_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST | | 1845 | cap_flags = en_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST; |
1752 | BE_IF_FLAGS_MCAST_PROMISCUOUS | | 1846 | |
1753 | BE_IF_FLAGS_PROMISCUOUS | | 1847 | if (be_physfn(adapter)) { |
1754 | BE_IF_FLAGS_PASS_L3L4_ERRORS; | 1848 | cap_flags |= BE_IF_FLAGS_MCAST_PROMISCUOUS | |
1755 | en_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST | | 1849 | BE_IF_FLAGS_PROMISCUOUS | |
1756 | BE_IF_FLAGS_PASS_L3L4_ERRORS; | 1850 | BE_IF_FLAGS_PASS_L3L4_ERRORS; |
1851 | en_flags |= BE_IF_FLAGS_PASS_L3L4_ERRORS; | ||
1852 | } | ||
1757 | 1853 | ||
1758 | status = be_cmd_if_create(adapter, cap_flags, en_flags, | 1854 | status = be_cmd_if_create(adapter, cap_flags, en_flags, |
1759 | netdev->dev_addr, false/* pmac_invalid */, | 1855 | netdev->dev_addr, false/* pmac_invalid */, |
1760 | &adapter->if_handle, &adapter->pmac_id); | 1856 | &adapter->if_handle, &adapter->pmac_id, 0); |
1761 | if (status != 0) | 1857 | if (status != 0) |
1762 | goto do_none; | 1858 | goto do_none; |
1763 | 1859 | ||
1860 | if (be_physfn(adapter)) { | ||
1861 | while (vf < num_vfs) { | ||
1862 | cap_flags = en_flags = BE_IF_FLAGS_UNTAGGED | ||
1863 | | BE_IF_FLAGS_BROADCAST; | ||
1864 | status = be_cmd_if_create(adapter, cap_flags, en_flags, | ||
1865 | mac, true, &adapter->vf_if_handle[vf], | ||
1866 | NULL, vf+1); | ||
1867 | if (status) { | ||
1868 | dev_err(&adapter->pdev->dev, | ||
1869 | "Interface Create failed for VF %d\n", vf); | ||
1870 | goto if_destroy; | ||
1871 | } | ||
1872 | vf++; | ||
1873 | } while (vf < num_vfs); | ||
1874 | } else if (!be_physfn(adapter)) { | ||
1875 | status = be_cmd_mac_addr_query(adapter, mac, | ||
1876 | MAC_ADDRESS_TYPE_NETWORK, false, adapter->if_handle); | ||
1877 | if (!status) { | ||
1878 | memcpy(adapter->netdev->dev_addr, mac, ETH_ALEN); | ||
1879 | memcpy(adapter->netdev->perm_addr, mac, ETH_ALEN); | ||
1880 | } | ||
1881 | } | ||
1882 | |||
1764 | status = be_tx_queues_create(adapter); | 1883 | status = be_tx_queues_create(adapter); |
1765 | if (status != 0) | 1884 | if (status != 0) |
1766 | goto if_destroy; | 1885 | goto if_destroy; |
@@ -1782,6 +1901,9 @@ rx_qs_destroy: | |||
1782 | tx_qs_destroy: | 1901 | tx_qs_destroy: |
1783 | be_tx_queues_destroy(adapter); | 1902 | be_tx_queues_destroy(adapter); |
1784 | if_destroy: | 1903 | if_destroy: |
1904 | for (vf = 0; vf < num_vfs; vf++) | ||
1905 | if (adapter->vf_if_handle[vf]) | ||
1906 | be_cmd_if_destroy(adapter, adapter->vf_if_handle[vf]); | ||
1785 | be_cmd_if_destroy(adapter, adapter->if_handle); | 1907 | be_cmd_if_destroy(adapter, adapter->if_handle); |
1786 | do_none: | 1908 | do_none: |
1787 | return status; | 1909 | return status; |
@@ -2061,6 +2183,7 @@ static struct net_device_ops be_netdev_ops = { | |||
2061 | .ndo_vlan_rx_register = be_vlan_register, | 2183 | .ndo_vlan_rx_register = be_vlan_register, |
2062 | .ndo_vlan_rx_add_vid = be_vlan_add_vid, | 2184 | .ndo_vlan_rx_add_vid = be_vlan_add_vid, |
2063 | .ndo_vlan_rx_kill_vid = be_vlan_rem_vid, | 2185 | .ndo_vlan_rx_kill_vid = be_vlan_rem_vid, |
2186 | .ndo_set_vf_mac = be_set_vf_mac | ||
2064 | }; | 2187 | }; |
2065 | 2188 | ||
2066 | static void be_netdev_init(struct net_device *netdev) | 2189 | static void be_netdev_init(struct net_device *netdev) |
@@ -2102,37 +2225,48 @@ static void be_unmap_pci_bars(struct be_adapter *adapter) | |||
2102 | iounmap(adapter->csr); | 2225 | iounmap(adapter->csr); |
2103 | if (adapter->db) | 2226 | if (adapter->db) |
2104 | iounmap(adapter->db); | 2227 | iounmap(adapter->db); |
2105 | if (adapter->pcicfg) | 2228 | if (adapter->pcicfg && be_physfn(adapter)) |
2106 | iounmap(adapter->pcicfg); | 2229 | iounmap(adapter->pcicfg); |
2107 | } | 2230 | } |
2108 | 2231 | ||
2109 | static int be_map_pci_bars(struct be_adapter *adapter) | 2232 | static int be_map_pci_bars(struct be_adapter *adapter) |
2110 | { | 2233 | { |
2111 | u8 __iomem *addr; | 2234 | u8 __iomem *addr; |
2112 | int pcicfg_reg; | 2235 | int pcicfg_reg, db_reg; |
2113 | |||
2114 | addr = ioremap_nocache(pci_resource_start(adapter->pdev, 2), | ||
2115 | pci_resource_len(adapter->pdev, 2)); | ||
2116 | if (addr == NULL) | ||
2117 | return -ENOMEM; | ||
2118 | adapter->csr = addr; | ||
2119 | 2236 | ||
2120 | addr = ioremap_nocache(pci_resource_start(adapter->pdev, 4), | 2237 | if (be_physfn(adapter)) { |
2121 | 128 * 1024); | 2238 | addr = ioremap_nocache(pci_resource_start(adapter->pdev, 2), |
2122 | if (addr == NULL) | 2239 | pci_resource_len(adapter->pdev, 2)); |
2123 | goto pci_map_err; | 2240 | if (addr == NULL) |
2124 | adapter->db = addr; | 2241 | return -ENOMEM; |
2242 | adapter->csr = addr; | ||
2243 | } | ||
2125 | 2244 | ||
2126 | if (adapter->generation == BE_GEN2) | 2245 | if (adapter->generation == BE_GEN2) { |
2127 | pcicfg_reg = 1; | 2246 | pcicfg_reg = 1; |
2128 | else | 2247 | db_reg = 4; |
2248 | } else { | ||
2129 | pcicfg_reg = 0; | 2249 | pcicfg_reg = 0; |
2130 | 2250 | if (be_physfn(adapter)) | |
2131 | addr = ioremap_nocache(pci_resource_start(adapter->pdev, pcicfg_reg), | 2251 | db_reg = 4; |
2132 | pci_resource_len(adapter->pdev, pcicfg_reg)); | 2252 | else |
2253 | db_reg = 0; | ||
2254 | } | ||
2255 | addr = ioremap_nocache(pci_resource_start(adapter->pdev, db_reg), | ||
2256 | pci_resource_len(adapter->pdev, db_reg)); | ||
2133 | if (addr == NULL) | 2257 | if (addr == NULL) |
2134 | goto pci_map_err; | 2258 | goto pci_map_err; |
2135 | adapter->pcicfg = addr; | 2259 | adapter->db = addr; |
2260 | |||
2261 | if (be_physfn(adapter)) { | ||
2262 | addr = ioremap_nocache( | ||
2263 | pci_resource_start(adapter->pdev, pcicfg_reg), | ||
2264 | pci_resource_len(adapter->pdev, pcicfg_reg)); | ||
2265 | if (addr == NULL) | ||
2266 | goto pci_map_err; | ||
2267 | adapter->pcicfg = addr; | ||
2268 | } else | ||
2269 | adapter->pcicfg = adapter->db + SRIOV_VF_PCICFG_OFFSET; | ||
2136 | 2270 | ||
2137 | return 0; | 2271 | return 0; |
2138 | pci_map_err: | 2272 | pci_map_err: |
@@ -2246,6 +2380,8 @@ static void __devexit be_remove(struct pci_dev *pdev) | |||
2246 | 2380 | ||
2247 | be_ctrl_cleanup(adapter); | 2381 | be_ctrl_cleanup(adapter); |
2248 | 2382 | ||
2383 | be_sriov_disable(adapter); | ||
2384 | |||
2249 | be_msix_disable(adapter); | 2385 | be_msix_disable(adapter); |
2250 | 2386 | ||
2251 | pci_set_drvdata(pdev, NULL); | 2387 | pci_set_drvdata(pdev, NULL); |
@@ -2270,16 +2406,20 @@ static int be_get_config(struct be_adapter *adapter) | |||
2270 | return status; | 2406 | return status; |
2271 | 2407 | ||
2272 | memset(mac, 0, ETH_ALEN); | 2408 | memset(mac, 0, ETH_ALEN); |
2273 | status = be_cmd_mac_addr_query(adapter, mac, | 2409 | |
2410 | if (be_physfn(adapter)) { | ||
2411 | status = be_cmd_mac_addr_query(adapter, mac, | ||
2274 | MAC_ADDRESS_TYPE_NETWORK, true /*permanent */, 0); | 2412 | MAC_ADDRESS_TYPE_NETWORK, true /*permanent */, 0); |
2275 | if (status) | ||
2276 | return status; | ||
2277 | 2413 | ||
2278 | if (!is_valid_ether_addr(mac)) | 2414 | if (status) |
2279 | return -EADDRNOTAVAIL; | 2415 | return status; |
2416 | |||
2417 | if (!is_valid_ether_addr(mac)) | ||
2418 | return -EADDRNOTAVAIL; | ||
2280 | 2419 | ||
2281 | memcpy(adapter->netdev->dev_addr, mac, ETH_ALEN); | 2420 | memcpy(adapter->netdev->dev_addr, mac, ETH_ALEN); |
2282 | memcpy(adapter->netdev->perm_addr, mac, ETH_ALEN); | 2421 | memcpy(adapter->netdev->perm_addr, mac, ETH_ALEN); |
2422 | } | ||
2283 | 2423 | ||
2284 | if (adapter->cap & 0x400) | 2424 | if (adapter->cap & 0x400) |
2285 | adapter->max_vlans = BE_NUM_VLANS_SUPPORTED/4; | 2425 | adapter->max_vlans = BE_NUM_VLANS_SUPPORTED/4; |
@@ -2296,6 +2436,7 @@ static int __devinit be_probe(struct pci_dev *pdev, | |||
2296 | struct be_adapter *adapter; | 2436 | struct be_adapter *adapter; |
2297 | struct net_device *netdev; | 2437 | struct net_device *netdev; |
2298 | 2438 | ||
2439 | |||
2299 | status = pci_enable_device(pdev); | 2440 | status = pci_enable_device(pdev); |
2300 | if (status) | 2441 | if (status) |
2301 | goto do_none; | 2442 | goto do_none; |
@@ -2344,24 +2485,28 @@ static int __devinit be_probe(struct pci_dev *pdev, | |||
2344 | } | 2485 | } |
2345 | } | 2486 | } |
2346 | 2487 | ||
2488 | be_sriov_enable(adapter); | ||
2489 | |||
2347 | status = be_ctrl_init(adapter); | 2490 | status = be_ctrl_init(adapter); |
2348 | if (status) | 2491 | if (status) |
2349 | goto free_netdev; | 2492 | goto free_netdev; |
2350 | 2493 | ||
2351 | /* sync up with fw's ready state */ | 2494 | /* sync up with fw's ready state */ |
2352 | status = be_cmd_POST(adapter); | 2495 | if (be_physfn(adapter)) { |
2353 | if (status) | 2496 | status = be_cmd_POST(adapter); |
2354 | goto ctrl_clean; | 2497 | if (status) |
2498 | goto ctrl_clean; | ||
2499 | |||
2500 | status = be_cmd_reset_function(adapter); | ||
2501 | if (status) | ||
2502 | goto ctrl_clean; | ||
2503 | } | ||
2355 | 2504 | ||
2356 | /* tell fw we're ready to fire cmds */ | 2505 | /* tell fw we're ready to fire cmds */ |
2357 | status = be_cmd_fw_init(adapter); | 2506 | status = be_cmd_fw_init(adapter); |
2358 | if (status) | 2507 | if (status) |
2359 | goto ctrl_clean; | 2508 | goto ctrl_clean; |
2360 | 2509 | ||
2361 | status = be_cmd_reset_function(adapter); | ||
2362 | if (status) | ||
2363 | goto ctrl_clean; | ||
2364 | |||
2365 | status = be_stats_init(adapter); | 2510 | status = be_stats_init(adapter); |
2366 | if (status) | 2511 | if (status) |
2367 | goto ctrl_clean; | 2512 | goto ctrl_clean; |
@@ -2391,6 +2536,7 @@ ctrl_clean: | |||
2391 | be_ctrl_cleanup(adapter); | 2536 | be_ctrl_cleanup(adapter); |
2392 | free_netdev: | 2537 | free_netdev: |
2393 | be_msix_disable(adapter); | 2538 | be_msix_disable(adapter); |
2539 | be_sriov_disable(adapter); | ||
2394 | free_netdev(adapter->netdev); | 2540 | free_netdev(adapter->netdev); |
2395 | pci_set_drvdata(pdev, NULL); | 2541 | pci_set_drvdata(pdev, NULL); |
2396 | rel_reg: | 2542 | rel_reg: |
@@ -2587,6 +2733,13 @@ static int __init be_init_module(void) | |||
2587 | rx_frag_size = 2048; | 2733 | rx_frag_size = 2048; |
2588 | } | 2734 | } |
2589 | 2735 | ||
2736 | if (num_vfs > 32) { | ||
2737 | printk(KERN_WARNING DRV_NAME | ||
2738 | " : Module param num_vfs must not be greater than 32." | ||
2739 | "Using 32\n"); | ||
2740 | num_vfs = 32; | ||
2741 | } | ||
2742 | |||
2590 | return pci_register_driver(&be_driver); | 2743 | return pci_register_driver(&be_driver); |
2591 | } | 2744 | } |
2592 | module_init(be_init_module); | 2745 | module_init(be_init_module); |